You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem
When changing the source of a direct dependency (for example, switching from crates.io to a git dependency), Cargo fails to poison the crates.io source. This results in all crates.io dependencies remaining "locked". If the git dependency introduces any increased requirements, they will fail to resolve because the old version is locked.
Steps
The real-world example is a bit large, but here it is:
error: failed to select a version for `miow`.
... required by package `mio v0.7.6`
... which is depended on by `tokio v1.0.1`
... which is depended on by `rustwide v0.12.0 (https://github.com/jyn514/rustwide?rev=60de530190b86fd8cc4dda772a96ce0208531d44#60de5301)`
... which is depended on by `docs-rs v0.6.0 (/Users/eric/Proj/rust/docs.rs)`
versions that meet the requirements `^0.3.6` are: 0.3.6
all possible versions conflict with previously selected packages.
previously selected package `miow v0.3.3`
... which is depended on by `mio-named-pipes v0.1.6`
... which is depended on by `tokio v0.2.22`
... which is depended on by `docs-rs v0.6.0 (/Users/eric/Proj/rust/docs.rs)`
failed to select a version for `miow` which could resolve this conflict
A reduced example using Cargo's testsuite is:
use cargo_test_support::git;#[cargo_test]fnswitches_source_poison(){// Issue with changing the source of a direct dependency, which results in// an elevated requirement for something locked in Cargo.lock.// Needy is here to add a transitive requirement to `conflict.`Package::new("needy","1.0.0").dep("conflict","1.4").publish();// Conflict causes all the trouble.Package::new("conflict","1.4.0").publish();// Changeme will be replaced with a git dependency that has elevated requirements.Package::new("changeme","1.0.0").dep("conflict","1.4").publish();let base_manifest = r#" [package] name = "foo" version = "0.1.0" [dependencies] needy = "1.0" "#;let p = project().file("Cargo.toml",&format!(r#" {} changeme = "1.0" "#,
base_manifest
),).file("src/lib.rs","").build();// Create a valid lock file.
p.cargo("tree").with_stdout("\foo v0.1.0 [..]├── changeme v1.0.0│ └── conflict v1.4.0└── needy v1.0.0 └── conflict v1.4.0",).run();// Swap `changeme` with a git dependency that has a newer requirement for `conflict`.let changeme_git = git::new("changeme", |project| {
project
.file("Cargo.toml",r#" [package] name = "changeme" version = "2.0.0" [dependencies] conflict = "1.5" "#,).file("src/lib.rs","")});Package::new("conflict","1.5.0").publish();
p.change_file("Cargo.toml",&format!(r#" {} changeme.git = '{}' "#,
base_manifest,
changeme_git.url()),);// ****TODO**** This fails, but should succeed.// error: failed to select a version for `conflict`.// ... required by package `needy v1.0.0`// ... which is depended on by `foo v0.1.0 (/Users/eric/Proj/rust/cargo/target/cit/t0/foo)`// versions that meet the requirements `=1.4.0` are: 1.4.0//// all possible versions conflict with previously selected packages.//// previously selected package `conflict v1.5.0`// ... which is depended on by `changeme v2.0.0 (file:///Users/eric/Proj/rust/cargo/target/cit/t0/changeme#b28dec1c)`// ... which is depended on by `foo v0.1.0 (/Users/eric/Proj/rust/cargo/target/cit/t0/foo)`//// failed to select a version for `conflict` which could resolve this conflict
p.cargo("tree").with_stdout("\foo v0.1.0 [..]├── changeme v2.0.0 [..]│ └── conflict v1.5.0└── needy v1.0.0 └── conflict v1.5.0",).run();}
What's surprising to me is that cargo update -p rustwide --aggressive doesn't work, either. I would expect --aggressive to unlock all of those dependencies.
Possible Solution(s)
The issue is these lines of code. When the source changes, Cargo fails to poison crates.io, and thus keeping all dependencies locked. Due to the increased requirements in the git dependency, it can run into conflicts that it can't resolve because the old versions are locked.
I don't off-hand know how to solve this. Those lines are somewhat delicate, but I imagine being a little more aggressive with poisoning is the solution.
Notes
Output of cargo version: cargo 1.52.0-nightly (c68432f1e 2021-03-02)
The text was updated successfully, but these errors were encountered:
Problem
When changing the source of a direct dependency (for example, switching from crates.io to a git dependency), Cargo fails to poison the crates.io source. This results in all crates.io dependencies remaining "locked". If the git dependency introduces any increased requirements, they will fail to resolve because the old version is locked.
Steps
The real-world example is a bit large, but here it is:
git checkout https://github.com/rust-lang/docs.rs.git
cd docs.rs
git checkout da1f36263ff70c02b119a9582c1228b08bd233f2
Cargo.toml
, swaprustwide
with:rustwide = { git = "https://github.com/jyn514/rustwide", rev = "60de530190b86fd8cc4dda772a96ce0208531d44" }
cargo tree
Fails with the error:
A reduced example using Cargo's testsuite is:
What's surprising to me is that
cargo update -p rustwide --aggressive
doesn't work, either. I would expect--aggressive
to unlock all of those dependencies.Possible Solution(s)
The issue is these lines of code. When the source changes, Cargo fails to poison crates.io, and thus keeping all dependencies locked. Due to the increased requirements in the git dependency, it can run into conflicts that it can't resolve because the old versions are locked.
I don't off-hand know how to solve this. Those lines are somewhat delicate, but I imagine being a little more aggressive with poisoning is the solution.
Notes
Output of
cargo version
:cargo 1.52.0-nightly (c68432f1e 2021-03-02)
The text was updated successfully, but these errors were encountered: