about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomas Tauber <2410580+tomtau@users.noreply.github.com>2019-09-27 21:32:04 +0800
committerTomas Tauber <2410580+tomtau@users.noreply.github.com>2019-09-27 22:56:23 +0800
commitac9aed56e4dc62c4959ae0c14cec585994302c93 (patch)
tree662e775cef1564ba959e05a578cd5ca197c0d51f
parent59367b074f1523353dddefa678ffe3cac9fd4e50 (diff)
downloadrust-ac9aed56e4dc62c4959ae0c14cec585994302c93.tar.gz
rust-ac9aed56e4dc62c4959ae0c14cec585994302c93.zip
getting more context for duplicate lang items (fixes #60561)
Where possible, the error message includes the name of the crate
that brought in the crate with duplicate lang items (which
helps with debugging). This information is passed on from cstore
using the `extern_crate` query.
-rw-r--r--src/librustc/middle/cstore.rs9
-rw-r--r--src/librustc/middle/lang_items.rs34
-rw-r--r--src/librustc/ty/print/pretty.rs2
-rw-r--r--src/librustc_metadata/creader.rs15
-rw-r--r--src/librustc_metadata/cstore_impl.rs2
-rw-r--r--src/test/ui/duplicate_entry_error.stderr2
-rw-r--r--src/test/ui/error-codes/E0152.stderr2
-rw-r--r--src/test/ui/panic-handler/panic-handler-std.stderr2
8 files changed, 50 insertions, 18 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index de84fcd7160..ddf6262b738 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -126,10 +126,17 @@ pub struct ExternCrate {
     /// used to select the extern with the shortest path
     pub path_len: usize,
 
+    /// Crate that depends on this crate
+    pub dependency_of: CrateNum,
+}
+
+impl ExternCrate {
     /// If true, then this crate is the crate named by the extern
     /// crate referenced above. If false, then this crate is a dep
     /// of the crate.
-    pub direct: bool,
+    pub fn is_direct(&self) -> bool {
+        self.dependency_of == LOCAL_CRATE
+    }
 }
 
 #[derive(Copy, Clone, Debug, HashStable)]
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index c5d9a722ae1..cab929389d6 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -13,6 +13,7 @@ use crate::hir::def_id::DefId;
 use crate::hir::check_attr::Target;
 use crate::ty::{self, TyCtxt};
 use crate::middle::weak_lang_items;
+use crate::middle::cstore::ExternCrate;
 use crate::util::nodemap::FxHashMap;
 
 use syntax::ast;
@@ -182,16 +183,39 @@ impl LanguageItemCollector<'tcx> {
                         E0152,
                         "duplicate lang item found: `{}`.",
                         name),
