about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs40
-rw-r--r--tests/run-make/crate-loading/rmake.rs66
2 files changed, 48 insertions, 58 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index b3d622d0c9b..088fa668914 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1723,7 +1723,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 } else {
                     None
                 };
-            let spans: Vec<_> = [trait_def_id, other_trait_def_id]
+            let candidates = if impl_candidates.is_empty() {
+                alternative_candidates(trait_def_id)
+            } else {
+                impl_candidates.into_iter().map(|cand| cand.trait_ref).collect()
+            };
+            let mut span: MultiSpan = self.tcx.def_span(trait_def_id).into();
+            span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait");
+            for (sp, label) in [trait_def_id, other_trait_def_id]
                 .iter()
                 .filter_map(|def_id| self.tcx.extern_crate(def_id.krate))
                 .map(|data| {
@@ -1740,25 +1747,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         ),
                     )
                 })
-                .collect();
-            let mut span: MultiSpan = spans.iter().map(|(sp, _)| *sp).collect::<Vec<Span>>().into();
-            for (sp, label) in spans.into_iter() {
+            {
                 span.push_span_label(sp, label);
             }
-            err.highlighted_span_help(span, vec![
-                StringPart::normal("there are ".to_string()),
-                StringPart::highlighted("multiple different versions".to_string()),
-                StringPart::normal(" of crate `".to_string()),
-                StringPart::highlighted(format!("{crate_name}")),
-                StringPart::normal("` in the dependency graph".to_string()),
-            ]);
-            let candidates = if impl_candidates.is_empty() {
-                alternative_candidates(trait_def_id)
-            } else {
-                impl_candidates.into_iter().map(|cand| cand.trait_ref).collect()
-            };
-            let mut span: MultiSpan = self.tcx.def_span(trait_def_id).into();
-            span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait");
             if let Some(found_type) = found_type {
                 span.push_span_label(
                     self.tcx.def_span(found_type),
@@ -1786,6 +1777,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
             span.push_span_label(self.tcx.def_span(other_trait_def_id), "this is the found trait");
             err.highlighted_span_note(span, vec![
+                StringPart::normal("there are ".to_string()),
+                StringPart::highlighted("multiple different versions".to_string()),
+                StringPart::normal(" of crate `".to_string()),
+                StringPart::highlighted(format!("{crate_name}")),
+                StringPart::normal("` in the dependency graph\n".to_string()),
+            ]);
+            err.highlighted_note(vec![
                 StringPart::normal(
                     "two types coming from two different versions of the same crate are \
                          different types "
@@ -1793,7 +1791,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 ),
                 StringPart::highlighted("even if they look the same".to_string()),
             ]);
-            err.help("you can use `cargo tree` to explore your dependency tree");
+            err.highlighted_help(vec![
+                StringPart::normal("you can use `".to_string()),
+                StringPart::highlighted("cargo tree".to_string()),
+                StringPart::normal("` to explore your dependency tree".to_string()),
+            ]);
             return true;
         }
 
diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs
index ea8802f6e2a..544bf9ab957 100644
--- a/tests/run-make/crate-loading/rmake.rs
+++ b/tests/run-make/crate-loading/rmake.rs
@@ -18,8 +18,7 @@ fn main() {
         .extern_("dependency", rust_lib_name("dependency"))
         .extern_("dep_2_reexport", rust_lib_name("foo"))
         .run_fail()
-        .assert_stderr_contains(
-            r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
+        .assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
   --> multiple-dep-versions.rs:7:18
    |
 7  |     do_something(Type);
@@ -27,41 +26,37 @@ fn main() {
    |     |
    |     required by a bound introduced by this call
    |
-help: there are multiple different versions of crate `dependency` in the dependency graph
-  --> 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"#,
-        )
-        .assert_stderr_contains(
-            r#"
+note: there are multiple different versions of crate `dependency` in the dependency graph"#)
+        .assert_stderr_contains(r#"
 3  | pub struct Type(pub i32);
    | --------------- this type implements the required trait
 4  | pub trait Trait {
-   | ^^^^^^^^^^^^^^^ this is the required trait"#,
-        )
-        .assert_stderr_contains(
-            r#"
+   | ^^^^^^^^^^^^^^^ this is the required trait
+"#)
+        .assert_stderr_contains(r#"
+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"#)
+        .assert_stderr_contains(r#"
 3  | pub struct Type;
    | --------------- this type doesn't implement the required trait
 4  | pub trait Trait {
    | --------------- this is the found trait
-   = help: you can use `cargo tree` to explore your dependency tree"#,
-        )
-        .assert_stderr_contains(
-            r#"
-error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
+   = 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"#)
+        .assert_stderr_contains(r#"note: required by a bound in `do_something`"#)
+        .assert_stderr_contains(r#"
+12 | pub fn do_something<X: Trait>(_: X) {}
+   |                        ^^^^^ required by this bound in `do_something`"#)
+        .assert_stderr_contains(r#"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"#,
-        )
-        .assert_stderr_contains(
-            r#"
+note: there are multiple different versions of crate `dependency` in the dependency graph"#)
+        .assert_stderr_contains(r#"
 4 | pub trait Trait {
   | ^^^^^^^^^^^^^^^ this is the trait that is needed
 5 |     fn foo(&self);
@@ -70,25 +65,19 @@ note: there are multiple different versions of crate `dependency` in the depende
  ::: multiple-dep-versions.rs:4:18
   |
 4 | use dependency::{Trait, do_something};
-  |                  ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#,
-        )
-        .assert_stderr_contains(
-            r#"
+  |                  ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
+        .assert_stderr_contains(r#"
 4 | pub trait Trait {
-  | --------------- this is the trait that was imported"#,
-        )
-        .assert_stderr_contains(
-            r#"
+  | --------------- this is the trait that was imported"#)
+        .assert_stderr_contains(r#"
 error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope
  --> multiple-dep-versions.rs:9:11
   |
 9 |     Type::bar();
   |           ^^^ function or associated item not found in `Type`
   |
-note: there are multiple different versions of crate `dependency` in the dependency graph"#,
-        )
-        .assert_stderr_contains(
-            r#"
+note: there are multiple different versions of crate `dependency` in the dependency graph"#)
+        .assert_stderr_contains(r#"
 4 | pub trait Trait {
   | ^^^^^^^^^^^^^^^ this is the trait that is needed
 5 |     fn foo(&self);
@@ -98,8 +87,7 @@ note: there are multiple different versions of crate `dependency` in the depende
  ::: multiple-dep-versions.rs:4:18
   |
 4 | use dependency::{Trait, do_something};
-  |                  ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#,
-        )
+  |                  ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
         .assert_stderr_contains(
           r#"
 6  | pub struct OtherType;