Open epage opened 5 months ago
https://github.com/rust-lang/cargo/issues/14010#issuecomment-2148408439
This makes me worried about
dep_name/feature_name
syntax on Edition 2024. It now requires also addingdep:dep_name
at which point it isn't much different thandep_name?/feature_name
.I had missing this part in past discussions (e.g. this zulip topic). It seems like we should have either changed it in Edition 2024 to not need
dep:dep_name
or transition out the syntax according to #10556. I worry that changing the meaning ofdep_name/feature_name
would be too subtle. Maybe we should at least go forward with the deprecation ofdep_name/feature_name
as mentioned in the comments of #10556?
https://github.com/rust-lang/cargo/issues/14010#issuecomment-2148415751
Also, another reason why deprecating implicit features doesn't play well with
dep_name/feature_name
is that[features] foo = ["dep:dep_name"] bar = ["dep_name/feature_name"]
and
[features] bar = ["dep:dep_name", "dep_name/feature_name"]
are valid while the following is not
[features] bar = ["dep_name/feature_name"]
That inconsistency feels weird.
We discussed this in today's team meeting and lean towards "dep_name/feature_name"
implying "dep:dep_name"
in Edition 2024 with it being normalized in the published Cargo.toml
file.
Re-opened due to #14295. See #14283 for more context.
When we tried to fix this with #14221, we caused #14283.
The following content is adapted from #14283 and https://blog.rust-lang.org/inside-rust/2024/08/15/this-development-cycle-in-cargo-1.81.html#removing-implicit-features
Let's step back to the beginning of how all of this works.
package.edition = "2021"
[features]
feature = ["dep/feature"]
[dependencies]
dep = { version = "1", optional = true }
will cause a dep
implicit feature to be created
As we want to suppress implicit features in 2024, we strip all optional dependencies like that. This led to a new problem:
package.edition = "2024"
[features]
feature = ["dep/feature"]
[dependencies]
dep = { version = "1", optional = true }
As dep
is stripped, this fails because dep/feature
can't be resolved. The user can workaround this by adding dep:dep
(discoverability is poor).
We solved this by implicitly adding dep:dep
to feature
. However, I forgot to check dependencies.dep.optional
, so if it isn't optional, it also fails but in a way the user can't workaround.
Logically, checking dependencies.dep.optional
gets circular because
resolve_features
needs to know about resolved dependencies to add dep:dep
resolve_dependencies
needs to know about resolved features to know what dep:dep
are presentWe could break this cycle by making a lot of assumptions about the unresolved forms.
If we solved this now, we would be stuck with it forever. In examining the potential alternatives, it seemed better to design a more holistic solution rather than being stuck with the maintenance burden that solving this now would cause.
Other options include
dep_name/feature_name
de-sugars to, including making dep:dep_name
work with optional dependenciesdep_name?/feature_name
to work with required dependencies and switch to itWhatever we design, we need to keep in mind that "dep_name/feature_name"
is more like "dep_name"?, "dep:dep_name"?, "dep_name?/feature_name"
dep_name
, if presentdep:dep_name
, if optionalfeature_name
inside of dep_name
Problem
If nothing can activate an optional dependency, cargo acts as if the dependency doesn't exist which creates poor error messages.
Also, with how things are arranged, the unused optional dependency lint doesn't get reported which could at least reduce the burden on the error message.
Steps
Baseline
Cargo.toml
:Add the following to
Cargo.toml
:Possible Solution(s)
dep:serde
ifserde/derive
is usedserde/derive
syntax, removing it in a new edition (#10556)Notes
This was split out of #14015 assuming we'll go with a different solution than it
Version
No response