about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Huss <eric@huss.org>2020-06-17 11:05:30 -0700
committerEric Huss <eric@huss.org>2020-06-30 08:35:11 -0700
commitc225e5c5cb1200f46b83752e160b489eba1cd597 (patch)
tree3b681db12226705652d3d7a3a5df251c86f6529a
parent665190b34609c5204a3bd57c571c1dff4d8bc5f2 (diff)
downloadrust-c225e5c5cb1200f46b83752e160b489eba1cd597.tar.gz
rust-c225e5c5cb1200f46b83752e160b489eba1cd597.zip
Provide more information on duplicate lang item error.
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs5
-rw-r--r--src/librustc_middle/middle/cstore.rs1
-rw-r--r--src/librustc_middle/ty/context.rs9
-rw-r--r--src/librustc_passes/lang_items.rs21
-rw-r--r--src/test/ui/duplicate_entry_error.rs1
-rw-r--r--src/test/ui/duplicate_entry_error.stderr4
-rw-r--r--src/test/ui/error-codes/E0152.rs1
-rw-r--r--src/test/ui/error-codes/E0152.stderr4
-rw-r--r--src/test/ui/panic-handler/panic-handler-std.rs1
-rw-r--r--src/test/ui/panic-handler/panic-handler-std.stderr6
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<AllocatorKind> {
         self.allocator_kind()
     }
+
+    fn crate_extern_paths(&self, cnum: CrateNum) -> Vec<PathBuf> {
+        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<AllocatorKind>;
+    fn crate_extern_paths(&self, cnum: CrateNum) -> Vec<PathBuf>;
 }
 
 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<Interned<'tcx, T>, ()>;
@@ -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<PathBuf> {
+        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) -> ! {
    |                ^^^^^^^^^