-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cargo generate-lockfile doesn't give a working lockfile in some situations #8302
Comments
Thanks for the report! It doesn't matter which command is run. Building a lock file with any command, and then running any command with --locked will fail. This seems similar to #7753. [target."cfg(unix)".dev-dependencies.futures]
version = "^0"
[target."cfg(windows)".dev-dependencies.futures]
version = "^0.1" I think that is a use case that Cargo never really considers, and it doesn't seem to work properly. As mentioned in #7753 (comment), it would be very difficult to determine that these two expressions are mutually exclusive. I would lean towards forbidding that as a duplicate dependency for now. @Eh2406 wdyt? |
Note that the final |
I believe that it is currently treated as being mutually true. I get a lockfile that just has |
I originally noticed this on the latest nightly since that's what docs.rs uses, the repro I posted above was when using |
@Eh2406 it is probably because you are on windows (and the #[cargo_test]
fn mixed_targets_same_dependency() {
Package::new("bar", "0.1.0").publish();
Package::new("bar", "0.2.0").publish();
Package::new("zoo", "1.0.0")
.dep("bar", "0.1")
.publish();
let p = project()
.file("Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
zoo = "1.0"
bar = "^0"
[target.'cfg(does_not_exist)'.dependencies]
bar = "^0.1"
"#)
.file("src/lib.rs", "")
.build();
p.cargo("generate-lockfile").run();
p.cargo("check --locked").run();
} I haven't checked, but I suspect this is relatively common, so rejecting it outright might not be the right thing. |
I'm a bit surprised by this behavior, I thought we fixed this some time ago! I don't think we necessarily want a special case to reject this in the manifest, it seems like it would be pretty difficult to detect overlapping ranges. The resolver, however, should be trying to solve both version constraints and realize there's one solution. Currently it seems like it's picking the first for |
I took a little look at this. It seems to be unique to this situation where one version req is a superset of another. If you change What happens is that when it is locking the summary, both I don't know how to fix that. Perhaps it should pick the dep with the greatest matching version? Iterate in reverse order? |
Hm this seems like it's even more evidence that the current implementation of locking is not really up to par. We should know that if a crate has two versions in a lock file exactly which one you should be locked to for each dep. This sounds like we're basically not keeping track of that information, only what's available to lock. I don't think iteration order can solve this, because you should be able to construct situations where there's as many versions in play as you need, and the lock should always be able to pick the one the lock file indicates. In any case this seems like a more fundamental issue in how lock files are handled. This doesn't really ever come up much in practice because 99% of version requirements are "semver compatible" which means there's no overlap across major versions. |
Problem
For some crates running
generate-lockfile
does not result in a working lockfile, whereas runningfetch
does.Steps
The text was updated successfully, but these errors were encountered: