Skip to content
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

On trait bound mismatch, detect multiple crate versions in dep tree #124944

Merged
merged 8 commits into from
Aug 7, 2024

Conversation

estebank
Copy link
Contributor

@estebank estebank commented May 9, 2024

When encountering an E0277, if the type and the trait both come from a crate with the same name but different crate number, we explain that there are multiple crate versions in the dependency tree.

If there's a type that fulfills the bound, and it has the same name as the passed in type and has the same crate name, we explain that the same type in two different versions of the same crate are different.

error[E0277]: the trait bound `Type: dependency::Trait` is not satisfied
 --> src/main.rs:4:18
  |
4 |     do_something(Type);
  |     ------------ ^^^^ the trait `dependency::Trait` is not implemented for `Type`
  |     |
  |     required by a bound introduced by this call
  |
help: you have multiple different versions of crate `dependency` in your dependency graph
 --> src/main.rs:1:5
  |
1 | use bar::do_something;
  |     ^^^ one version of crate `dependency` is used here, as a dependency of crate `bar`
2 | use dependency::Type;
  |     ^^^^^^^^^^ one version of crate `dependency` is used here, as a direct dependency of the current crate
note: two types coming from two different versions of the same crate are different types even if they look the same
 --> /home/gh-estebank/crate_versions/baz-2/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type doesn't implement the required trait
  |
 ::: /home/gh-estebank/crate_versions/baz/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type implements the required trait
2 | pub trait Trait {}
  | --------------- this is the required trait
note: required by a bound in `bar::do_something`
 --> /home/gh-estebank/crate_versions/baz/src/lib.rs:4:24
  |
4 | pub fn do_something<X: Trait>(_: X) {}
  |                        ^^^^^ required by this bound in `do_something`

Address #22750.

@rustbot
Copy link
Collaborator

rustbot commented May 9, 2024

r? @fee1-dead

rustbot has assigned @fee1-dead.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 9, 2024
Copy link
Member

@fee1-dead fee1-dead left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! It would be nice if we could add a test for this though. Maybe run-make?

@weiznich
Copy link
Contributor

This new error message looks great ❤️

I think it would even be more helpful if it would point the user to use cargo tree as debugging tool for finding the sources of the duplicated crates in their dependency tree. From my experience from helping users with such issues they are often not aware that they have several versions of the same crate in their dependency tree. Sometimes the even question that this might be the issue. This is almost always resolved by pointing them to cargo tree -p $crate -i, although that command will likely not work out of the box as it requires specifying the version of $crate if it appears in different versions in your dependency tree. By default cargo tree will print a error message that contains the different versions that occur in your tree, so the user has at least a starting point from there.

Something else I noticed with this error message is that it only describes what's the problem, but it does not really mention how to resolve it. Maybe include something that essentially says: Try to restructure your dependency tree in such way that this uses the same version of that crate here?

@estebank
Copy link
Contributor Author

@weiznich added a note about cargo tree, but it gets somewhat lost in the noise :-/

@estebank
Copy link
Contributor Author

@fee1-dead added test

@fee1-dead
Copy link
Member

Looks great! Thanks for working on this!

@bors
Copy link
Contributor

bors commented May 13, 2024

📌 Commit 782cba8 has been approved by fee1-dead

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 13, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request May 13, 2024
…fee1-dead

On trait bound mismatch, detect multiple crate versions in dep tree

When encountering an E0277, if the type and the trait both come from a crate with the same name but different crate number, we explain that there are multiple crate versions in the dependency tree.

If there's a type that fulfills the bound, and it has the same name as the passed in type and has the same crate name, we explain that the same type in two different versions of the same crate *are different*.

```
error[E0277]: the trait bound `Type: dependency::Trait` is not satisfied
 --> src/main.rs:4:18
  |
4 |     do_something(Type);
  |     ------------ ^^^^ the trait `dependency::Trait` is not implemented for `Type`
  |     |
  |     required by a bound introduced by this call
  |
help: you have multiple different versions of crate `dependency` in your dependency graph
 --> src/main.rs:1:5
  |
1 | use bar::do_something;
  |     ^^^ one version of crate `dependency` is used here, as a dependency of crate `bar`
2 | use dependency::Type;
  |     ^^^^^^^^^^ one version of crate `dependency` is used here, as a direct dependency of the current crate
note: two types coming from two different versions of the same crate are different types even if they look the same
 --> /home/gh-estebank/crate_versions/baz-2/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type doesn't implement the required trait
  |
 ::: /home/gh-estebank/crate_versions/baz/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type implements the required trait
2 | pub trait Trait {}
  | --------------- this is the required trait
note: required by a bound in `bar::do_something`
 --> /home/gh-estebank/crate_versions/baz/src/lib.rs:4:24
  |
4 | pub fn do_something<X: Trait>(_: X) {}
  |                        ^^^^^ required by this bound in `do_something`
```

Address rust-lang#22750.
@bors
Copy link
Contributor

bors commented May 13, 2024

⌛ Testing commit 782cba8 with merge 3a9190b...

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented May 13, 2024

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 13, 2024
@estebank
Copy link
Contributor Author

