cargo add cannot enable features if version="*" in Cargo.toml
Problem
When trying to run cargo add crate -F feature with crate = "*" or crate = { version="*" } in Cargo.toml, an error is returned.
Steps
- Add
time = "*"to Cargo.toml - Run the following command:
$ cargo +nightly add time -F serde
Updating crates.io index
Adding time * to dependencies
error: unrecognized feature for crate time: serde
no features available for crate time
- Change
time = "*"totime = "0.3" - Run the command again:
$ cargo +nightly add time -F serde
Updating crates.io index
Adding time v0.3 to dependencies
Features as of v0.3.0:
+ alloc
+ serde
+ std
- formatting
- itoa
- large-dates
- local-offset
- macros
- parsing
- quickcheck
- quickcheck-dep
- rand
- serde-human-readable
- time-macros
List of features changes when using the last concrete version (0.3.36).
Possible Solution(s)
For version="*", I would expect that it uses the feature list of the used root dependency (as in Cargo.lock) or of the latest version available.
Notes
No response
Version
cargo 1.83.0-nightly (80d82ca22 2024-09-27) release: 1.83.0-nightly commit-hash: 80d82ca22abbee5fb7b51fa1abeb1ae34e99e88a commit-date: 2024-09-27 host: x86_64-unknown-linux-gnu libgit2: 1.8.1 (sys:0.19.0 vendored) libcurl: 8.9.0-DEV (sys:0.4.74+curl-8.9.0 vendored ssl:OpenSSL/1.1.1w) ssl: OpenSSL 1.1.1w 11 Sep 2023 os: Fedora 41.0.0 (FortyOne) [64-bit]
When cargo add looks for available features to display and validate against, it looks to the oldest version compatible with your version requirement, assuming
- You set the minimum supported version in your version requirement
- The dependency doesn't remove features, making this the lowest common denominator for your version requirement. Granted, this gets fuzzy with multi-major version requirements.
In your case, its picking time = "0.1.0" and only allowing features from that version.
@Kelvin-1013 please don't post LLM responses without reading and reformatting.
The behavior is written down here in code: https://github.com/rust-lang/cargo/blob/d8cb5fb7f8f66fc9b4ba3d80b089474164a8a83d/src/cargo/ops/cargo_add/mod.rs?plain=1#L1040-L1054
It seems pretty like an implementation detail relying on the assumption in the comment. I don't think this should be documented, and picking up the latest version isn't better either. I would propose we close this as the behavior is intended.
imo if we did anything, it would likely to be lint against wildcard dependencies, see #5340
It seems odd that cargo, which has a ton of code about resolving versions of crates, doesn't reuse this for determining which version's features are in play here? Especially in this case where the actual version is already known in Cargo.lock?
A diagnostic sounds good to me -- the current behaviour is surprising.
The current version is in Cargo.lock but your dependency specification says any version in existence could be used instead. We are trying to pick features that work for your dependency specification. However, as I said earlier
Granted, this gets fuzzy with multi-major version requirements.