Skip to content

Commit 6fbf444

Browse files
committed
Tweak diagnostic output
``` error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version --> multiple-dep-versions.rs:7:18 | 7 | do_something(Type); | ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` | note: there are multiple different versions of crate `dependency` in the dependency graph --> /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1 | 3 | pub struct Type(pub i32); | --------------- this type implements the required trait 4 | pub trait Trait { | ^^^^^^^^^^^^^^^ this is the required trait | ::: multiple-dep-versions.rs:1:1 | 1 | extern crate dep_2_reexport; | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo` 2 | extern crate dependency; | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate | ::: /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:3:1 | 3 | pub struct Type; | --------------- this type doesn't implement the required trait 4 | pub trait Trait { | --------------- this is the found trait = note: two types coming from two different versions of the same crate are different types even if they look the same = help: you can use `cargo tree` to explore your dependency tree note: required by a bound in `do_something` --> /home/gh-estebank/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:12:24 | 12 | pub fn do_something<X: Trait>(_: X) {} | ^^^^^ required by this bound in `do_something` ```
1 parent 35bde07 commit 6fbf444

File tree

2 files changed

+48
-58
lines changed

2 files changed

+48
-58
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+21-19
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17231723
} else {
17241724
None
17251725
};
1726-
let spans: Vec<_> = [trait_def_id, other_trait_def_id]
1726+
let candidates = if impl_candidates.is_empty() {
1727+
alternative_candidates(trait_def_id)
1728+
} else {
1729+
impl_candidates.into_iter().map(|cand| cand.trait_ref).collect()
1730+
};
1731+
let mut span: MultiSpan = self.tcx.def_span(trait_def_id).into();
1732+
span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait");
1733+
for (sp, label) in [trait_def_id, other_trait_def_id]
17271734
.iter()
17281735
.filter_map(|def_id| self.tcx.extern_crate(def_id.krate))
17291736
.map(|data| {
@@ -1740,25 +1747,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17401747
),
17411748
)
17421749
})
1743-
.collect();
1744-
let mut span: MultiSpan = spans.iter().map(|(sp, _)| *sp).collect::<Vec<Span>>().into();
1745-
for (sp, label) in spans.into_iter() {
1750+
{
17461751
span.push_span_label(sp, label);
17471752
}
1748-
err.highlighted_span_help(span, vec![
1749-
StringPart::normal("there are ".to_string()),
1750-
StringPart::highlighted("multiple different versions".to_string()),
1751-
StringPart::normal(" of crate `".to_string()),
1752-
StringPart::highlighted(format!("{crate_name}")),
1753-
StringPart::normal("` in the dependency graph".to_string()),
1754-
]);
1755-
let candidates = if impl_candidates.is_empty() {
1756-
alternative_candidates(trait_def_id)
1757-
} else {
1758-
impl_candidates.into_iter().map(|cand| cand.trait_ref).collect()
1759-
};
1760-
let mut span: MultiSpan = self.tcx.def_span(trait_def_id).into();
1761-
span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait");
17621753
if let Some(found_type) = found_type {
17631754
span.push_span_label(
17641755
self.tcx.def_span(found_type),
@@ -1786,14 +1777,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17861777
}
17871778
span.push_span_label(self.tcx.def_span(other_trait_def_id), "this is the found trait");
17881779
err.highlighted_span_note(span, vec![
1780+
StringPart::normal("there are ".to_string()),
1781+
StringPart::highlighted("multiple different versions".to_string()),
1782+
StringPart::normal(" of crate `".to_string()),
1783+
StringPart::highlighted(format!("{crate_name}")),
1784+
StringPart::normal("` in the dependency graph\n".to_string()),
1785+
]);
1786+
err.highlighted_note(vec![
17891787
StringPart::normal(
17901788
"two types coming from two different versions of the same crate are \
17911789
different types "
17921790
.to_string(),
17931791
),
17941792
StringPart::highlighted("even if they look the same".to_string()),
17951793
]);
1796-
err.help("you can use `cargo tree` to explore your dependency tree");
1794+
err.highlighted_help(vec![
1795+
StringPart::normal("you can use `".to_string()),
1796+
StringPart::highlighted("cargo tree".to_string()),
1797+
StringPart::normal("` to explore your dependency tree".to_string()),
1798+
]);
17971799
return true;
17981800
}
17991801

tests/run-make/crate-loading/rmake.rs

+27-39
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,45 @@ fn main() {
1818
.extern_("dependency", rust_lib_name("dependency"))
1919
.extern_("dep_2_reexport", rust_lib_name("foo"))
2020
.run_fail()
21-
.assert_stderr_contains(
22-
r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
21+
.assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
2322
--> multiple-dep-versions.rs:7:18
2423
|
2524
7 | do_something(Type);
2625
| ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
2726
| |
2827
| required by a bound introduced by this call
2928
|
30-
help: there are multiple different versions of crate `dependency` in the dependency graph
31-
--> multiple-dep-versions.rs:1:1
32-
|
33-
1 | extern crate dep_2_reexport;
34-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one version of crate `dependency` is used here, as a dependency of crate `foo`
35-
2 | extern crate dependency;
36-
| ^^^^^^^^^^^^^^^^^^^^^^^^ one version of crate `dependency` is used here, as a direct dependency of the current crate"#,
37-
)
38-
.assert_stderr_contains(
39-
r#"
29+
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
30+
.assert_stderr_contains(r#"
4031
3 | pub struct Type(pub i32);
4132
| --------------- this type implements the required trait
4233
4 | pub trait Trait {
43-
| ^^^^^^^^^^^^^^^ this is the required trait"#,
44-
)
45-
.assert_stderr_contains(
46-
r#"
34+
| ^^^^^^^^^^^^^^^ this is the required trait
35+
"#)
36+
.assert_stderr_contains(r#"
37+
1 | extern crate dep_2_reexport;
38+
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
39+
2 | extern crate dependency;
40+
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#)
41+
.assert_stderr_contains(r#"
4742
3 | pub struct Type;
4843
| --------------- this type doesn't implement the required trait
4944
4 | pub trait Trait {
5045
| --------------- this is the found trait
51-
= help: you can use `cargo tree` to explore your dependency tree"#,
52-
)
53-
.assert_stderr_contains(
54-
r#"
55-
error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
46+
= note: two types coming from two different versions of the same crate are different types even if they look the same
47+
= help: you can use `cargo tree` to explore your dependency tree"#)
48+
.assert_stderr_contains(r#"note: required by a bound in `do_something`"#)
49+
.assert_stderr_contains(r#"
50+
12 | pub fn do_something<X: Trait>(_: X) {}
51+
| ^^^^^ required by this bound in `do_something`"#)
52+
.assert_stderr_contains(r#"error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
5653
--> multiple-dep-versions.rs:8:10
5754
|
5855
8 | Type.foo();
5956
| ^^^ method not found in `Type`
6057
|
61-
note: there are multiple different versions of crate `dependency` in the dependency graph"#,
62-
)
63-
.assert_stderr_contains(
64-
r#"
58+
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
59+
.assert_stderr_contains(r#"
6560
4 | pub trait Trait {
6661
| ^^^^^^^^^^^^^^^ this is the trait that is needed
6762
5 | fn foo(&self);
@@ -70,25 +65,19 @@ note: there are multiple different versions of crate `dependency` in the depende
7065
::: multiple-dep-versions.rs:4:18
7166
|
7267
4 | use dependency::{Trait, do_something};
73-
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#,
74-
)
75-
.assert_stderr_contains(
76-
r#"
68+
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
69+
.assert_stderr_contains(r#"
7770
4 | pub trait Trait {
78-
| --------------- this is the trait that was imported"#,
79-
)
80-
.assert_stderr_contains(
81-
r#"
71+
| --------------- this is the trait that was imported"#)
72+
.assert_stderr_contains(r#"
8273
error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope
8374
--> multiple-dep-versions.rs:9:11
8475
|
8576
9 | Type::bar();
8677
| ^^^ function or associated item not found in `Type`
8778
|
88-
note: there are multiple different versions of crate `dependency` in the dependency graph"#,
89-
)
90-
.assert_stderr_contains(
91-
r#"
79+
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
80+
.assert_stderr_contains(r#"
9281
4 | pub trait Trait {
9382
| ^^^^^^^^^^^^^^^ this is the trait that is needed
9483
5 | fn foo(&self);
@@ -98,8 +87,7 @@ note: there are multiple different versions of crate `dependency` in the depende
9887
::: multiple-dep-versions.rs:4:18
9988
|
10089
4 | use dependency::{Trait, do_something};
101-
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#,
102-
)
90+
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
10391
.assert_stderr_contains(
10492
r#"
10593
6 | pub struct OtherType;

0 commit comments

Comments
 (0)