diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 6cbb90627eab5..d07df103e242d 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -32,7 +32,6 @@ use util::nodemap::FnvHashMap; use syntax::ast; use syntax::attr::AttrMetaMethods; -use syntax::codemap::{DUMMY_SP, Span}; use syntax::parse::token::InternedString; use rustc_front::intravisit::Visitor; use rustc_front::hir; @@ -158,7 +157,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for LanguageItemCollector<'a, 'tcx> { let item_index = self.item_refs.get(&value[..]).cloned(); if let Some(item_index) = item_index { - self.collect_item(item_index, self.ast_map.local_def_id(item.id), item.span) + self.collect_item(item_index, self.ast_map.local_def_id(item.id)) } } } @@ -180,15 +179,26 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { } pub fn collect_item(&mut self, item_index: usize, - item_def_id: DefId, span: Span) { + item_def_id: DefId) { // Check for duplicates. match self.items.items[item_index] { Some(original_def_id) if original_def_id != item_def_id => { let cstore = &self.session.cstore; - span_err!(self.session, span, E0152, - "duplicate entry for `{}`, first definition found in `{}`", - LanguageItems::item_name(item_index), - cstore.crate_name(item_def_id.krate)); + let span = self.ast_map.span_if_local(item_def_id) + .expect("we should have found local duplicate earlier"); + let mut err = struct_span_err!(self.session, + span, + E0152, + "duplicate lang item found: `{}`.", + LanguageItems::item_name(item_index)); + if let Some(span) = self.ast_map.span_if_local(original_def_id) { + span_note!(&mut err, span, + "first defined here."); + } else { + err.note(&format!("first defined in crate `{}`.", + cstore.crate_name(original_def_id.krate))); + } + err.emit(); } _ => { // OK. @@ -205,17 +215,18 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { pub fn collect_external_language_items(&mut self) { let cstore = &self.session.cstore; + for cnum in cstore.crates() { for (index, item_index) in cstore.lang_items(cnum) { let def_id = DefId { krate: cnum, index: index }; - self.collect_item(item_index, def_id, DUMMY_SP); + self.collect_item(item_index, def_id); } } } pub fn collect(&mut self, krate: &hir::Crate) { - self.collect_local_language_items(krate); self.collect_external_language_items(); + self.collect_local_language_items(krate); } } diff --git a/src/test/compile-fail/duplicate_entry_error.rs b/src/test/compile-fail/duplicate_entry_error.rs index d39553a7267e0..ad5ea29159968 100644 --- a/src/test/compile-fail/duplicate_entry_error.rs +++ b/src/test/compile-fail/duplicate_entry_error.rs @@ -8,14 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test for issue #31788 +// note-pattern: first defined in crate `std`. -// error-pattern: duplicate entry for `panic_fmt`, first definition found in `std` +// Test for issue #31788 and E0152 #![feature(lang_items)] #[lang = "panic_fmt"] fn panic_fmt() -> ! { +//~^ ERROR: duplicate lang item found: `panic_fmt`. loop {} }