From 2ecce7ccc5d74eb3d6b0ff400b2a19944e2ae51a Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 11 Oct 2018 19:36:51 +0200 Subject: [PATCH] Extend lang items to assert correct target. This commit extends the existing lang items functionality to assert that the `#[lang_item]` attribute is only found on the appropriate item for any given lang item. That is, language items representing traits must only ever have their corresponding attribute placed on a trait, for example. --- src/librustc/diagnostics.rs | 18 +- src/librustc/hir/check_attr.rs | 74 ++++- src/librustc/middle/lang_items.rs | 304 ++++++++++-------- src/test/ui/error-codes/E0152.rs | 2 +- src/test/ui/error-codes/E0152.stderr | 4 +- src/test/ui/error-codes/E0718.rs | 17 + src/test/ui/error-codes/E0718.stderr | 9 + .../panic-handler-wrong-location.rs | 18 ++ .../panic-handler-wrong-location.stderr | 11 + 9 files changed, 295 insertions(+), 162 deletions(-) create mode 100644 src/test/ui/error-codes/E0718.rs create mode 100644 src/test/ui/error-codes/E0718.stderr create mode 100644 src/test/ui/panic-handler/panic-handler-wrong-location.rs create mode 100644 src/test/ui/panic-handler/panic-handler-wrong-location.stderr diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 84afdd53cf48c..1d21a5cf79d10 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -637,8 +637,8 @@ Erroneous code example: ```compile_fail,E0152 #![feature(lang_items)] -#[lang = "panic_impl"] -struct Foo; // error: duplicate lang item found: `panic_impl` +#[lang = "arc"] +struct Foo; // error: duplicate lang item found: `arc` ``` Lang items are already implemented in the standard library. Unless you are @@ -2116,6 +2116,20 @@ struct Foo; ``` "##, +E0718: r##" +This error indicates that a `#[lang = ".."]` attribute was placed +on the wrong type of item. + +Examples of erroneous code: + +```compile_fail,E0718 +#![feature(lang_items)] + +#[lang = "arc"] +static X: u32 = 42; +``` +"##, + } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index b23a50ef1a402..020012d756a1c 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -14,40 +14,80 @@ //! conflicts between multiple such attributes attached to the same //! item. -use syntax_pos::Span; -use ty::TyCtxt; - use hir; use hir::intravisit::{self, Visitor, NestedVisitorMap}; +use ty::TyCtxt; +use std::fmt::{self, Display}; +use syntax_pos::Span; #[derive(Copy, Clone, PartialEq)] -enum Target { +pub(crate) enum Target { + ExternCrate, + Use, + Static, + Const, Fn, + Closure, + Mod, + ForeignMod, + GlobalAsm, + Ty, + Existential, + Enum, Struct, Union, - Enum, - Const, - ForeignMod, + Trait, + TraitAlias, + Impl, Expression, Statement, - Closure, - Static, - Trait, - Other, +} + +impl Display for Target { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", match *self { + Target::ExternCrate => "extern crate", + Target::Use => "use", + Target::Static => "static item", + Target::Const => "constant item", + Target::Fn => "function", + Target::Closure => "closure", + Target::Mod => "module", + Target::ForeignMod => "foreign module", + Target::GlobalAsm => "global asm", + Target::Ty => "type alias", + Target::Existential => "existential type", + Target::Enum => "enum", + Target::Struct => "struct", + Target::Union => "union", + Target::Trait => "trait", + Target::TraitAlias => "trait alias", + Target::Impl => "item", + Target::Expression => "expression", + Target::Statement => "statement", + }) + } } impl Target { - fn from_item(item: &hir::Item) -> Target { + pub(crate) fn from_item(item: &hir::Item) -> Target { match item.node { + hir::ItemKind::ExternCrate(..) => Target::ExternCrate, + hir::ItemKind::Use(..) => Target::Use, + hir::ItemKind::Static(..) => Target::Static, + hir::ItemKind::Const(..) => Target::Const, hir::ItemKind::Fn(..) => Target::Fn, + hir::ItemKind::Mod(..) => Target::Mod, + hir::ItemKind::ForeignMod(..) => Target::ForeignMod, + hir::ItemKind::GlobalAsm(..) => Target::GlobalAsm, + hir::ItemKind::Ty(..) => Target::Ty, + hir::ItemKind::Existential(..) => Target::Existential, + hir::ItemKind::Enum(..) => Target::Enum, hir::ItemKind::Struct(..) => Target::Struct, hir::ItemKind::Union(..) => Target::Union, - hir::ItemKind::Enum(..) => Target::Enum, - hir::ItemKind::Const(..) => Target::Const, - hir::ItemKind::ForeignMod(..) => Target::ForeignMod, - hir::ItemKind::Static(..) => Target::Static, hir::ItemKind::Trait(..) => Target::Trait, - _ => Target::Other, + hir::ItemKind::TraitAlias(..) => Target::TraitAlias, + hir::ItemKind::Impl(..) => Target::Impl, } } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 0bd816b3e55f0..c5d028c1735d5 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -22,6 +22,7 @@ pub use self::LangItem::*; use hir::def_id::DefId; +use hir::check_attr::Target; use ty::{self, TyCtxt}; use middle::weak_lang_items; use util::nodemap::FxHashMap; @@ -36,7 +37,7 @@ use hir; // So you probably just want to nip down to the end. macro_rules! language_item_table { ( - $( $variant:ident, $name:expr, $method:ident; )* + $( $variant:ident, $name:expr, $method:ident, $target:path; )* ) => { enum_from_u32! { @@ -96,26 +97,49 @@ impl LanguageItems { struct LanguageItemCollector<'a, 'tcx: 'a> { items: LanguageItems, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - - item_refs: FxHashMap<&'static str, usize>, + item_refs: FxHashMap<&'static str, (usize, Target)>, } impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { 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 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(); + let actual_target = Target::from_item(item); + match self.item_refs.get(&*value.as_str()).cloned() { + // Known lang item with attribute on correct target. + Some((item_index, expected_target)) if actual_target == expected_target => { + let def_id = self.tcx.hir.local_def_id(item.id); + self.collect_item(item_index, def_id); + }, + // Known lang item with attribute on incorrect target. + Some((_, expected_target)) => { + let mut err = struct_span_err!( + self.tcx.sess, span, E0718, + "`{}` language item must be applied to a {}", + value, expected_target, + ); + err.span_label( + span, + format!( + "attribute should be applied to a {}, not a {}", + expected_target, actual_target, + ), + ); + err.emit(); + }, + // Unknown lang item. + _ => { + 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(); + }, } } } @@ -133,7 +157,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItemCollector<'a, 'tcx> { let mut item_refs = FxHashMap(); - $( item_refs.insert($name, $variant as usize); )* + $( item_refs.insert($name, ($variant as usize, $target)); )* LanguageItemCollector { tcx, @@ -210,84 +234,84 @@ pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems { } language_item_table! { -// Variant name, Name, Method name; - CharImplItem, "char", char_impl; - StrImplItem, "str", str_impl; - SliceImplItem, "slice", slice_impl; - SliceU8ImplItem, "slice_u8", slice_u8_impl; - StrAllocImplItem, "str_alloc", str_alloc_impl; - SliceAllocImplItem, "slice_alloc", slice_alloc_impl; - SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl; - ConstPtrImplItem, "const_ptr", const_ptr_impl; - MutPtrImplItem, "mut_ptr", mut_ptr_impl; - I8ImplItem, "i8", i8_impl; - I16ImplItem, "i16", i16_impl; - I32ImplItem, "i32", i32_impl; - I64ImplItem, "i64", i64_impl; - I128ImplItem, "i128", i128_impl; - IsizeImplItem, "isize", isize_impl; - U8ImplItem, "u8", u8_impl; - U16ImplItem, "u16", u16_impl; - U32ImplItem, "u32", u32_impl; - U64ImplItem, "u64", u64_impl; - U128ImplItem, "u128", u128_impl; - UsizeImplItem, "usize", usize_impl; - F32ImplItem, "f32", f32_impl; - F64ImplItem, "f64", f64_impl; - F32RuntimeImplItem, "f32_runtime", f32_runtime_impl; - F64RuntimeImplItem, "f64_runtime", f64_runtime_impl; - - SizedTraitLangItem, "sized", sized_trait; - UnsizeTraitLangItem, "unsize", unsize_trait; - CopyTraitLangItem, "copy", copy_trait; - CloneTraitLangItem, "clone", clone_trait; - SyncTraitLangItem, "sync", sync_trait; - FreezeTraitLangItem, "freeze", freeze_trait; - - DropTraitLangItem, "drop", drop_trait; - - CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait; - - AddTraitLangItem, "add", add_trait; - SubTraitLangItem, "sub", sub_trait; - MulTraitLangItem, "mul", mul_trait; - DivTraitLangItem, "div", div_trait; - RemTraitLangItem, "rem", rem_trait; - NegTraitLangItem, "neg", neg_trait; - NotTraitLangItem, "not", not_trait; - BitXorTraitLangItem, "bitxor", bitxor_trait; - BitAndTraitLangItem, "bitand", bitand_trait; - BitOrTraitLangItem, "bitor", bitor_trait; - ShlTraitLangItem, "shl", shl_trait; - ShrTraitLangItem, "shr", shr_trait; - AddAssignTraitLangItem, "add_assign", add_assign_trait; - SubAssignTraitLangItem, "sub_assign", sub_assign_trait; - MulAssignTraitLangItem, "mul_assign", mul_assign_trait; - DivAssignTraitLangItem, "div_assign", div_assign_trait; - RemAssignTraitLangItem, "rem_assign", rem_assign_trait; - BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait; - BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait; - BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait; - ShlAssignTraitLangItem, "shl_assign", shl_assign_trait; - ShrAssignTraitLangItem, "shr_assign", shr_assign_trait; - IndexTraitLangItem, "index", index_trait; - IndexMutTraitLangItem, "index_mut", index_mut_trait; - - UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type; - - DerefTraitLangItem, "deref", deref_trait; - DerefMutTraitLangItem, "deref_mut", deref_mut_trait; - - FnTraitLangItem, "fn", fn_trait; - FnMutTraitLangItem, "fn_mut", fn_mut_trait; - FnOnceTraitLangItem, "fn_once", fn_once_trait; - - GeneratorStateLangItem, "generator_state", gen_state; - GeneratorTraitLangItem, "generator", gen_trait; - - EqTraitLangItem, "eq", eq_trait; - PartialOrdTraitLangItem, "partial_ord", partial_ord_trait; - OrdTraitLangItem, "ord", ord_trait; +// Variant name, Name, Method name, Target; + CharImplItem, "char", char_impl, Target::Impl; + StrImplItem, "str", str_impl, Target::Impl; + SliceImplItem, "slice", slice_impl, Target::Impl; + SliceU8ImplItem, "slice_u8", slice_u8_impl, Target::Impl; + StrAllocImplItem, "str_alloc", str_alloc_impl, Target::Impl; + SliceAllocImplItem, "slice_alloc", slice_alloc_impl, Target::Impl; + SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl, Target::Impl; + ConstPtrImplItem, "const_ptr", const_ptr_impl, Target::Impl; + MutPtrImplItem, "mut_ptr", mut_ptr_impl, Target::Impl; + I8ImplItem, "i8", i8_impl, Target::Impl; + I16ImplItem, "i16", i16_impl, Target::Impl; + I32ImplItem, "i32", i32_impl, Target::Impl; + I64ImplItem, "i64", i64_impl, Target::Impl; + I128ImplItem, "i128", i128_impl, Target::Impl; + IsizeImplItem, "isize", isize_impl, Target::Impl; + U8ImplItem, "u8", u8_impl, Target::Impl; + U16ImplItem, "u16", u16_impl, Target::Impl; + U32ImplItem, "u32", u32_impl, Target::Impl; + U64ImplItem, "u64", u64_impl, Target::Impl; + U128ImplItem, "u128", u128_impl, Target::Impl; + UsizeImplItem, "usize", usize_impl, Target::Impl; + F32ImplItem, "f32", f32_impl, Target::Impl; + F64ImplItem, "f64", f64_impl, Target::Impl; + F32RuntimeImplItem, "f32_runtime", f32_runtime_impl, Target::Impl; + F64RuntimeImplItem, "f64_runtime", f64_runtime_impl, Target::Impl; + + SizedTraitLangItem, "sized", sized_trait, Target::Trait; + UnsizeTraitLangItem, "unsize", unsize_trait, Target::Trait; + CopyTraitLangItem, "copy", copy_trait, Target::Trait; + CloneTraitLangItem, "clone", clone_trait, Target::Trait; + SyncTraitLangItem, "sync", sync_trait, Target::Trait; + FreezeTraitLangItem, "freeze", freeze_trait, Target::Trait; + + DropTraitLangItem, "drop", drop_trait, Target::Trait; + + CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait, Target::Trait; + + AddTraitLangItem, "add", add_trait, Target::Trait; + SubTraitLangItem, "sub", sub_trait, Target::Trait; + MulTraitLangItem, "mul", mul_trait, Target::Trait; + DivTraitLangItem, "div", div_trait, Target::Trait; + RemTraitLangItem, "rem", rem_trait, Target::Trait; + NegTraitLangItem, "neg", neg_trait, Target::Trait; + NotTraitLangItem, "not", not_trait, Target::Trait; + BitXorTraitLangItem, "bitxor", bitxor_trait, Target::Trait; + BitAndTraitLangItem, "bitand", bitand_trait, Target::Trait; + BitOrTraitLangItem, "bitor", bitor_trait, Target::Trait; + ShlTraitLangItem, "shl", shl_trait, Target::Trait; + ShrTraitLangItem, "shr", shr_trait, Target::Trait; + AddAssignTraitLangItem, "add_assign", add_assign_trait, Target::Trait; + SubAssignTraitLangItem, "sub_assign", sub_assign_trait, Target::Trait; + MulAssignTraitLangItem, "mul_assign", mul_assign_trait, Target::Trait; + DivAssignTraitLangItem, "div_assign", div_assign_trait, Target::Trait; + RemAssignTraitLangItem, "rem_assign", rem_assign_trait, Target::Trait; + BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait, Target::Trait; + BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait, Target::Trait; + BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait, Target::Trait; + ShlAssignTraitLangItem, "shl_assign", shl_assign_trait, Target::Trait; + ShrAssignTraitLangItem, "shr_assign", shr_assign_trait, Target::Trait; + IndexTraitLangItem, "index", index_trait, Target::Trait; + IndexMutTraitLangItem, "index_mut", index_mut_trait, Target::Trait; + + UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type, Target::Struct; + + DerefTraitLangItem, "deref", deref_trait, Target::Trait; + DerefMutTraitLangItem, "deref_mut", deref_mut_trait, Target::Trait; + + FnTraitLangItem, "fn", fn_trait, Target::Trait; + FnMutTraitLangItem, "fn_mut", fn_mut_trait, Target::Trait; + FnOnceTraitLangItem, "fn_once", fn_once_trait, Target::Trait; + + GeneratorStateLangItem, "generator_state", gen_state, Target::Enum; + GeneratorTraitLangItem, "generator", gen_trait, Target::Trait; + + EqTraitLangItem, "eq", eq_trait, Target::Trait; + PartialOrdTraitLangItem, "partial_ord", partial_ord_trait, Target::Trait; + OrdTraitLangItem, "ord", ord_trait, Target::Trait; // A number of panic-related lang items. The `panic` item corresponds to // divide-by-zero and various panic cases with `match`. The @@ -298,68 +322,68 @@ language_item_table! { // defined to use it, but a final product is required to define it // somewhere. Additionally, there are restrictions on crates that use a weak // lang item, but do not have it defined. - PanicFnLangItem, "panic", panic_fn; - PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn; - PanicInfoLangItem, "panic_info", panic_info; - PanicImplLangItem, "panic_impl", panic_impl; + PanicFnLangItem, "panic", panic_fn, Target::Fn; + PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn, Target::Fn; + PanicInfoLangItem, "panic_info", panic_info, Target::Struct; + PanicImplLangItem, "panic_impl", panic_impl, Target::Fn; // Libstd panic entry point. Necessary for const eval to be able to catch it - BeginPanicFnLangItem, "begin_panic", begin_panic_fn; + BeginPanicFnLangItem, "begin_panic", begin_panic_fn, Target::Fn; - ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn; - BoxFreeFnLangItem, "box_free", box_free_fn; - DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn; - OomLangItem, "oom", oom; - AllocLayoutLangItem, "alloc_layout", alloc_layout; + ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn, Target::Fn; + BoxFreeFnLangItem, "box_free", box_free_fn, Target::Fn; + DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn, Target::Fn; + OomLangItem, "oom", oom, Target::Fn; + AllocLayoutLangItem, "alloc_layout", alloc_layout, Target::Struct; - StartFnLangItem, "start", start_fn; + StartFnLangItem, "start", start_fn, Target::Fn; - EhPersonalityLangItem, "eh_personality", eh_personality; - EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume; - MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter; + EhPersonalityLangItem, "eh_personality", eh_personality, Target::Fn; + EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Fn; + MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter, Target::Static; - OwnedBoxLangItem, "owned_box", owned_box; + OwnedBoxLangItem, "owned_box", owned_box, Target::Struct; - PhantomDataItem, "phantom_data", phantom_data; + PhantomDataItem, "phantom_data", phantom_data, Target::Struct; - ManuallyDropItem, "manually_drop", manually_drop; + ManuallyDropItem, "manually_drop", manually_drop, Target::Struct; - DebugTraitLangItem, "debug_trait", debug_trait; + DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait; // A lang item for each of the 128-bit operators we can optionally lower. - I128AddFnLangItem, "i128_add", i128_add_fn; - U128AddFnLangItem, "u128_add", u128_add_fn; - I128SubFnLangItem, "i128_sub", i128_sub_fn; - U128SubFnLangItem, "u128_sub", u128_sub_fn; - I128MulFnLangItem, "i128_mul", i128_mul_fn; - U128MulFnLangItem, "u128_mul", u128_mul_fn; - I128DivFnLangItem, "i128_div", i128_div_fn; - U128DivFnLangItem, "u128_div", u128_div_fn; - I128RemFnLangItem, "i128_rem", i128_rem_fn; - U128RemFnLangItem, "u128_rem", u128_rem_fn; - I128ShlFnLangItem, "i128_shl", i128_shl_fn; - U128ShlFnLangItem, "u128_shl", u128_shl_fn; - I128ShrFnLangItem, "i128_shr", i128_shr_fn; - U128ShrFnLangItem, "u128_shr", u128_shr_fn; + I128AddFnLangItem, "i128_add", i128_add_fn, Target::Fn; + U128AddFnLangItem, "u128_add", u128_add_fn, Target::Fn; + I128SubFnLangItem, "i128_sub", i128_sub_fn, Target::Fn; + U128SubFnLangItem, "u128_sub", u128_sub_fn, Target::Fn; + I128MulFnLangItem, "i128_mul", i128_mul_fn, Target::Fn; + U128MulFnLangItem, "u128_mul", u128_mul_fn, Target::Fn; + I128DivFnLangItem, "i128_div", i128_div_fn, Target::Fn; + U128DivFnLangItem, "u128_div", u128_div_fn, Target::Fn; + I128RemFnLangItem, "i128_rem", i128_rem_fn, Target::Fn; + U128RemFnLangItem, "u128_rem", u128_rem_fn, Target::Fn; + I128ShlFnLangItem, "i128_shl", i128_shl_fn, Target::Fn; + U128ShlFnLangItem, "u128_shl", u128_shl_fn, Target::Fn; + I128ShrFnLangItem, "i128_shr", i128_shr_fn, Target::Fn; + U128ShrFnLangItem, "u128_shr", u128_shr_fn, Target::Fn; // And overflow versions for the operators that are checkable. // While MIR calls these Checked*, they return (T,bool), not Option. - I128AddoFnLangItem, "i128_addo", i128_addo_fn; - U128AddoFnLangItem, "u128_addo", u128_addo_fn; - I128SuboFnLangItem, "i128_subo", i128_subo_fn; - U128SuboFnLangItem, "u128_subo", u128_subo_fn; - I128MuloFnLangItem, "i128_mulo", i128_mulo_fn; - U128MuloFnLangItem, "u128_mulo", u128_mulo_fn; - I128ShloFnLangItem, "i128_shlo", i128_shlo_fn; - U128ShloFnLangItem, "u128_shlo", u128_shlo_fn; - I128ShroFnLangItem, "i128_shro", i128_shro_fn; - U128ShroFnLangItem, "u128_shro", u128_shro_fn; + I128AddoFnLangItem, "i128_addo", i128_addo_fn, Target::Fn; + U128AddoFnLangItem, "u128_addo", u128_addo_fn, Target::Fn; + I128SuboFnLangItem, "i128_subo", i128_subo_fn, Target::Fn; + U128SuboFnLangItem, "u128_subo", u128_subo_fn, Target::Fn; + I128MuloFnLangItem, "i128_mulo", i128_mulo_fn, Target::Fn; + U128MuloFnLangItem, "u128_mulo", u128_mulo_fn, Target::Fn; + I128ShloFnLangItem, "i128_shlo", i128_shlo_fn, Target::Fn; + U128ShloFnLangItem, "u128_shlo", u128_shlo_fn, Target::Fn; + I128ShroFnLangItem, "i128_shro", i128_shro_fn, Target::Fn; + U128ShroFnLangItem, "u128_shro", u128_shro_fn, Target::Fn; // Align offset for stride != 1, must not panic. - AlignOffsetLangItem, "align_offset", align_offset_fn; + AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; - TerminationTraitLangItem, "termination", termination; + TerminationTraitLangItem, "termination", termination, Target::Trait; - Arc, "arc", arc; - Rc, "rc", rc; + Arc, "arc", arc, Target::Struct; + Rc, "rc", rc, Target::Struct; } impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> { diff --git a/src/test/ui/error-codes/E0152.rs b/src/test/ui/error-codes/E0152.rs index 8fbad7b3ff301..96a4d51bd2437 100644 --- a/src/test/ui/error-codes/E0152.rs +++ b/src/test/ui/error-codes/E0152.rs @@ -10,7 +10,7 @@ #![feature(lang_items)] -#[lang = "panic_impl"] +#[lang = "arc"] struct Foo; //~ ERROR E0152 fn main() { diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index c7f5f362efb28..a0530f24de679 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -1,10 +1,10 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: duplicate lang item found: `arc`. --> $DIR/E0152.rs:14:1 | LL | struct Foo; //~ ERROR E0152 | ^^^^^^^^^^^ | - = note: first defined in crate `std`. + = note: first defined in crate `alloc`. error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0718.rs b/src/test/ui/error-codes/E0718.rs new file mode 100644 index 0000000000000..ce74e35ac6bb6 --- /dev/null +++ b/src/test/ui/error-codes/E0718.rs @@ -0,0 +1,17 @@ +// Copyright 2013 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. + +#![feature(lang_items)] + +// Arc is expected to be a struct, so this will error. +#[lang = "arc"] +static X: u32 = 42; + +fn main() {} diff --git a/src/test/ui/error-codes/E0718.stderr b/src/test/ui/error-codes/E0718.stderr new file mode 100644 index 0000000000000..8ce721d30a16b --- /dev/null +++ b/src/test/ui/error-codes/E0718.stderr @@ -0,0 +1,9 @@ +error[E0718]: `arc` language item must be applied to a struct + --> $DIR/E0718.rs:14:1 + | +LL | #[lang = "arc"] + | ^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static item + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0718`. diff --git a/src/test/ui/panic-handler/panic-handler-wrong-location.rs b/src/test/ui/panic-handler/panic-handler-wrong-location.rs new file mode 100644 index 0000000000000..04e02682bc12b --- /dev/null +++ b/src/test/ui/panic-handler/panic-handler-wrong-location.rs @@ -0,0 +1,18 @@ +// 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. + +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +#[panic_handler] +#[no_mangle] +static X: u32 = 42; diff --git a/src/test/ui/panic-handler/panic-handler-wrong-location.stderr b/src/test/ui/panic-handler/panic-handler-wrong-location.stderr new file mode 100644 index 0000000000000..f761e26b86e71 --- /dev/null +++ b/src/test/ui/panic-handler/panic-handler-wrong-location.stderr @@ -0,0 +1,11 @@ +error[E0718]: `panic_impl` language item must be applied to a function + --> $DIR/panic-handler-wrong-location.rs:16:1 + | +LL | #[panic_handler] + | ^^^^^^^^^^^^^^^^ attribute should be applied to a function, not a static item + +error: `#[panic_handler]` function required, but not found + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0718`.