Need to fix the tests, clearly they worked because of dirty environment only. I'll fix them.

@jieyouxu
Copy link
Member

@bors r- (tree is weird atm)

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 26, 2024
@estebank estebank force-pushed the multiple-crate-versions branch from 782cba8 to e756425 Compare June 24, 2024 19:12
@fee1-dead
Copy link
Member

Do the tests work now? If they do r=me

@estebank
Copy link
Contributor Author

@fee1-dead I haven't been able to replicate the CI failure in my dev env, which has stumped me.

@fee1-dead
Copy link
Member

If you want, you could modify the try CI config and use [at]bors try to replicate the CI test environment

@bors
Copy link
Contributor

bors commented Jul 9, 2024

☔ The latest upstream changes (presumably #127493) made this pull request unmergeable. Please resolve the merge conflicts.

@estebank estebank force-pushed the multiple-crate-versions branch 2 times, most recently from 8e26711 to a0f5dee Compare July 12, 2024 02:59
@estebank
Copy link
Contributor Author

@bors try

When encountering an E0277, if the type and the trait both come from a crate with the same name but different crate number, we explain that there are multiple crate versions in the dependency tree.

If there's a type that fulfills the bound, and it has the same name as the passed in type and has the same crate name, we explain that the same type in two different versions of the same crate *are different*.

```
error[E0277]: the trait bound `Type: dependency::Trait` is not satisfied
 --> src/main.rs:4:18
  |
4 |     do_something(Type);
  |     ------------ ^^^^ the trait `dependency::Trait` is not implemented for `Type`
  |     |
  |     required by a bound introduced by this call
  |
help: you have multiple different versions of crate `dependency` in your dependency graph
 --> src/main.rs:1:5
  |
1 | use bar::do_something;
  |     ^^^ one version of crate `dependency` is used here, as a dependency of crate `bar`
2 | use dependency::Type;
  |     ^^^^^^^^^^ one version of crate `dependency` is used here, as a direct dependency of the current crate
note: two types coming from two different versions of the same crate are different types even if they look the same
 --> /home/gh-estebank/crate_versions/baz-2/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type doesn't implement the required trait
  |
 ::: /home/gh-estebank/crate_versions/baz/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type implements the required trait
2 | pub trait Trait {}
  | --------------- this is the required trait
note: required by a bound in `bar::do_something`
 --> /home/gh-estebank/crate_versions/baz/src/lib.rs:4:24
  |
4 | pub fn do_something<X: Trait>(_: X) {}
  |                        ^^^^^ required by this bound in `do_something`
```

Address rust-lang#22750.
@estebank estebank force-pushed the multiple-crate-versions branch from b32a96c to 5e26c8d Compare August 6, 2024 17:58
@estebank estebank force-pushed the multiple-crate-versions branch from 6fdc364 to 034b73b Compare August 6, 2024 19:10
@estebank
Copy link
Contributor Author

estebank commented Aug 6, 2024

@bors r=fee1-dead

@bors
Copy link
Contributor

bors commented Aug 6, 2024

📌 Commit 034b73b has been approved by fee1-dead

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 6, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 7, 2024
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#124944 (On trait bound mismatch, detect multiple crate versions in dep tree)
 - rust-lang#125048 (PinCoerceUnsized trait into core)
 - rust-lang#128406 (implement BufReader::peek)
 - rust-lang#128539 (Forbid unused unsafe in vxworks-specific std modules)
 - rust-lang#128687 (interpret: refactor function call handling to be better-abstracted)
 - rust-lang#128692 (Add a triagebot mention for `library/Cargo.lock`)
 - rust-lang#128710 (Don't ICE when getting an input file name's stem fails)
 - rust-lang#128718 (Consider `cfg_attr` checked by `CheckAttrVisitor`)
 - rust-lang#128751 (std::thread: set_name implementation proposal for vxWorks.)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 38e631e into rust-lang:master Aug 7, 2024
6 checks passed
@rustbot rustbot added this to the 1.82.0 milestone Aug 7, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 7, 2024
Rollup merge of rust-lang#124944 - estebank:multiple-crate-versions, r=fee1-dead

On trait bound mismatch, detect multiple crate versions in dep tree

When encountering an E0277, if the type and the trait both come from a crate with the same name but different crate number, we explain that there are multiple crate versions in the dependency tree.

If there's a type that fulfills the bound, and it has the same name as the passed in type and has the same crate name, we explain that the same type in two different versions of the same crate *are different*.

```
error[E0277]: the trait bound `Type: dependency::Trait` is not satisfied
 --> src/main.rs:4:18
  |
4 |     do_something(Type);
  |     ------------ ^^^^ the trait `dependency::Trait` is not implemented for `Type`
  |     |
  |     required by a bound introduced by this call
  |
help: you have multiple different versions of crate `dependency` in your dependency graph
 --> src/main.rs:1:5
  |
1 | use bar::do_something;
  |     ^^^ one version of crate `dependency` is used here, as a dependency of crate `bar`
2 | use dependency::Type;
  |     ^^^^^^^^^^ one version of crate `dependency` is used here, as a direct dependency of the current crate
note: two types coming from two different versions of the same crate are different types even if they look the same
 --> /home/gh-estebank/crate_versions/baz-2/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type doesn't implement the required trait
  |
 ::: /home/gh-estebank/crate_versions/baz/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type implements the required trait
2 | pub trait Trait {}
  | --------------- this is the required trait
note: required by a bound in `bar::do_something`
 --> /home/gh-estebank/crate_versions/baz/src/lib.rs:4:24
  |
4 | pub fn do_something<X: Trait>(_: X) {}
  |                        ^^^^^ required by this bound in `do_something`
```

Address rust-lang#22750.
tgross35 added a commit to tgross35/rust that referenced this pull request Aug 17, 2024
…r=fee1-dead

Detect multiple crate versions on method not found

When a type comes indirectly from one crate version but the imported trait comes from a separate crate version, the called method won't be found. We now show additional context:

```
error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
 --> multiple-dep-versions.rs:8:10
  |
8 |     Type.foo();
  |          ^^^ method not found in `Type`
  |
note: there are multiple different versions of crate `dependency` in the dependency graph
 --> multiple-dep-versions.rs:4:32
  |
4 | use dependency::{do_something, Trait};
  |                                ^^^^^ `dependency` imported here doesn't correspond to the right crate version
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that was imported
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that is needed
5 |     fn foo(&self);
  |        --- the method is available for `dep_2_reexport::Type` here
```

Fix rust-lang#128569, fix rust-lang#110926, fix rust-lang#109161, fix rust-lang#81659, fix rust-lang#51458, fix rust-lang#32611. Follow up to rust-lang#124944.
tgross35 added a commit to tgross35/rust that referenced this pull request Aug 17, 2024
…r=fee1-dead

Detect multiple crate versions on method not found

When a type comes indirectly from one crate version but the imported trait comes from a separate crate version, the called method won't be found. We now show additional context:

```
error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
 --> multiple-dep-versions.rs:8:10
  |
8 |     Type.foo();
  |          ^^^ method not found in `Type`
  |
note: there are multiple different versions of crate `dependency` in the dependency graph
 --> multiple-dep-versions.rs:4:32
  |
4 | use dependency::{do_something, Trait};
  |                                ^^^^^ `dependency` imported here doesn't correspond to the right crate version
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that was imported
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that is needed
5 |     fn foo(&self);
  |        --- the method is available for `dep_2_reexport::Type` here
```

Fix rust-lang#128569, fix rust-lang#110926, fix rust-lang#109161, fix rust-lang#81659, fix rust-lang#51458, fix rust-lang#32611. Follow up to rust-lang#124944.
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 17, 2024
…fee1-dead

Detect multiple crate versions on method not found

When a type comes indirectly from one crate version but the imported trait comes from a separate crate version, the called method won't be found. We now show additional context:

```
error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
 --> multiple-dep-versions.rs:8:10
  |
8 |     Type.foo();
  |          ^^^ method not found in `Type`
  |
note: there are multiple different versions of crate `dependency` in the dependency graph
 --> multiple-dep-versions.rs:4:32
  |
4 | use dependency::{do_something, Trait};
  |                                ^^^^^ `dependency` imported here doesn't correspond to the right crate version
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that was imported
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that is needed
5 |     fn foo(&self);
  |        --- the method is available for `dep_2_reexport::Type` here
```

Fix rust-lang#128569, fix rust-lang#110926, fix rust-lang#109161, fix rust-lang#81659, fix rust-lang#51458, fix rust-lang#32611. Follow up to rust-lang#124944.
fee1-dead added a commit to fee1-dead-contrib/rust that referenced this pull request Sep 17, 2024
Don't call `extern_crate` when local crate name is the same as a dependency and we have a trait error

rust-lang#124944 implemented logic to point out when a trait bound failure involves a *trait* and *type* who come from identically named but different crates. This logic calls the `extern_crate` query which is not valid on `LOCAL_CRATE` cnum, so let's filter that out eagerly.

Fixes rust-lang#130272
Fixes rust-lang#129184
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Sep 17, 2024
Don't call `extern_crate` when local crate name is the same as a dependency and we have a trait error

rust-lang#124944 implemented logic to point out when a trait bound failure involves a *trait* and *type* who come from identically named but different crates. This logic calls the `extern_crate` query which is not valid on `LOCAL_CRATE` cnum, so let's filter that out eagerly.

Fixes rust-lang#130272
Fixes rust-lang#129184
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Sep 17, 2024
Rollup merge of rust-lang#130275 - compiler-errors:extern-crate, r=lcnr

Don't call `extern_crate` when local crate name is the same as a dependency and we have a trait error

rust-lang#124944 implemented logic to point out when a trait bound failure involves a *trait* and *type* who come from identically named but different crates. This logic calls the `extern_crate` query which is not valid on `LOCAL_CRATE` cnum, so let's filter that out eagerly.

Fixes rust-lang#130272
Fixes rust-lang#129184
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-run-make Area: port run-make Makefiles to rmake.rs S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

10 participants