-                    None => self.tcx.sess.struct_err(&format!(
-                            "duplicate lang item in crate `{}`: `{}`.",
-                            self.tcx.crate_name(item_def_id.krate),
-                            name)),
+                    None => {
+                        match self.tcx.extern_crate(item_def_id) {
+                            Some(ExternCrate {dependency_of, ..}) => {
+                                self.tcx.sess.struct_err(&format!(
+                                "duplicate lang item in crate `{}` (which `{}` depends on): `{}`.",
+                                self.tcx.crate_name(item_def_id.krate),
+                                self.tcx.crate_name(*dependency_of),
+                                name))
+                            },
+                            _ => {
+                                self.tcx.sess.struct_err(&format!(
+                                "duplicate lang item in crate `{}`: `{}`.",
+                                self.tcx.crate_name(item_def_id.krate),
+                                name))
+                            }
+                        }
+                    },
                 };
                 if let Some(span) = self.tcx.hir().span_if_local(original_def_id) {
                     span_note!(&mut err, span, "first defined here.");
                 } else {
-                    err.note(&format!("first defined in crate `{}`.",
+                    match self.tcx.extern_crate(original_def_id) {
+                        Some(ExternCrate {dependency_of, ..}) => {
+                            err.note(&format!(
+                            "first defined in crate `{}` (which `{}` depends on).",
+                                      self.tcx.crate_name(original_def_id.krate),
+                                      self.tcx.crate_name(*dependency_of)));
+                        },
+                        _ => {
+                            err.note(&format!("first defined in crate `{}`.",
                                       self.tcx.crate_name(original_def_id.krate)));
+                        }
+                    }
                 }
                 err.emit();
             }
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 2bc87d6b8ba..fe0d0fad3a5 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -278,7 +278,7 @@ pub trait PrettyPrinter<'tcx>:
             match self.tcx().extern_crate(def_id) {
                 Some(&ExternCrate {
                     src: ExternCrateSource::Extern(def_id),
-                    direct: true,
+                    dependency_of: LOCAL_CRATE,
                     span,
                     ..
                 }) => {
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index af41b6a4c85..91b9f38ebce 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -17,6 +17,7 @@ use rustc::middle::cstore::{ExternCrate, ExternCrateSource};
 use rustc::util::common::record_time;
 use rustc::util::nodemap::FxHashSet;
 use rustc::hir::map::Definitions;
+use rustc::hir::def_id::LOCAL_CRATE;
 
 use std::ops::Deref;
 use std::path::PathBuf;
@@ -430,7 +431,7 @@ impl<'a> CrateLoader<'a> {
                            mut extern_crate: ExternCrate,
                            visited: &mut FxHashSet<(CrateNum, bool)>)
     {
-        if !visited.insert((cnum, extern_crate.direct)) { return }
+        if !visited.insert((cnum, extern_crate.is_direct())) { return }
 
         let cmeta = self.cstore.get_crate_data(cnum);
         let mut old_extern_crate = cmeta.extern_crate.borrow_mut();
@@ -441,14 +442,14 @@ impl<'a> CrateLoader<'a> {
         // - shorter paths to longer (tuple.2).
         let new_rank = (
             true,
-            extern_crate.direct,
+            extern_crate.is_direct(),
             cmp::Reverse(extern_crate.path_len),
         );
         let old_rank = match *old_extern_crate {
             None => (false, false, cmp::Reverse(usize::max_value())),
             Some(ref c) => (
                 true,
-                c.direct,
+                c.is_direct(),
                 cmp::Reverse(c.path_len),
             ),
         };
@@ -460,7 +461,7 @@ impl<'a> CrateLoader<'a> {
         drop(old_extern_crate);
 
         // Propagate the extern crate info to dependencies.
-        extern_crate.direct = false;
+        extern_crate.dependency_of = cnum;
         for &dep_cnum in cmeta.dependencies.borrow().iter() {
             self.update_extern_crate(dep_cnum, extern_crate, visited);
         }
@@ -1030,7 +1031,7 @@ impl<'a> CrateLoader<'a> {
                         src: ExternCrateSource::Extern(def_id),
                         span: item.span,
                         path_len,
-                        direct: true,
+                        dependency_of: LOCAL_CRATE,
                     },
                     &mut FxHashSet::default(),
                 );
@@ -1057,7 +1058,7 @@ impl<'a> CrateLoader<'a> {
                 span,
                 // to have the least priority in `update_extern_crate`
                 path_len: usize::max_value(),
-                direct: true,
+                dependency_of: LOCAL_CRATE,
             },
             &mut FxHashSet::default(),
         );
@@ -1081,7 +1082,7 @@ impl<'a> CrateLoader<'a> {
                 span,
                 // to have the least priority in `update_extern_crate`
                 path_len: usize::max_value(),
-                direct: true,
+                dependency_of: LOCAL_CRATE,
             },
             &mut FxHashSet::default(),
         );
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 11121ee875d..0cca4dfa4c5 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -233,7 +233,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
     missing_extern_crate_item => {
         let r = match *cdata.extern_crate.borrow() {
-            Some(extern_crate) if !extern_crate.direct => true,
+            Some(extern_crate) if !extern_crate.is_direct() => true,
             _ => false,
         };
         r
diff --git a/src/test/ui/duplicate_entry_error.stderr b/src/test/ui/duplicate_entry_error.stderr
index 1892ad38a59..02be11d1fd0 100644
--- a/src/test/ui/duplicate_entry_error.stderr
+++ b/src/test/ui/duplicate_entry_error.stderr
@@ -7,7 +7,7 @@ LL | |     loop {}
 LL | | }
    | |_^
    |
-   = note: first defined in crate `std`.
+   = note: first defined in crate `std` (which `duplicate_entry_error` depends on).
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr
index 26e6e2e1bce..d4b59a1148e 100644
--- a/src/test/ui/error-codes/E0152.stderr
+++ b/src/test/ui/error-codes/E0152.stderr
@@ -4,7 +4,7 @@ error[E0152]: duplicate lang item found: `arc`.
 LL | struct Foo;
    | ^^^^^^^^^^^
    |
-   = note: first defined in crate `alloc`.
+   = note: first defined in crate `alloc` (which `std` depends on).
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr
index 32240311116..e6d24348ca8 100644
--- a/src/test/ui/panic-handler/panic-handler-std.stderr
+++ b/src/test/ui/panic-handler/panic-handler-std.stderr
@@ -6,7 +6,7 @@ LL | |     loop {}
 LL | | }
    | |_^
    |
-   = note: first defined in crate `std`.
+   = note: first defined in crate `std` (which `panic_handler_std` depends on).
 
 error: argument should be `&PanicInfo`
   --> $DIR/panic-handler-std.rs:7:16