From e6af9ebea280aac2fc98e67816403ec350aba7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 23 Jan 2018 15:34:16 -0800 Subject: [PATCH] Point at unknown lang item attribute --- src/librustc/middle/lang_items.rs | 16 +++++++++------- src/librustc/middle/weak_lang_items.rs | 4 ++-- src/test/compile-fail/E0522.rs | 3 ++- src/test/ui/unknown-language-item.rs | 20 ++++++++++++++++++++ src/test/ui/unknown-language-item.stderr | 8 ++++++++ 5 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/unknown-language-item.rs create mode 100644 src/test/ui/unknown-language-item.stderr diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index dca676130b9..447ce46ee5c 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -28,6 +28,7 @@ use syntax::ast; use syntax::symbol::Symbol; +use syntax_pos::Span; use hir::itemlikevisit::ItemLikeVisitor; use hir; @@ -104,17 +105,18 @@ struct LanguageItemCollector<'a, 'tcx: 'a> { 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(); } } } @@ -177,11 +179,11 @@ fn collect_item(&mut self, item_index: usize, item_def_id: DefId) { } } -pub fn extract(attrs: &[ast::Attribute]) -> Option { +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)); } } } diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 50fb5840702..95e75b4f064 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -55,7 +55,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } pub fn link_name(attrs: &[ast::Attribute]) -> Option { - lang_items::extract(attrs).and_then(|name| { + lang_items::extract(attrs).and_then(|(name, _)| { $(if name == stringify!($name) { Some(Symbol::intern(stringify!($sym))) } else)* { @@ -129,7 +129,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { } 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) diff --git a/src/test/compile-fail/E0522.rs b/src/test/compile-fail/E0522.rs index 5103c83cafc..3d437785346 100644 --- a/src/test/compile-fail/E0522.rs +++ b/src/test/compile-fail/E0522.rs @@ -11,6 +11,7 @@ #![feature(lang_items)] #[lang = "cookie"] -fn cookie() -> ! { //~ E0522 +fn cookie() -> ! { +//~^^ ERROR definition of an unknown language item: `cookie` [E0522] loop {} } diff --git a/src/test/ui/unknown-language-item.rs b/src/test/ui/unknown-language-item.rs new file mode 100644 index 00000000000..3c210599712 --- /dev/null +++ b/src/test/ui/unknown-language-item.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , 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() {} diff --git a/src/test/ui/unknown-language-item.stderr b/src/test/ui/unknown-language-item.stderr new file mode 100644 index 00000000000..c4b4a789c3d --- /dev/null +++ b/src/test/ui/unknown-language-item.stderr @@ -0,0 +1,8 @@ +error[E0522]: definition of an unknown language item: `foo` + --> $DIR/unknown-language-item.rs:14:1 + | +14 | #[lang = "foo"] + | ^^^^^^^^^^^^^^^ definition of unknown language item `foo` + +error: aborting due to previous error + -- GitLab