killercup / killercup/cargo-edit
cargo upgrade selects versions of native dependencies which are not compatible with transitive packages
- Dominant language
- Rust
- Stars
- 3.5k
- Forks
- 166
- PR merge metrics
- No merged PRs in 30d
Description
Originally reported in diesel-rs/diesel#3587 and rust-lang/cargo#11948
The issue here is that diesel depends on libsqlite3-sys, which as a native dependency and declares that it links to `sqlite3`. If the crate being upgraded has a direct dependency to libsqlite3-sys (something which is needed to activate features in it that are not re-exported by diesel) this can cause `cargo upgrade` to potentially select an incompatible version to upgrade to.
If you run `cargo upgrade` on a manifest with the following:
```toml
[dependencies]
libsqlite3-sys = { version = "0.25.2", features = ["bundled", "unlock_notify"] }
diesel = { version = "2.0.3", features = ["sqlite", "chrono"] }
```
It gets upgraded to this:
```toml
[dependencies]
libsqlite3-sys = { version = "0.26.0", features = ["bundled", "unlock_notify"] }
diesel = { version = "2.0.3", features = ["sqlite", "chrono"] }
```
Trying to build it results in this error:
```
Updating crates.io index
error: failed to select a version for `libsqlite3-sys`.
... required by package `diesel v2.0.3`
... which satisfies dependency `diesel = "~2.0.0"` of package `diesel_migrations v2.0.0`
... which satisfies dependency `diesel_migrations = "^2.0.0"` of package `oxidize v0.0.0 (D:\Repo\*snip*)`
versions that meet the requirements `>=0.17.2, <0.26.0` are: 0.25.2, 0.25.1, 0.25.0, 0.24.2, 0.24.1, 0.24.0, 0.23.2, 0.23.1, 0.23.0, 0.22.2, 0.22.1, 0.22.0, 0.20.1, 0.20.0, 0.18.0, 0.17.3, 0.17.2
the package `libsqlite3-sys` links to the native library `sqlite3`, but it conflicts with a previous package which links to `sqlite3` as well:
package `libsqlite3-sys v0.26.0`
... which satisfies dependency `libsqlite3-sys = "^0.26.0"` of package `oxidize v0.0.0 (D:\Repo\*snip*)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='libsqlite3-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
failed to select a version for `libsqlite3-sys` which could resolve this conflict
```
## Possible Solution(s)
We could opt to only upgrade to versions of libsqlite3-sys which are compatible. That means it would have to analyze linking restrictions when selecting a new version.
We could also opt to allow the activation of transitive features. I'm sure that's been discussed somewhere but I can't find it right now.
Note that there's also the option for the transitive crate to re-export the desired feature, [but in the case of `diesel` the maintainer is unwilling to do so](https://github.com/diesel-rs/diesel/issues/3587#issuecomment-1501166521).
Contributor guide
Research direction
Reproduce the issue with the provided Cargo.toml and `cargo upgrade` command, then inspect how dependency versions are selected when `libsqlite3-sys` and Diesel share the `sqlite3` links value. Done means the upgrade avoids an incompatible native dependency version and the resulting manifest builds without the reported links conflict.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- build-system, cli
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100