Skip to content

Commit 05881d0

Browse files
authored
Rollup merge of rust-lang#64678 - tomtau:fix/no-std-error, r=matthewjasper
added more context for duplicate lang item errors (fixes rust-lang#60561) Some more information about rust-lang#60561 -- these errors are pretty common when one works in restrictive environments with `no_std` or customized `std`, but they don't provide much context for debugging, as any transitive dependency could have brought in `std` crate. With that, currently, one needs to use something like `cargo tree` and investigate transitive dependencies one by one. It'll be more helpful to know at least the crate that uses `std` (which `cargo tree` doesn't show) to pin down this investigation when debugging. I'm not sure what the best way to get this context is inside rustc internals (I'm new to them). I found that `all_crate_nums` query returns the crates in some dependency order, so printing out the name of the preceding crate seems to do the trick. But I welcome suggestions if this can be done in a better way.
2 parents 55a3ead + ac9aed5 commit 05881d0

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)