rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.58k stars 2.39k forks source link

Can't generate feature gated code from a proc macro in a reliable way when used by both normal/build dependencies with `resolver="2"` #14415

Open weiznich opened 1 month ago

weiznich commented 1 month ago

Problem

Consider the following example:

Assuming that host and target match:

Given this situation: How do I resolve that while supporting both resolver versions. If the answer is: You cannot, then resolver = "2" is a breaking change and should have been marked as such (== shipping rust 2.0). I fully understand that it is far to late to roll back that change but I would like to see the cargo team to at least acknowledge that they broke something and that they should prioritizing working on a fix (and maybe more than working on implementing new features!).

Steps

For a real word example try to build the following crate:

[package]
name = "test_resolver"
version = "0.1.0"
edition = "2021"

[dependencies]
diesel = { version = "=2.2.2", features = ["postgres"] }

[build-dependencies]
diesel = { version = "=2.2.1", features = ["sqlite"] }

This breaks diesel as we cannot encapsulate the proc-macros and the main crate as "one" unit.

Possible Solution(s)

Notes

See the offtopic part of https://github.com/rust-lang/cargo/issues/14406 for more discussion on this topic

Version

cargo 1.80.0 (376290515 2024-07-16)
release: 1.80.0
commit-hash: 37629051518c3df9ac2c1744589362a02ecafa99
commit-date: 2024-07-16
host: x86_64-unknown-linux-gnu
libgit2: 1.7.2 (sys:0.18.3 vendored)
libcurl: 8.6.0-DEV (sys:0.4.72+curl-8.6.0 vendored ssl:OpenSSL/1.1.1w)
ssl: OpenSSL 1.1.1w  11 Sep 2023
os: Fedora 40.0.0 [64-bit]
epage commented 1 month ago

Originally reported at https://internals.rust-lang.org/t/concerns-about-making-resolver-2-the-default-in-2021-edition/14684

epage commented 1 month ago

proc-macros are in an unfortunate situation where the main crate depends on them but they generate code for the main crate, requiring them to know what is in the main crate. Another problem that crops up due to this cyclic relationship is that the proc-macro can generate code that is "too new" for the main crate if work isn't done by the end-user or the maintainer to keep them in lockstep (e.g. using = version requirements).