about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs21
-rw-r--r--tests/incremental/auxiliary/circular-dependencies-aux.rs10
-rw-r--r--tests/incremental/circular-dependencies.rs37
3 files changed, 61 insertions, 7 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 8a2b800af0e..7ce6bd418eb 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -613,9 +613,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
 
         let report_path_match = |err: &mut Diagnostic, did1: DefId, did2: DefId| {
-            // Only external crates, if either is from a local
-            // module we could have false positives
-            if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
+            // Only report definitions from different crates. If both definitions
+            // are from a local module we could have false positives, e.g.
+            // let _ = [{struct Foo; Foo}, {struct Foo; Foo}];
+            if did1.krate != did2.krate {
                 let abs_path =
                     |def_id| AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]);
 
@@ -627,10 +628,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 };
                 if same_path().unwrap_or(false) {
                     let crate_name = self.tcx.crate_name(did1.krate);
-                    err.note(&format!(
-                        "perhaps two different versions of crate `{}` are being used?",
-                        crate_name
-                    ));
+                    let msg = if did1.is_local() || did2.is_local() {
+                        format!(
+                            "the crate `{crate_name}` is compiled multiple times, possibly with different configurations"
+                        )
+                    } else {
+                        format!(
+                            "perhaps two different versions of crate `{crate_name}` are being used?"
+                        )
+                    };
+                    err.note(msg);
                 }
             }
         };
diff --git a/tests/incremental/auxiliary/circular-dependencies-aux.rs b/tests/incremental/auxiliary/circular-dependencies-aux.rs
new file mode 100644
index 00000000000..0e74eb1b2f2
--- /dev/null
+++ b/tests/incremental/auxiliary/circular-dependencies-aux.rs
@@ -0,0 +1,10 @@
+// edition: 2021
+// compile-flags: --crate-type lib --extern circular_dependencies={{build-base}}/circular-dependencies/libcircular_dependencies.rmeta --emit dep-info,metadata
+
+use circular_dependencies::Foo;
+
+pub fn consume_foo(_: Foo) {}
+
+pub fn produce_foo() -> Foo {
+    Foo
+}
diff --git a/tests/incremental/circular-dependencies.rs b/tests/incremental/circular-dependencies.rs
new file mode 100644
index 00000000000..10673066a9d
--- /dev/null
+++ b/tests/incremental/circular-dependencies.rs
@@ -0,0 +1,37 @@
+// ignore-tidy-linelength
+// revisions: cpass1 cfail2
+// edition: 2021
+// [cpass1] compile-flags: --crate-type lib --emit dep-info,metadata
+// [cfail2] aux-build: circular-dependencies-aux.rs
+// [cfail2] compile-flags: --test --extern aux={{build-base}}/circular-dependencies/auxiliary/libcircular_dependencies_aux.rmeta -L dependency={{build-base}}/circular-dependencies
+
+pub struct Foo;
+//[cfail2]~^ NOTE `Foo` is defined in the current crate
+//[cfail2]~| NOTE `Foo` is defined in the current crate
+//[cfail2]~| NOTE `circular_dependencies::Foo` is defined in crate `circular_dependencies`
+//[cfail2]~| NOTE `circular_dependencies::Foo` is defined in crate `circular_dependencies`
+
+pub fn consume_foo(_: Foo) {}
+//[cfail2]~^ NOTE function defined here
+
+pub fn produce_foo() -> Foo {
+    Foo
+}
+
+#[test]
+fn test() {
+    aux::consume_foo(produce_foo());
+    //[cfail2]~^ ERROR mismatched types [E0308]
+    //[cfail2]~| NOTE expected `circular_dependencies::Foo`, found `Foo`
+    //[cfail2]~| NOTE arguments to this function are incorrect
+    //[cfail2]~| NOTE `Foo` and `circular_dependencies::Foo` have similar names, but are actually distinct types
+    //[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
+    //[cfail2]~| NOTE function defined here
+
+    consume_foo(aux::produce_foo());
+    //[cfail2]~^ ERROR mismatched types [E0308]
+    //[cfail2]~| NOTE expected `Foo`, found `circular_dependencies::Foo`
+    //[cfail2]~| NOTE arguments to this function are incorrect
+    //[cfail2]~| NOTE `circular_dependencies::Foo` and `Foo` have similar names, but are actually distinct types
+    //[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
+}