Skip to content

Commit ac9aed5

Browse files
committed
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.
1 parent 59367b0 commit ac9aed5

File tree

8 files changed

+50
-18
lines changed

8 files changed

+50
-18
lines changed

src/librustc/middle/cstore.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,17 @@ pub struct ExternCrate {
126126
/// used to select the extern with the shortest path
127127
pub path_len: usize,
128128

129+
/// Crate that depends on this crate
130+
pub dependency_of: CrateNum,
131+
}
132+
133+
impl ExternCrate {
129134
/// If true, then this crate is the crate named by the extern
130135
/// crate referenced above. If false, then this crate is a dep
131136
/// of the crate.
132-
pub direct: bool,
137+
pub fn is_direct(&self) -> bool {
138+
self.dependency_of == LOCAL_CRATE
139+
}
133140
}
134141

135142
#[derive(Copy, Clone, Debug, HashStable)]

src/librustc/middle/lang_items.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::hir::def_id::DefId;
1313
use crate::hir::check_attr::Target;
1414
use crate::ty::{self, TyCtxt};
1515
use crate::middle::weak_lang_items;
16+
use crate::middle::cstore::ExternCrate;
1617
use crate::util::nodemap::FxHashMap;
1718

1819
use syntax::ast;
@@ -182,16 +183,39 @@ impl LanguageItemCollector<'tcx> {
182183
E0152,
183184
"duplicate lang item found: `{}`.",
184185
name),
185-
None => self.tcx.sess.struct_err(&format!(
186-
"duplicate lang item in crate `{}`: `{}`.",
187-
self.tcx.crate_name(item_def_id.krate),
188-
name)),
186+
None => {
187+
match self.tcx.extern_crate(item_def_id) {
188+
Some(ExternCrate {dependency_of, ..}) => {
189+
self.tcx.sess.struct_err(&format!(
190+
"duplicate lang item in crate `{}` (which `{}` depends on): `{}`.",
191+
self.tcx.crate_name(item_def_id.krate),
192+
self.tcx.crate_name(*dependency_of),
193+
name))
194+
},
195+
_ => {
196+
self.tcx.sess.struct_err(&format!(
197+
"duplicate lang item in crate `{}`: `{}`.",
198+
self.tcx.crate_name(item_def_id.krate),
199+
name))
200+
}
201+
}
202+
},
189203
};
190204
if let Some(span) = self.tcx.hir().span_if_local(original_def_id) {
191205
span_note!(&mut err, span, "first defined here.");
192206
} else {
193-
err.note(&format!("first defined in crate `{}`.",
207+
match self.tcx.extern_crate(original_def_id) {
208+
Some(ExternCrate {dependency_of, ..}) => {
209+
err.note(&format!(
210+
"first defined in crate `{}` (which `{}` depends on).",
211+
self.tcx.crate_name(original_def_id.krate),
212+
self.tcx.crate_name(*dependency_of)));
213+
},
214+
_ => {
215+
err.note(&format!("first defined in crate `{}`.",
194216
self.tcx.crate_name(original_def_id.krate)));
217+
}
218+
}
195219
}
196220
err.emit();
197221
}

src/librustc/ty/print/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ pub trait PrettyPrinter<'tcx>:
278278
match self.tcx().extern_crate(def_id) {
279279
Some(&ExternCrate {
280280
src: ExternCrateSource::Extern(def_id),
281-
direct: true,
281+
dependency_of: LOCAL_CRATE,
282282
span,
283283
..
284284
}) => {

src/librustc_metadata/creader.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc::middle::cstore::{ExternCrate, ExternCrateSource};
1717
use rustc::util::common::record_time;
1818
use rustc::util::nodemap::FxHashSet;
1919
use rustc::hir::map::Definitions;
20+
use rustc::hir::def_id::LOCAL_CRATE;
2021

2122
use std::ops::Deref;
2223
use std::path::PathBuf;
@@ -430,7 +431,7 @@ impl<'a> CrateLoader<'a> {
430431
mut extern_crate: ExternCrate,
431432
visited: &mut FxHashSet<(CrateNum, bool)>)
432433
{
433-
if !visited.insert((cnum, extern_crate.direct)) { return }
434+
if !visited.insert((cnum, extern_crate.is_direct())) { return }
434435

435436
let cmeta = self.cstore.get_crate_data(cnum);
436437
let mut old_extern_crate = cmeta.extern_crate.borrow_mut();
@@ -441,14 +442,14 @@ impl<'a> CrateLoader<'a> {
441442
// - shorter paths to longer (tuple.2).
442443
let new_rank = (
443444
true,
444-
extern_crate.direct,
445+
extern_crate.is_direct(),
445446
cmp::Reverse(extern_crate.path_len),
446447
);
447448
let old_rank = match *old_extern_crate {
448449
None => (false, false, cmp::Reverse(usize::max_value())),
449450
Some(ref c) => (
450451
true,
451-
c.direct,
452+
c.is_direct(),
452453
cmp::Reverse(c.path_len),
453454
),
454455
};
@@ -460,7 +461,7 @@ impl<'a> CrateLoader<'a> {
460461
drop(old_extern_crate);
461462

462463
// Propagate the extern crate info to dependencies.
463-
extern_crate.direct = false;
464+
extern_crate.dependency_of = cnum;
464465
for &dep_cnum in cmeta.dependencies.borrow().iter() {
465466
self.update_extern_crate(dep_cnum, extern_crate, visited);
466467
}
@@ -1030,7 +1031,7 @@ impl<'a> CrateLoader<'a> {
10301031
src: ExternCrateSource::Extern(def_id),
10311032
span: item.span,
10321033
path_len,
1033-
direct: true,
1034+
dependency_of: LOCAL_CRATE,
10341035
},
10351036
&mut FxHashSet::default(),
10361037
);
@@ -1057,7 +1058,7 @@ impl<'a> CrateLoader<'a> {
10571058
span,
10581059
// to have the least priority in `update_extern_crate`
10591060
path_len: usize::max_value(),
1060-
direct: true,
1061+
dependency_of: LOCAL_CRATE,
10611062
},
10621063
&mut FxHashSet::default(),
10631064
);
@@ -1081,7 +1082,7 @@ impl<'a> CrateLoader<'a> {
10811082
span,
10821083
// to have the least priority in `update_extern_crate`
10831084
path_len: usize::max_value(),
1084-
direct: true,
1085+
dependency_of: LOCAL_CRATE,
10851086
},
10861087
&mut FxHashSet::default(),
10871088
);

src/librustc_metadata/cstore_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
233233

234234
missing_extern_crate_item => {
235235
let r = match *cdata.extern_crate.borrow() {
236-
Some(extern_crate) if !extern_crate.direct => true,
236+
Some(extern_crate) if !extern_crate.is_direct() => true,
237237
_ => false,
238238
};
239239
r

src/test/ui/duplicate_entry_error.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | | loop {}
77
LL | | }
88
| |_^
99
|
10-
= note: first defined in crate `std`.
10+
= note: first defined in crate `std` (which `duplicate_entry_error` depends on).
1111

1212
error: aborting due to previous error
1313

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0152]: duplicate lang item found: `arc`.
44
LL | struct Foo;
55
| ^^^^^^^^^^^
66
|
7-
= note: first defined in crate `alloc`.
7+
= note: first defined in crate `alloc` (which `std` depends on).
88

99
error: aborting due to previous error
1010

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | | loop {}
66
LL | | }
77
| |_^
88
|
9-
= note: first defined in crate `std`.
9+
= note: first defined in crate `std` (which `panic_handler_std` depends on).
1010

1111
error: argument should be `&PanicInfo`
1212
--> $DIR/panic-handler-std.rs:7:16

0 commit comments

Comments
 (0)