From c225e5c5cb1200f46b83752e160b489eba1cd597 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 17 Jun 2020 11:05:30 -0700 Subject: [PATCH] Provide more information on duplicate lang item error. --- .../rmeta/decoder/cstore_impl.rs | 5 +++++ src/librustc_middle/middle/cstore.rs | 1 + src/librustc_middle/ty/context.rs | 9 ++++++++ src/librustc_passes/lang_items.rs | 21 +++++++++++++++++++ src/test/ui/duplicate_entry_error.rs | 1 + src/test/ui/duplicate_entry_error.stderr | 4 +++- src/test/ui/error-codes/E0152.rs | 1 + src/test/ui/error-codes/E0152.stderr | 4 +++- .../ui/panic-handler/panic-handler-std.rs | 1 + .../ui/panic-handler/panic-handler-std.stderr | 6 ++++-- 10 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index 1b168bf0117..3472d8987c6 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -27,6 +27,7 @@ use rustc_span::symbol::{Ident, Symbol}; use rustc_data_structures::sync::Lrc; use smallvec::SmallVec; use std::any::Any; +use std::path::PathBuf; macro_rules! provide { (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, @@ -513,4 +514,8 @@ impl CrateStore for CStore { fn allocator_kind(&self) -> Option { self.allocator_kind() } + + fn crate_extern_paths(&self, cnum: CrateNum) -> Vec { + self.get_crate_data(cnum).source().paths().cloned().collect() + } } diff --git a/src/librustc_middle/middle/cstore.rs b/src/librustc_middle/middle/cstore.rs index 97e877df966..91754f458c8 100644 --- a/src/librustc_middle/middle/cstore.rs +++ b/src/librustc_middle/middle/cstore.rs @@ -203,6 +203,7 @@ pub trait CrateStore { fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata; fn metadata_encoding_version(&self) -> &[u8]; fn allocator_kind(&self) -> Option; + fn crate_extern_paths(&self, cnum: CrateNum) -> Vec; } pub type CrateStoreDyn = dyn CrateStore + sync::Sync; diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index e2f601371b1..e6c0cd24bff 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -62,6 +62,7 @@ use std::hash::{Hash, Hasher}; use std::iter; use std::mem; use std::ops::{Bound, Deref}; +use std::path::PathBuf; use std::sync::Arc; type InternedSet<'tcx, T> = ShardedHashMap, ()>; @@ -1252,6 +1253,14 @@ impl<'tcx> TyCtxt<'tcx> { if cnum == LOCAL_CRATE { false } else { self.cstore.crate_is_private_dep_untracked(cnum) } } + pub fn crate_extern_paths(&self, cnum: CrateNum) -> Vec { + if cnum == LOCAL_CRATE { + self.sess.local_crate_source_file.iter().cloned().collect() + } else { + self.cstore.crate_extern_paths(cnum) + } + } + #[inline] pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash { if let Some(def_id) = def_id.as_local() { diff --git a/src/librustc_passes/lang_items.rs b/src/librustc_passes/lang_items.rs index 0be37cb0960..d2635b89545 100644 --- a/src/librustc_passes/lang_items.rs +++ b/src/librustc_passes/lang_items.rs @@ -146,6 +146,27 @@ impl LanguageItemCollector<'tcx> { )); } } + let mut note_def = |which, def_id: DefId| { + let location = if def_id.is_local() { + "the local crate".to_string() + } else { + let paths: Vec<_> = self + .tcx + .crate_extern_paths(def_id.krate) + .iter() + .map(|p| p.display().to_string()) + .collect(); + paths.join(", ") + }; + err.note(&format!( + "{} definition in `{}` loaded from {}", + which, + self.tcx.crate_name(def_id.krate), + location + )); + }; + note_def("first", original_def_id); + note_def("second", item_def_id); } err.emit(); } diff --git a/src/test/ui/duplicate_entry_error.rs b/src/test/ui/duplicate_entry_error.rs index b8d98a8999b..776ecedea7e 100644 --- a/src/test/ui/duplicate_entry_error.rs +++ b/src/test/ui/duplicate_entry_error.rs @@ -1,3 +1,4 @@ +// normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" // note-pattern: first defined in crate `std`. // Test for issue #31788 and E0152 diff --git a/src/test/ui/duplicate_entry_error.stderr b/src/test/ui/duplicate_entry_error.stderr index 2d52ea3f6c2..93e4f9fa5e9 100644 --- a/src/test/ui/duplicate_entry_error.stderr +++ b/src/test/ui/duplicate_entry_error.stderr @@ -1,5 +1,5 @@ error[E0152]: found duplicate lang item `panic_impl` - --> $DIR/duplicate_entry_error.rs:10:1 + --> $DIR/duplicate_entry_error.rs:11:1 | LL | / fn panic_impl(info: &PanicInfo) -> ! { LL | | @@ -8,6 +8,8 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) + = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: second definition in `duplicate_entry_error` loaded from the local crate error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0152.rs b/src/test/ui/error-codes/E0152.rs index 94467b9bdde..d716ca1a14f 100644 --- a/src/test/ui/error-codes/E0152.rs +++ b/src/test/ui/error-codes/E0152.rs @@ -1,3 +1,4 @@ +// normalize-stderr-test "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" #![feature(lang_items)] #[lang = "owned_box"] diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index fbaa276ce10..5520b5454f9 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -1,10 +1,12 @@ error[E0152]: found duplicate lang item `owned_box` - --> $DIR/E0152.rs:4:1 + --> $DIR/E0152.rs:5:1 | LL | struct Foo; | ^^^^^^^^^^^ | = note: the lang item is first defined in crate `alloc` (which `std` depends on) + = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib + = note: second definition in `E0152` loaded from the local crate error: aborting due to previous error diff --git a/src/test/ui/panic-handler/panic-handler-std.rs b/src/test/ui/panic-handler/panic-handler-std.rs index 0acc2722cb2..6183c886cfa 100644 --- a/src/test/ui/panic-handler/panic-handler-std.rs +++ b/src/test/ui/panic-handler/panic-handler-std.rs @@ -1,3 +1,4 @@ +// normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" // error-pattern: found duplicate lang item `panic_impl` diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr index f71c28e5aa6..1cba0ac3b9a 100644 --- a/src/test/ui/panic-handler/panic-handler-std.stderr +++ b/src/test/ui/panic-handler/panic-handler-std.stderr @@ -1,5 +1,5 @@ error[E0152]: found duplicate lang item `panic_impl` - --> $DIR/panic-handler-std.rs:7:1 + --> $DIR/panic-handler-std.rs:8:1 | LL | / fn panic(info: PanicInfo) -> ! { LL | | loop {} @@ -7,9 +7,11 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) + = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: second definition in `panic_handler_std` loaded from the local crate error: argument should be `&PanicInfo` - --> $DIR/panic-handler-std.rs:7:16 + --> $DIR/panic-handler-std.rs:8:16 | LL | fn panic(info: PanicInfo) -> ! { | ^^^^^^^^^