Point at unknown lang item attribute
This commit is contained in:
parent
3a39b2aa5a
commit
e6af9ebea2
5 changed files with 41 additions and 10 deletions
|
@ -28,6 +28,7 @@ use util::nodemap::FxHashMap;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
|
use syntax_pos::Span;
|
||||||
use hir::itemlikevisit::ItemLikeVisitor;
|
use hir::itemlikevisit::ItemLikeVisitor;
|
||||||
use hir;
|
use hir;
|
||||||
|
|
||||||
|
@ -104,17 +105,18 @@ struct LanguageItemCollector<'a, 'tcx: 'a> {
|
||||||
|
|
||||||
impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
|
impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &hir::Item) {
|
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();
|
let item_index = self.item_refs.get(&*value.as_str()).cloned();
|
||||||
|
|
||||||
if let Some(item_index) = item_index {
|
if let Some(item_index) = item_index {
|
||||||
let def_id = self.tcx.hir.local_def_id(item.id);
|
let def_id = self.tcx.hir.local_def_id(item.id);
|
||||||
self.collect_item(item_index, def_id);
|
self.collect_item(item_index, def_id);
|
||||||
} else {
|
} else {
|
||||||
let span = self.tcx.hir.span(item.id);
|
let mut err = struct_span_err!(self.tcx.sess, span, E0522,
|
||||||
span_err!(self.tcx.sess, span, E0522,
|
"definition of an unknown language item: `{}`",
|
||||||
"definition of an unknown language item: `{}`.",
|
|
||||||
value);
|
value);
|
||||||
|
err.span_label(span, format!("definition of unknown language item `{}`", value));
|
||||||
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,11 +179,11 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
|
pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
|
||||||
for attribute in attrs {
|
for attribute in attrs {
|
||||||
if attribute.check_name("lang") {
|
if attribute.check_name("lang") {
|
||||||
if let Some(value) = attribute.value_str() {
|
if let Some(value) = attribute.value_str() {
|
||||||
return Some(value)
|
return Some((value, attribute.span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
|
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) {
|
$(if name == stringify!($name) {
|
||||||
Some(Symbol::intern(stringify!($sym)))
|
Some(Symbol::intern(stringify!($sym)))
|
||||||
} else)* {
|
} else)* {
|
||||||
|
@ -129,7 +129,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
|
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);
|
self.register(&lang_item.as_str(), i.span);
|
||||||
}
|
}
|
||||||
intravisit::walk_foreign_item(self, i)
|
intravisit::walk_foreign_item(self, i)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
|
|
||||||
#[lang = "cookie"]
|
#[lang = "cookie"]
|
||||||
fn cookie() -> ! { //~ E0522
|
fn cookie() -> ! {
|
||||||
|
//~^^ ERROR definition of an unknown language item: `cookie` [E0522]
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
20
src/test/ui/unknown-language-item.rs
Normal file
20
src/test/ui/unknown-language-item.rs
Normal file
|
@ -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 <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() {}
|
8
src/test/ui/unknown-language-item.stderr
Normal file
8
src/test/ui/unknown-language-item.stderr
Normal file
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue