Skip to content

Commit 407099e

Browse files
committed
Distinguish crates with the same name in type errors
Previously, errors for crates with the same name would only distinguish them by the span of the source: ``` note: `HashMap<_, _, _, _>` is defined in crate `hashbrown` --> /Users/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.12.3/src/map.rs:188:1 note: `HashMap<u32, u32>` is defined in crate `hashbrown` --> /Users/jyn/.local/lib/cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.12.3/src/map.rs:188:1 ``` When the same version of the crate is loaded twice, this isn't particularly helpful. Additionally show where the .rlib was loaded from (in this case one was loaded from the sysroot and the other from a cargo target dir).
1 parent 4b85902 commit 407099e

File tree

7 files changed

+71
-1
lines changed

7 files changed

+71
-1
lines changed

Diff for: compiler/rustc_infer/src/infer/error_reporting/mod.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1824,6 +1824,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18241824
let expected_defid = expected_adt.did();
18251825

18261826
diagnostic.note(format!("{found_name} and {expected_name} have similar names, but are actually distinct types"));
1827+
let have_same_crate_name = self.tcx.crate_name(found_defid.krate) == self.tcx.crate_name(expected_defid.krate);
18271828
for (defid, name) in
18281829
[(found_defid, found_name), (expected_defid, expected_name)]
18291830
{
@@ -1843,7 +1844,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18431844
format!("{name} is defined in the current crate")
18441845
} else {
18451846
let crate_name = self.tcx.crate_name(defid.krate);
1846-
format!("{name} is defined in crate `{crate_name}`")
1847+
diagnostic.span_note(def_span, format!("{name} is defined in crate `{crate_name}`"));
1848+
1849+
// If these are named the same, give a hint about why the compiler thinks they're different.
1850+
if have_same_crate_name {
1851+
let crate_paths = self.tcx.crate_extern_paths(defid.krate);
1852+
diagnostic.note(format!("`{crate_name}` was loaded from {}", crate_paths[0].display()));
1853+
}
1854+
1855+
continue;
18471856
};
18481857
diagnostic.span_note(def_span, msg);
18491858
}

Diff for: tests/incremental/circular-dependencies.rs

+2
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ fn test() {
2626
//[cfail2]~| NOTE arguments to this function are incorrect
2727
//[cfail2]~| NOTE `Foo` and `circular_dependencies::Foo` have similar names, but are actually distinct types
2828
//[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
29+
//[cfail2]~| NOTE loaded from
2930
//[cfail2]~| NOTE function defined here
3031

3132
consume_foo(aux::produce_foo());
3233
//[cfail2]~^ ERROR mismatched types [E0308]
3334
//[cfail2]~| NOTE expected `Foo`, found `circular_dependencies::Foo`
3435
//[cfail2]~| NOTE arguments to this function are incorrect
3536
//[cfail2]~| NOTE `circular_dependencies::Foo` and `Foo` have similar names, but are actually distinct types
37+
//[cfail2]~| NOTE loaded from
3638
//[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations
3739
}

Diff for: tests/run-make/type-mismatch-sysroot-crate/Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Test that we emit useful diagnostics when the same crate is loaded from the sysroot and --extern.
2+
# This can't be a run-make test because it needs the aux-file to itself have a dependency passed with --extern
3+
# (and just bare `--extern hashbrown` errors too early, while compiling `uses_hashbrown.rs`).
4+
5+
include ../tools.mk
6+
define SED_REGEX
7+
s#[^ ]*registry/src/index.crates.io[^ ]*/src#CARGO_REGISTRY/hashbrown-VERSION/src#;
8+
s#[^ ]*/build/[^ ]*/lib/rustlib/[^ ]*#BUILD_DIR/HOST/stageN/lib/rustlib/TARGET/lib/libhashbrown.rlib#;
9+
s#[^ ]*/build/[^ ]*/test/run-make/#BUILD_DIR/HOST/test/run-make/#
10+
s#[^ ]*tests/run-make/#TEST_DIR/#
11+
endef
12+
export SED_REGEX
13+
14+
all:
15+
$(RUSTC) hashbrown.rs --crate-type lib
16+
$(RUSTC) uses-hashbrown.rs --extern hashbrown=$(TMPDIR)/libhashbrown.rlib --crate-type lib
17+
$(RUSTC) mismatch.rs --extern uses_hashbrown=$(TMPDIR)/libuses_hashbrown.rlib 2>$(TMPDIR)/stderr.txt || true
18+
sed -e "$$SED_REGEX" < $(TMPDIR)/stderr.txt > $(TMPDIR)/normalized.txt
19+
$(RUSTC_TEST_OP) $(TMPDIR)/normalized.txt expected.txt
20+
$(CGREP) "loaded from" < $(TMPDIR)/stderr.txt
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0308]: mismatched types
2+
--> mismatch.rs:5:25
3+
|
4+
5 | uses_hashbrown::foo(hashbrown::HashMap::default())
5+
| ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `HashMap`, found `HashMap<_, _, _, _>`
6+
| |
7+
| arguments to this function are incorrect
8+
|
9+
= note: `hashbrown::HashMap<_, _, _, _>` and `hashbrown::HashMap` have similar names, but are actually distinct types
10+
note: `hashbrown::HashMap<_, _, _, _>` is defined in crate `hashbrown`
11+
--> CARGO_REGISTRY/hashbrown-VERSION/src/map.rs:190:1
12+
|
13+
190 | pub struct HashMap<K, V, S = DefaultHashBuilder, A: Allocator = Global> {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
= note: `hashbrown` was loaded from BUILD_DIR/HOST/stageN/lib/rustlib/TARGET/lib/libhashbrown.rlib
16+
note: `hashbrown::HashMap` is defined in crate `hashbrown`
17+
--> TEST_DIR/type-mismatch-sysroot-crate/hashbrown.rs:4:1
18+
|
19+
4 | pub struct HashMap;
20+
| ^^^^^^^^^^^^^^^^^^
21+
= note: `hashbrown` was loaded from BUILD_DIR/HOST/test/run-make/type-mismatch-sysroot-crate/type-mismatch-sysroot-crate/libhashbrown.rlib
22+
= note: perhaps two different versions of crate `hashbrown` are being used?
23+
note: function defined here
24+
--> TEST_DIR/type-mismatch-sysroot-crate/uses-hashbrown.rs:1:8
25+
|
26+
1 | pub fn foo(_: hashbrown::HashMap) {}
27+
| ^^^
28+
29+
error: aborting due to previous error
30+
31+
For more information about this error, try `rustc --explain E0308`.
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub struct HashMap;
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![feature(rustc_private)]
2+
extern crate hashbrown;
3+
4+
fn main() {
5+
uses_hashbrown::foo(hashbrown::HashMap::default())
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub fn foo(_: hashbrown::HashMap) {}

0 commit comments

Comments
 (0)