Description
Problem
Two crates using the same library can fail to compile if one library version is updated in the Cargo.toml
, but the other is not. If you do not run cargo update <other crate>
then rustc will give you mysterious errors that tell you that the structs are mis-matched but do not hint that the problem is solvable via a cargo update
.
I'm unsure if this is an enhancement that would fall in rustc or in cargo, but reporting here.
Proposed Solution
Desired
error[E0631]: type mismatch in function arguments
--> src/main.rs:7:89
|
3 | Cmd(fun_run::CmdError)
| --- found signature defined here
...
7 | print::sub_stream_cmd(std::process::Command::new("echo").arg("hello world")).map_err(Errorz::Cmd).unwrap();
| ------- ^^^^^^^^^^^ expected due to this
| |
| required by a bound introduced by this call
|
= note: expected function signature `fn(fun_run::CmdError) -> _` imported by crate `fun_run`
found function signature `fn(CmdError) -> _` imported by crate `bullet_stream` that depends on `fun_run` (`>=0.5, <1`). Run `cargo update bullet_stream` to update it's locked sub-dependencies
note: required by a bound in `Result::<T, E>::map_err`
--> /Users/rschneeman/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:853:26
help: consider running `cargo update bullet_stream`
Also, it would be nice if cargo tree
could identify dependencies that COULD be unified but aren't due to their locked status. It wouldn't be as nice as inside of the compiler error, but I was lead to cargo tree
for debugging this problem. Perhaps we could update cargo tree
to hint at possible cargo update
options, and then compiler error could hint to run cargo tree
(instead of trying to reverse the logic of how that dependency resolved to that type from that crate and that version, which seems hard as I type it out).
Notes
Full output of a reproduction:
See more
$ cat src/main.rs
use bullet_stream::global::print;
enum Errorz {
Cmd(fun_run::CmdError)
}
fn main() {
print::sub_stream_cmd(std::process::Command::new("echo").arg("hello world")).map_err(Errorz::Cmd).unwrap();
}
$ cat Cargo.toml
[package]
name = "lol"
version = "0.1.0"
edition = "2024"
[dependencies]
bullet_stream = { version = "0.8.0", features = ["fun_run"]}
fun_run = "0.5.0"
$ cat Cargo.lock
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "bullet_stream"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc54f3252b0ff30201f78a466a017afef4da0ec6c669efcabef8d4cec7c0d58"
dependencies = [
"fun_run",
]
[[package]]
name = "fun_run"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60475c9540e62902b2b2e292be87f61df540c7e0f0bdb92416fd5ae792450049"
dependencies = [
"regex",
]
[[package]]
name = "lol"
version = "0.1.0"
dependencies = [
"bullet_stream",
"fun_run",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
$ cargo tree
lol v0.1.0 (/private/tmp/c3c7baffda7a90a43a79ebd5d642b33c/lol)
├── bullet_stream v0.8.0
│ └── fun_run v0.5.0
│ └── regex v1.11.1
│ ├── aho-corasick v1.1.3
│ │ └── memchr v2.7.4
│ ├── memchr v2.7.4
│ ├── regex-automata v0.4.9
│ │ ├── aho-corasick v1.1.3 (*)
│ │ ├── memchr v2.7.4
│ │ └── regex-syntax v0.8.5
│ └── regex-syntax v0.8.5
└── fun_run v0.5.0 (*)
$ echo "Update Cargo.toml"
Update Cargo.toml
$ cat Cargo.toml
[package]
name = "lol"
version = "0.1.0"
edition = "2024"
[dependencies]
bullet_stream = { version = "0.8.0", features = ["fun_run"]}
fun_run = "0.6.0"
$ cargo tree
lol v0.1.0 (/private/tmp/c3c7baffda7a90a43a79ebd5d642b33c/lol)
├── bullet_stream v0.8.0
│ └── fun_run v0.5.0
│ └── regex v1.11.1
│ ├── aho-corasick v1.1.3
│ │ └── memchr v2.7.4
│ ├── memchr v2.7.4
│ ├── regex-automata v0.4.9
│ │ ├── aho-corasick v1.1.3 (*)
│ │ ├── memchr v2.7.4
│ │ └── regex-syntax v0.8.5
│ └── regex-syntax v0.8.5
└── fun_run v0.6.0
└── regex v1.11.1 (*)
$ cargo build
Compiling lol v0.1.0 (/private/tmp/c3c7baffda7a90a43a79ebd5d642b33c/lol)
error[E0631]: type mismatch in function arguments
--> src/main.rs:7:90
|
3 | Cmd(fun_run::CmdError)
| --- found signature defined here
...
7 | print::sub_stream_cmd(std::process::Command::new("echo").arg("hello world")).map_err(Errorz::Cmd).unwrap();
| ------- ^^^^^^^^^^^ expected due to this
| |
| required by a bound introduced by this call
|
= note: expected function signature `fn(fun_run::CmdError) -> _`
found function signature `fn(CmdError) -> _`
note: required by a bound in `Result::<T, E>::map_err`
--> /Users/rschneeman/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:853:26
|
853 | pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, F> {
| ^^^^^^^^^^^^^^ required by this bound in `Result::<T, E>::map_err`
help: consider wrapping the function in a closure
|
7 | print::sub_stream_cmd(std::process::Command::new("echo").arg("hello world")).map_err(|arg0: fun_run::CmdError| Errorz::Cmd(/* CmdError */)).unwrap();
| +++++++++++++++++++++++++ ++++++++++++++++
For more information about this error, try `rustc --explain E0631`.
error: could not compile `lol` (bin "lol") due to 1 previous error