mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
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.
This commit is contained in:
parent
a534216fa6
commit
2ecce7ccc5
@ -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;
|
||||
```
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
// 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;
|
||||
UnsizeTraitLangItem, "unsize", unsize_trait;
|
||||
CopyTraitLangItem, "copy", copy_trait;
|
||||
CloneTraitLangItem, "clone", clone_trait;
|
||||
SyncTraitLangItem, "sync", sync_trait;
|
||||
FreezeTraitLangItem, "freeze", freeze_trait;
|
||||
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;
|
||||
DropTraitLangItem, "drop", drop_trait, Target::Trait;
|
||||
|
||||
CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait;
|
||||
CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait, Target::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;
|
||||
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;
|
||||
UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type, Target::Struct;
|
||||
|
||||
DerefTraitLangItem, "deref", deref_trait;
|
||||
DerefMutTraitLangItem, "deref_mut", deref_mut_trait;
|
||||
DerefTraitLangItem, "deref", deref_trait, Target::Trait;
|
||||
DerefMutTraitLangItem, "deref_mut", deref_mut_trait, Target::Trait;
|
||||
|
||||
FnTraitLangItem, "fn", fn_trait;
|
||||
FnMutTraitLangItem, "fn_mut", fn_mut_trait;
|
||||
FnOnceTraitLangItem, "fn_once", fn_once_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;
|
||||
GeneratorTraitLangItem, "generator", gen_trait;
|
||||
GeneratorStateLangItem, "generator_state", gen_state, Target::Enum;
|
||||
GeneratorTraitLangItem, "generator", gen_trait, Target::Trait;
|
||||
|
||||
EqTraitLangItem, "eq", eq_trait;
|
||||
PartialOrdTraitLangItem, "partial_ord", partial_ord_trait;
|
||||
OrdTraitLangItem, "ord", ord_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<T>.
|
||||
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> {
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#![feature(lang_items)]
|
||||
|
||||
#[lang = "panic_impl"]
|
||||
#[lang = "arc"]
|
||||
struct Foo; //~ ERROR E0152
|
||||
|
||||
fn main() {
|
||||
|
@ -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
|
||||
|
||||
|
17
src/test/ui/error-codes/E0718.rs
Normal file
17
src/test/ui/error-codes/E0718.rs
Normal file
@ -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 <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.
|
||||
|
||||
#![feature(lang_items)]
|
||||
|
||||
// Arc is expected to be a struct, so this will error.
|
||||
#[lang = "arc"]
|
||||
static X: u32 = 42;
|
||||
|
||||
fn main() {}
|
9
src/test/ui/error-codes/E0718.stderr
Normal file
9
src/test/ui/error-codes/E0718.stderr
Normal file
@ -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`.
|
18
src/test/ui/panic-handler/panic-handler-wrong-location.rs
Normal file
18
src/test/ui/panic-handler/panic-handler-wrong-location.rs
Normal file
@ -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 <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.
|
||||
|
||||
// compile-flags:-C panic=abort
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[panic_handler]
|
||||
#[no_mangle]
|
||||
static X: u32 = 42;
|
@ -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`.
|
Loading…
Reference in New Issue
Block a user