Skip to content

Commit c225e5c

Browse files
committed
Provide more information on duplicate lang item error.
1 parent 665190b commit c225e5c

File tree

10 files changed

+49
-4
lines changed

10 files changed

+49
-4
lines changed

src/librustc_metadata/rmeta/decoder/cstore_impl.rs

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc_span::symbol::{Ident, Symbol};
2727
use rustc_data_structures::sync::Lrc;
2828
use smallvec::SmallVec;
2929
use std::any::Any;
30+
use std::path::PathBuf;
3031

3132
macro_rules! provide {
3233
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
@@ -513,4 +514,8 @@ impl CrateStore for CStore {
513514
fn allocator_kind(&self) -> Option<AllocatorKind> {
514515
self.allocator_kind()
515516
}
517+
518+
fn crate_extern_paths(&self, cnum: CrateNum) -> Vec<PathBuf> {
519+
self.get_crate_data(cnum).source().paths().cloned().collect()
520+
}
516521
}

src/librustc_middle/middle/cstore.rs

+1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ pub trait CrateStore {
203203
fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
204204
fn metadata_encoding_version(&self) -> &[u8];
205205
fn allocator_kind(&self) -> Option<AllocatorKind>;
206+
fn crate_extern_paths(&self, cnum: CrateNum) -> Vec<PathBuf>;
206207
}
207208

208209
pub type CrateStoreDyn = dyn CrateStore + sync::Sync;

src/librustc_middle/ty/context.rs

+9
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ use std::hash::{Hash, Hasher};
6262
use std::iter;
6363
use std::mem;
6464
use std::ops::{Bound, Deref};
65+
use std::path::PathBuf;
6566
use std::sync::Arc;
6667

6768
type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
@@ -1252,6 +1253,14 @@ impl<'tcx> TyCtxt<'tcx> {
12521253
if cnum == LOCAL_CRATE { false } else { self.cstore.crate_is_private_dep_untracked(cnum) }
12531254
}
12541255

1256+
pub fn crate_extern_paths(&self, cnum: CrateNum) -> Vec<PathBuf> {
1257+
if cnum == LOCAL_CRATE {
1258+
self.sess.local_crate_source_file.iter().cloned().collect()
1259+
} else {
1260+
self.cstore.crate_extern_paths(cnum)
1261+
}
1262+
}
1263+
12551264
#[inline]
12561265
pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
12571266
if let Some(def_id) = def_id.as_local() {

src/librustc_passes/lang_items.rs

+21
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,27 @@ impl LanguageItemCollector<'tcx> {
146146
));
147147
}
148148
}
149+
let mut note_def = |which, def_id: DefId| {
150+
let location = if def_id.is_local() {
151+
"the local crate".to_string()
152+
} else {
153+
let paths: Vec<_> = self
154+
.tcx
155+
.crate_extern_paths(def_id.krate)
156+
.iter()
157+
.map(|p| p.display().to_string())
158+
.collect();
159+
paths.join(", ")
160+
};
161+
err.note(&format!(
162+
"{} definition in `{}` loaded from {}",
163+
which,
164+
self.tcx.crate_name(def_id.krate),
165+
location
166+
));
167+
};
168+
note_def("first", original_def_id);
169+
note_def("second", item_def_id);
149170
}
150171
err.emit();
151172
}

src/test/ui/duplicate_entry_error.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib"
12
// note-pattern: first defined in crate `std`.
23

34
// Test for issue #31788 and E0152

src/test/ui/duplicate_entry_error.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0152]: found duplicate lang item `panic_impl`
2-
--> $DIR/duplicate_entry_error.rs:10:1
2+
--> $DIR/duplicate_entry_error.rs:11:1
33
|
44
LL | / fn panic_impl(info: &PanicInfo) -> ! {
55
LL | |
@@ -8,6 +8,8 @@ LL | | }
88
| |_^
99
|
1010
= note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on)
11+
= note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
12+
= note: second definition in `duplicate_entry_error` loaded from the local crate
1113

1214
error: aborting due to previous error
1315

src/test/ui/error-codes/E0152.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// normalize-stderr-test "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib"
12
#![feature(lang_items)]
23

34
#[lang = "owned_box"]

src/test/ui/error-codes/E0152.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
error[E0152]: found duplicate lang item `owned_box`
2-
--> $DIR/E0152.rs:4:1
2+
--> $DIR/E0152.rs:5:1
33
|
44
LL | struct Foo;
55
| ^^^^^^^^^^^
66
|
77
= note: the lang item is first defined in crate `alloc` (which `std` depends on)
8+
= note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib
9+
= note: second definition in `E0152` loaded from the local crate
810

911
error: aborting due to previous error
1012

src/test/ui/panic-handler/panic-handler-std.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib"
12
// error-pattern: found duplicate lang item `panic_impl`
23

34

src/test/ui/panic-handler/panic-handler-std.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
error[E0152]: found duplicate lang item `panic_impl`
2-
--> $DIR/panic-handler-std.rs:7:1
2+
--> $DIR/panic-handler-std.rs:8:1
33
|
44
LL | / fn panic(info: PanicInfo) -> ! {
55
LL | | loop {}
66
LL | | }
77
| |_^
88
|
99
= note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on)
10+
= note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
11+
= note: second definition in `panic_handler_std` loaded from the local crate
1012

1113
error: argument should be `&PanicInfo`
12-
--> $DIR/panic-handler-std.rs:7:16
14+
--> $DIR/panic-handler-std.rs:8:16
1315
|
1416
LL | fn panic(info: PanicInfo) -> ! {
1517
| ^^^^^^^^^

0 commit comments

Comments
 (0)