X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=src%2Flibrustc%2Fmiddle%2Flang_items.rs;h=5d809f1407114aec0849b8554ce227cbf8df61d9;hb=532ac7d7530943571f2cb2e5c624518527c627b4;hp=6cbb90627eab5ee12dc6e153d24d292f51dffcab;hpb=7453a54e5240c53c1674e3dda6cc681179b9c8f2;p=rustc.git diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 6cbb90627e..5d809f1407 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -1,57 +1,52 @@ -// Copyright 2012 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. - // Detecting language items. // // Language items are items that represent concepts intrinsic to the language // itself. Examples are: // -// * Traits that specify "kinds"; e.g. "Sync", "Send". +// * Traits that specify "kinds"; e.g., "Sync", "Send". // -// * Traits that represent operators; e.g. "Add", "Sub", "Index". +// * Traits that represent operators; e.g., "Add", "Sub", "Index". // // * Functions called by the compiler itself. pub use self::LangItem::*; -use dep_graph::DepNode; -use front::map as hir_map; -use session::Session; -use middle::cstore::CrateStore; -use middle::def_id::DefId; -use middle::ty; -use middle::weak_lang_items; -use util::nodemap::FnvHashMap; +use crate::hir::def_id::DefId; +use crate::hir::check_attr::Target; +use crate::ty::{self, TyCtxt}; +use crate::middle::weak_lang_items; +use crate::util::nodemap::FxHashMap; use syntax::ast; -use syntax::attr::AttrMetaMethods; -use syntax::codemap::{DUMMY_SP, Span}; -use syntax::parse::token::InternedString; -use rustc_front::intravisit::Visitor; -use rustc_front::hir; +use syntax::symbol::Symbol; +use syntax_pos::Span; +use rustc_macros::HashStable; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use crate::hir; // The actual lang items defined come at the end of this file in one handy table. // So you probably just want to nip down to the end. -macro_rules! lets_do_this { +macro_rules! language_item_table { ( - $( $variant:ident, $name:expr, $method:ident; )* + $( $variant:ident, $name:expr, $method:ident, $target:path; )* ) => { - enum_from_u32! { - #[derive(Copy, Clone, PartialEq, Eq, Hash)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum LangItem { $($variant,)* } } +impl LangItem { + fn name(self) -> &'static str { + match self { + $( $variant => $name, )* + } + } +} + +#[derive(HashStable)] pub struct LanguageItems { pub items: Vec>, pub missing: Vec, @@ -62,7 +57,7 @@ impl LanguageItems { fn foo(_: LangItem) -> Option { None } LanguageItems { - items: vec!($(foo($variant)),*), + items: vec![$(foo($variant)),*], missing: Vec::new(), } } @@ -71,67 +66,17 @@ impl LanguageItems { &*self.items } - pub fn item_name(index: usize) -> &'static str { - let item: Option = LangItem::from_u32(index as u32); - match item { - $( Some($variant) => $name, )* - None => "???" - } - } - pub fn require(&self, it: LangItem) -> Result { - match self.items[it as usize] { - Some(id) => Ok(id), - None => { - Err(format!("requires `{}` lang_item", - LanguageItems::item_name(it as usize))) - } - } - } - - pub fn require_owned_box(&self) -> Result { - self.require(OwnedBoxLangItem) - } - - pub fn from_builtin_kind(&self, bound: ty::BuiltinBound) - -> Result - { - match bound { - ty::BoundSend => self.require(SendTraitLangItem), - ty::BoundSized => self.require(SizedTraitLangItem), - ty::BoundCopy => self.require(CopyTraitLangItem), - ty::BoundSync => self.require(SyncTraitLangItem), - } - } - - pub fn to_builtin_kind(&self, id: DefId) -> Option { - if Some(id) == self.send_trait() { - Some(ty::BoundSend) - } else if Some(id) == self.sized_trait() { - Some(ty::BoundSized) - } else if Some(id) == self.copy_trait() { - Some(ty::BoundCopy) - } else if Some(id) == self.sync_trait() { - Some(ty::BoundSync) - } else { - None - } + self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name())) } pub fn fn_trait_kind(&self, id: DefId) -> Option { - let def_id_kinds = [ - (self.fn_trait(), ty::FnClosureKind), - (self.fn_mut_trait(), ty::FnMutClosureKind), - (self.fn_once_trait(), ty::FnOnceClosureKind), - ]; - - for &(opt_def_id, kind) in &def_id_kinds { - if Some(id) == opt_def_id { - return Some(kind); - } + match Some(id) { + x if x == self.fn_trait() => Some(ty::ClosureKind::Fn), + x if x == self.fn_mut_trait() => Some(ty::ClosureKind::FnMut), + x if x == self.fn_once_trait() => Some(ty::ClosureKind::FnOnce), + _ => None } - - None } $( @@ -144,103 +89,133 @@ impl LanguageItems { struct LanguageItemCollector<'a, 'tcx: 'a> { items: LanguageItems, - - ast_map: &'a hir_map::Map<'tcx>, - - session: &'a Session, - - item_refs: FnvHashMap<&'static str, usize>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_refs: FxHashMap<&'static str, (usize, Target)>, } -impl<'a, 'v, 'tcx> Visitor<'v> for LanguageItemCollector<'a, 'tcx> { +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) { - let item_index = self.item_refs.get(&value[..]).cloned(); - - if let Some(item_index) = item_index { - self.collect_item(item_index, self.ast_map.local_def_id(item.id), item.span) + if let Some((value, span)) = extract(&item.attrs) { + 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_from_hir_id(item.hir_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(); + }, } } } + + fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) { + // at present, lang items are always items, not trait items + } + + fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { + // at present, lang items are always items, not impl items + } } impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { - pub fn new(session: &'a Session, ast_map: &'a hir_map::Map<'tcx>) - -> LanguageItemCollector<'a, 'tcx> { - let mut item_refs = FnvHashMap(); + fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItemCollector<'a, 'tcx> { + let mut item_refs = FxHashMap::default(); - $( item_refs.insert($name, $variant as usize); )* + $( item_refs.insert($name, ($variant as usize, $target)); )* LanguageItemCollector { - session: session, - ast_map: ast_map, + tcx, items: LanguageItems::new(), - item_refs: item_refs, + item_refs, } } - pub fn collect_item(&mut self, item_index: usize, - item_def_id: DefId, span: Span) { + fn collect_item(&mut self, item_index: usize, item_def_id: DefId) { // Check for duplicates. - match self.items.items[item_index] { - Some(original_def_id) if original_def_id != item_def_id => { - let cstore = &self.session.cstore; - span_err!(self.session, span, E0152, - "duplicate entry for `{}`, first definition found in `{}`", - LanguageItems::item_name(item_index), - cstore.crate_name(item_def_id.krate)); - } - _ => { - // OK. + if let Some(original_def_id) = self.items.items[item_index] { + if original_def_id != item_def_id { + let name = LangItem::from_u32(item_index as u32).unwrap().name(); + let mut err = match self.tcx.hir().span_if_local(item_def_id) { + Some(span) => struct_span_err!( + self.tcx.sess, + span, + E0152, + "duplicate lang item found: `{}`.", + name), + None => self.tcx.sess.struct_err(&format!( + "duplicate lang item in crate `{}`: `{}`.", + self.tcx.crate_name(item_def_id.krate), + name)), + }; + if let Some(span) = self.tcx.hir().span_if_local(original_def_id) { + span_note!(&mut err, span, "first defined here."); + } else { + err.note(&format!("first defined in crate `{}`.", + self.tcx.crate_name(original_def_id.krate))); + } + err.emit(); } } // Matched. self.items.items[item_index] = Some(item_def_id); } - - pub fn collect_local_language_items(&mut self, krate: &hir::Crate) { - krate.visit_all_items(self); - } - - pub fn collect_external_language_items(&mut self) { - let cstore = &self.session.cstore; - for cnum in cstore.crates() { - for (index, item_index) in cstore.lang_items(cnum) { - let def_id = DefId { krate: cnum, index: index }; - self.collect_item(item_index, def_id, DUMMY_SP); - } - } - } - - pub fn collect(&mut self, krate: &hir::Crate) { - self.collect_local_language_items(krate); - self.collect_external_language_items(); - } } -pub fn extract(attrs: &[ast::Attribute]) -> Option { +pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> { for attribute in attrs { - match attribute.value_str() { - Some(ref value) if attribute.check_name("lang") => { - return Some(value.clone()); + if attribute.check_name("lang") { + if let Some(value) = attribute.value_str() { + return Some((value, attribute.span)); } - _ => {} + } else if attribute.check_name("panic_handler") { + return Some((Symbol::intern("panic_impl"), attribute.span)) + } else if attribute.check_name("alloc_error_handler") { + return Some((Symbol::intern("oom"), attribute.span)) } } - return None; + None } -pub fn collect_language_items(session: &Session, - map: &hir_map::Map) - -> LanguageItems { - let _task = map.dep_graph.in_task(DepNode::CollectLanguageItems); - let krate: &hir::Crate = map.krate(); - let mut collector = LanguageItemCollector::new(session, map); - collector.collect(krate); +pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems { + let mut collector = LanguageItemCollector::new(tcx); + for &cnum in tcx.crates().iter() { + for &(def_id, item_index) in tcx.defined_lang_items(cnum).iter() { + collector.collect_item(item_index, def_id); + } + } + tcx.hir().krate().visit_all_item_likes(&mut collector); let LanguageItemCollector { mut items, .. } = collector; - weak_lang_items::check_crate(krate, session, &mut items); + weak_lang_items::check_crate(tcx, &mut items); items } @@ -248,78 +223,90 @@ pub fn collect_language_items(session: &Session, } } -lets_do_this! { -// Variant name, Name, Method name; - CharImplItem, "char", char_impl; - StrImplItem, "str", str_impl; - SliceImplItem, "slice", slice_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; - IsizeImplItem, "isize", isize_impl; - U8ImplItem, "u8", u8_impl; - U16ImplItem, "u16", u16_impl; - U32ImplItem, "u32", u32_impl; - U64ImplItem, "u64", u64_impl; - UsizeImplItem, "usize", usize_impl; - F32ImplItem, "f32", f32_impl; - F64ImplItem, "f64", f64_impl; - - SendTraitLangItem, "send", send_trait; - SizedTraitLangItem, "sized", sized_trait; - UnsizeTraitLangItem, "unsize", unsize_trait; - CopyTraitLangItem, "copy", copy_trait; - SyncTraitLangItem, "sync", sync_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; - RangeStructLangItem, "range", range_struct; - RangeFromStructLangItem, "range_from", range_from_struct; - RangeToStructLangItem, "range_to", range_to_struct; - RangeFullStructLangItem, "range_full", range_full_struct; - - 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; - - EqTraitLangItem, "eq", eq_trait; - OrdTraitLangItem, "ord", ord_trait; - - StrEqFnLangItem, "str_eq", str_eq_fn; +language_item_table! { +// 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; + DispatchFromDynTraitLangItem,"dispatch_from_dyn", dispatch_from_dyn_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; + VaListTypeLangItem, "va_list", va_list, Target::Struct; + + DerefTraitLangItem, "deref", deref_trait, Target::Trait; + DerefMutTraitLangItem, "deref_mut", deref_mut_trait, Target::Trait; + ReceiverTraitLangItem, "receiver", receiver_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; + UnpinTraitLangItem, "unpin", unpin_trait, Target::Trait; + PinTypeLangItem, "pin", pin_type, Target::Struct; + + 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 @@ -330,37 +317,74 @@ lets_do_this! { // 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; - PanicFmtLangItem, "panic_fmt", panic_fmt; - - ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn; - ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn; - BoxFreeFnLangItem, "box_free", box_free_fn; - StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn; - - StartFnLangItem, "start", start_fn; - - EhPersonalityLangItem, "eh_personality", eh_personality; - EhPersonalityCatchLangItem, "eh_personality_catch", eh_personality_catch; - EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume; - MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter; - - OwnedBoxLangItem, "owned_box", owned_box; - - PhantomDataItem, "phantom_data", phantom_data; - - // Deprecated: - CovariantTypeItem, "covariant_type", covariant_type; - ContravariantTypeItem, "contravariant_type", contravariant_type; - InvariantTypeItem, "invariant_type", invariant_type; - CovariantLifetimeItem, "covariant_lifetime", covariant_lifetime; - ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime; - InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime; - - NoCopyItem, "no_copy_bound", no_copy_bound; - - NonZeroItem, "non_zero", non_zero; + 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, Target::Fn; + + 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, Target::Fn; + + 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, Target::Struct; + + PhantomDataItem, "phantom_data", phantom_data, Target::Struct; + + ManuallyDropItem, "manually_drop", manually_drop, Target::Struct; + + 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, 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, 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, Target::Fn; + + TerminationTraitLangItem, "termination", termination, Target::Trait; + + Arc, "arc", arc, Target::Struct; + Rc, "rc", rc, Target::Struct; +} - DebugTraitLangItem, "debug_trait", debug_trait; +impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> { + pub fn require_lang_item(&self, lang_item: LangItem) -> DefId { + self.lang_items().require(lang_item).unwrap_or_else(|msg| { + self.sess.fatal(&msg) + }) + } }