use syntax::ast;
use syntax::symbol::Symbol;
+use syntax_pos::Span;
use hir::itemlikevisit::ItemLikeVisitor;
use hir;
impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
- if let Some(value) = extract(&item.attrs) {
+ if let Some((value, span)) = extract(&item.attrs) {
let item_index = self.item_refs.get(&*value.as_str()).cloned();
if let Some(item_index) = item_index {
let def_id = self.tcx.hir.local_def_id(item.id);
self.collect_item(item_index, def_id);
} else {
- let span = self.tcx.hir.span(item.id);
- span_err!(self.tcx.sess, span, E0522,
- "definition of an unknown language item: `{}`.",
- value);
+ let mut err = struct_span_err!(self.tcx.sess, span, E0522,
+ "definition of an unknown language item: `{}`",
+ value);
+ err.span_label(span, format!("definition of unknown language item `{}`", value));
+ err.emit();
}
}
}
}
}
-pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
+pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
for attribute in attrs {
if attribute.check_name("lang") {
if let Some(value) = attribute.value_str() {
- return Some(value)
+ return Some((value, attribute.span));
}
}
}
}
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
- lang_items::extract(attrs).and_then(|name| {
+ lang_items::extract(attrs).and_then(|(name, _)| {
$(if name == stringify!($name) {
Some(Symbol::intern(stringify!($sym)))
} else)* {
}
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
- if let Some(lang_item) = lang_items::extract(&i.attrs) {
+ if let Some((lang_item, _)) = lang_items::extract(&i.attrs) {
self.register(&lang_item.as_str(), i.span);
}
intravisit::walk_foreign_item(self, i)
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused)]
+#![feature(lang_items)]
+
+#[lang = "foo"]
+fn bar() -> ! {
+//~^^ ERROR definition of an unknown language item: `foo`
+ loop {}
+}
+
+fn main() {}