diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index aa1a8726f9d..3d003b96583 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -560,6 +560,7 @@ define_dep_nodes!( <'tcx> [] CrateName(CrateNum), [] ItemChildren(DefId), [] ExternModStmtCnum(HirId), + [] GetLangItems, ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index b8624722692..d79e90690ca 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -469,7 +469,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool { let field_type = self.tcx.type_of(self.tcx.hir.local_def_id(field.id)); let is_marker_field = match field_type.ty_to_def_id() { - Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)), + Some(def_id) => self.tcx.lang_items().items().iter().any(|item| *item == Some(def_id)), _ => false }; !field.is_positional() diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 374b02125a1..73f78477b0a 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -211,9 +211,9 @@ enum OverloadedCallType { impl OverloadedCallType { fn from_trait_id(tcx: TyCtxt, trait_id: DefId) -> OverloadedCallType { for &(maybe_function_trait, overloaded_call_type) in &[ - (tcx.lang_items.fn_once_trait(), FnOnceOverloadedCall), - (tcx.lang_items.fn_mut_trait(), FnMutOverloadedCall), - (tcx.lang_items.fn_trait(), FnOverloadedCall) + (tcx.lang_items().fn_once_trait(), FnOnceOverloadedCall), + (tcx.lang_items().fn_mut_trait(), FnMutOverloadedCall), + (tcx.lang_items().fn_trait(), FnOverloadedCall) ] { match maybe_function_trait { Some(function_trait) if function_trait == trait_id => { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 351daa198e8..d08d7eb48b6 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -21,10 +21,8 @@ pub use self::LangItem::*; -use hir::map as hir_map; -use session::Session; use hir::def_id::DefId; -use ty; +use ty::{self, TyCtxt}; use middle::weak_lang_items; use util::nodemap::FxHashMap; @@ -116,9 +114,7 @@ impl LanguageItems { struct LanguageItemCollector<'a, 'tcx: 'a> { items: LanguageItems, - hir_map: &'a hir_map::Map<'tcx>, - - session: &'a Session, + tcx: TyCtxt<'a, 'tcx, 'tcx>, item_refs: FxHashMap<&'static str, usize>, } @@ -129,10 +125,11 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { let item_index = self.item_refs.get(&*value.as_str()).cloned(); if let Some(item_index) = item_index { - self.collect_item(item_index, self.hir_map.local_def_id(item.id)) + let def_id = self.tcx.hir.local_def_id(item.id); + self.collect_item(item_index, def_id); } else { - let span = self.hir_map.span(item.id); - span_err!(self.session, span, E0522, + let span = self.tcx.hir.span(item.id); + span_err!(self.tcx.sess, span, E0522, "definition of an unknown language item: `{}`.", value); } @@ -149,45 +146,41 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { } impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { - pub fn new(session: &'a Session, hir_map: &'a hir_map::Map<'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); )* LanguageItemCollector { - session, - hir_map, + tcx, items: LanguageItems::new(), item_refs, } } - pub fn collect_item(&mut self, item_index: usize, - item_def_id: DefId) { + 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; let name = LanguageItems::item_name(item_index); - let mut err = match self.hir_map.span_if_local(item_def_id) { + let mut err = match self.tcx.hir.span_if_local(item_def_id) { Some(span) => struct_span_err!( - self.session, + self.tcx.sess, span, E0152, "duplicate lang item found: `{}`.", name), - None => self.session.struct_err(&format!( + None => self.tcx.sess.struct_err(&format!( "duplicate lang item in crate `{}`: `{}`.", - cstore.crate_name_untracked(item_def_id.krate), + self.tcx.crate_name(item_def_id.krate), name)), }; - if let Some(span) = self.hir_map.span_if_local(original_def_id) { + 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 `{}`.", - cstore.crate_name_untracked(original_def_id.krate))); + self.tcx.crate_name(original_def_id.krate))); } err.emit(); } @@ -199,26 +192,6 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { // Matched. self.items.items[item_index] = Some(item_def_id); } - - pub fn collect_local_language_items(&mut self, krate: &hir::Crate) { - krate.visit_all_item_likes(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); - } - } - } - - pub fn collect(&mut self, krate: &hir::Crate) { - self.collect_external_language_items(); - self.collect_local_language_items(krate); - } } pub fn extract(attrs: &[ast::Attribute]) -> Option { @@ -233,14 +206,17 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option { return None; } -pub fn collect_language_items(session: &Session, - map: &hir_map::Map) - -> LanguageItems { - 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.sess.cstore.crates() { + for (index, item_index) in tcx.sess.cstore.lang_items(cnum) { + let def_id = DefId { krate: cnum, index: index }; + 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 } @@ -366,7 +342,7 @@ language_item_table! { impl<'a, 'tcx, 'gcx> ty::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.lang_items().require(lang_item).unwrap_or_else(|msg| { self.sess.fatal(&msg) }) } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 3efc696f2a5..33f4d4093fe 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -392,7 +392,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> for (id, _) in &access_levels.map { reachable_context.worklist.push(*id); } - for item in tcx.lang_items.items().iter() { + for item in tcx.lang_items().items().iter() { if let Some(did) = *item { if let Some(node_id) = tcx.hir.as_local_node_id(did) { reachable_context.worklist.push(node_id); diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index acb506878e6..31114f8e302 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -11,7 +11,6 @@ //! Validity checking for weak lang items use session::config; -use session::Session; use middle::lang_items; use rustc_back::PanicStrategy; @@ -21,38 +20,38 @@ use syntax_pos::Span; use hir::intravisit::{Visitor, NestedVisitorMap}; use hir::intravisit; use hir; +use ty::TyCtxt; use std::collections::HashSet; macro_rules! weak_lang_items { ($($name:ident, $item:ident, $sym:ident;)*) => ( -struct Context<'a> { - sess: &'a Session, +struct Context<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, items: &'a mut lang_items::LanguageItems, } /// Checks the crate for usage of weak lang items, returning a vector of all the /// language items required by this crate, but not defined yet. -pub fn check_crate(krate: &hir::Crate, - sess: &Session, - items: &mut lang_items::LanguageItems) { +pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + items: &mut lang_items::LanguageItems) { // These are never called by user code, they're generated by the compiler. // They will never implicitly be added to the `missing` array unless we do // so here. if items.eh_personality().is_none() { items.missing.push(lang_items::EhPersonalityLangItem); } - if sess.target.target.options.custom_unwind_resume & + if tcx.sess.target.target.options.custom_unwind_resume & items.eh_unwind_resume().is_none() { items.missing.push(lang_items::EhUnwindResumeLangItem); } { - let mut cx = Context { sess: sess, items: items }; - krate.visit_all_item_likes(&mut cx.as_deep_visitor()); + let mut cx = Context { tcx, items }; + tcx.hir.krate().visit_all_item_likes(&mut cx.as_deep_visitor()); } - verify(sess, items); + verify(tcx, items); } pub fn link_name(attrs: &[ast::Attribute]) -> Option { @@ -65,10 +64,11 @@ pub fn link_name(attrs: &[ast::Attribute]) -> Option { }) } -fn verify(sess: &Session, items: &lang_items::LanguageItems) { +fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + items: &lang_items::LanguageItems) { // We only need to check for the presence of weak lang items if we're // emitting something that's not an rlib. - let needs_check = sess.crate_types.borrow().iter().any(|kind| { + let needs_check = tcx.sess.crate_types.borrow().iter().any(|kind| { match *kind { config::CrateTypeDylib | config::CrateTypeProcMacro | @@ -83,8 +83,8 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) { } let mut missing = HashSet::new(); - for cnum in sess.cstore.crates() { - for item in sess.cstore.missing_lang_items(cnum) { + for cnum in tcx.sess.cstore.crates() { + for item in tcx.sess.cstore.missing_lang_items(cnum) { missing.insert(item); } } @@ -93,7 +93,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) { // symbols. Other panic runtimes ensure that the relevant symbols are // available to link things together, but they're never exercised. let mut whitelisted = HashSet::new(); - if sess.panic_strategy() != PanicStrategy::Unwind { + if tcx.sess.panic_strategy() != PanicStrategy::Unwind { whitelisted.insert(lang_items::EhPersonalityLangItem); whitelisted.insert(lang_items::EhUnwindResumeLangItem); } @@ -102,28 +102,28 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) { if missing.contains(&lang_items::$item) && !whitelisted.contains(&lang_items::$item) && items.$name().is_none() { - sess.err(&format!("language item required, but not found: `{}`", - stringify!($name))); + tcx.sess.err(&format!("language item required, but not found: `{}`", + stringify!($name))); } )* } -impl<'a> Context<'a> { +impl<'a, 'tcx> Context<'a, 'tcx> { fn register(&mut self, name: &str, span: Span) { $(if name == stringify!($name) { if self.items.$name().is_none() { self.items.missing.push(lang_items::$item); } } else)* { - span_err!(self.sess, span, E0264, + span_err!(self.tcx.sess, span, E0264, "unknown external lang item: `{}`", name); } } } -impl<'a, 'v> Visitor<'v> for Context<'a> { +impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { NestedVisitorMap::None } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index ce6da55fec3..498dc0cf255 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -919,7 +919,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // anyway. In that case, why inundate the user. if !self.tcx.sess.has_errors() { if - self.tcx.lang_items.sized_trait() + self.tcx.lang_items().sized_trait() .map_or(false, |sized_id| sized_id == trait_ref.def_id()) { self.need_type_info(body_id, span, self_ty); diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 9c04c013c4b..fd6d5a86a7f 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -181,7 +181,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } fn generics_require_sized_self(self, def_id: DefId) -> bool { - let sized_def_id = match self.lang_items.sized_trait() { + let sized_def_id = match self.lang_items().sized_trait() { Some(def_id) => def_id, None => { return false; /* No Sized trait, can't require it! */ } }; diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 512cfee12b0..1088ada667f 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1155,7 +1155,7 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>( let tcx = selcx.tcx(); - let gen_def_id = tcx.lang_items.gen_trait().unwrap(); + let gen_def_id = tcx.lang_items().gen_trait().unwrap(); // Note: we unwrap the binder here but re-create it below (1) let ty::Binder((trait_ref, yield_ty, return_ty)) = @@ -1252,7 +1252,7 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>( fn_sig); // the `Output` associated type is declared on `FnOnce` - let fn_once_def_id = tcx.lang_items.fn_once_trait().unwrap(); + let fn_once_def_id = tcx.lang_items().fn_once_trait().unwrap(); // Note: we unwrap the binder here but re-create it below (1) let ty::Binder((trait_ref, ret_type)) = diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 726e5d83428..201395e6f90 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1235,7 +1235,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // and applicable impls. There is a certain set of precedence rules here. let def_id = obligation.predicate.def_id(); - if self.tcx().lang_items.copy_trait() == Some(def_id) { + let lang_items = self.tcx().lang_items(); + if lang_items.copy_trait() == Some(def_id) { debug!("obligation self ty is {:?}", obligation.predicate.0.self_ty()); @@ -1246,16 +1247,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // For other types, we'll use the builtin rules. let copy_conditions = self.copy_conditions(obligation); self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates)?; - } else if self.tcx().lang_items.sized_trait() == Some(def_id) { + } else if lang_items.sized_trait() == Some(def_id) { // Sized is never implementable by end-users, it is // always automatically computed. let sized_conditions = self.sized_conditions(obligation); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates)?; - } else if self.tcx().lang_items.unsize_trait() == Some(def_id) { + } else if lang_items.unsize_trait() == Some(def_id) { self.assemble_candidates_for_unsizing(obligation, &mut candidates); } else { - if self.tcx().lang_items.clone_trait() == Some(def_id) { + if lang_items.clone_trait() == Some(def_id) { // Same builtin conditions as `Copy`, i.e. every type which has builtin support // for `Copy` also has builtin support for `Clone`, + tuples and arrays of `Clone` // types have builtin support for `Clone`. @@ -1453,7 +1454,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { candidates: &mut SelectionCandidateSet<'tcx>) -> Result<(),SelectionError<'tcx>> { - if self.tcx().lang_items.gen_trait() != Some(obligation.predicate.def_id()) { + if self.tcx().lang_items().gen_trait() != Some(obligation.predicate.def_id()) { return Ok(()); } @@ -1490,7 +1491,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { candidates: &mut SelectionCandidateSet<'tcx>) -> Result<(),SelectionError<'tcx>> { - let kind = match self.tcx().lang_items.fn_trait_kind(obligation.predicate.0.def_id()) { + let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.0.def_id()) { Some(k) => k, None => { return Ok(()); } }; @@ -1532,7 +1533,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { -> Result<(),SelectionError<'tcx>> { // We provide impl of all fn traits for fn pointers. - if self.tcx().lang_items.fn_trait_kind(obligation.predicate.def_id()).is_none() { + if self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()).is_none() { return Ok(()); } @@ -2266,16 +2267,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { debug!("confirm_builtin_candidate({:?}, {:?})", obligation, has_nested); + let lang_items = self.tcx().lang_items(); let obligations = if has_nested { let trait_def = obligation.predicate.def_id(); let conditions = match trait_def { - _ if Some(trait_def) == self.tcx().lang_items.sized_trait() => { + _ if Some(trait_def) == lang_items.sized_trait() => { self.sized_conditions(obligation) } - _ if Some(trait_def) == self.tcx().lang_items.copy_trait() => { + _ if Some(trait_def) == lang_items.copy_trait() => { self.copy_conditions(obligation) } - _ if Some(trait_def) == self.tcx().lang_items.clone_trait() => { + _ if Some(trait_def) == lang_items.clone_trait() => { self.copy_conditions(obligation) } _ => bug!("unexpected builtin trait {:?}", trait_def) @@ -2578,7 +2580,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { { debug!("confirm_closure_candidate({:?})", obligation); - let kind = match self.tcx().lang_items.fn_trait_kind(obligation.predicate.0.def_id()) { + let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.0.def_id()) { Some(k) => k, None => bug!("closure candidate for non-fn trait {:?}", obligation) }; diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 51436660779..349d77cfc1b 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -110,8 +110,8 @@ impl<'a, 'gcx, 'tcx> OverloadedDeref<'tcx> { pub fn method_call(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, source: Ty<'tcx>) -> (DefId, &'tcx Substs<'tcx>) { let trait_def_id = match self.mutbl { - hir::MutImmutable => tcx.lang_items.deref_trait(), - hir::MutMutable => tcx.lang_items.deref_mut_trait() + hir::MutImmutable => tcx.lang_items().deref_trait(), + hir::MutMutable => tcx.lang_items().deref_mut_trait() }; let method_def_id = tcx.associated_items(trait_def_id.unwrap()) .find(|m| m.kind == ty::AssociatedKind::Method).unwrap().def_id; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index dbd288c6f2d..c40edff8ed7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -851,8 +851,6 @@ pub struct GlobalCtxt<'tcx> { pub inhabitedness_cache: RefCell, DefIdForest>>, - pub lang_items: middle::lang_items::LanguageItems, - /// Set of nodes which mark locals as mutable which end up getting used at /// some point. Local variable definitions not in this set can be warned /// about. @@ -992,7 +990,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { resolutions: ty::Resolutions, named_region_map: resolve_lifetime::NamedRegionMap, hir: hir_map::Map<'tcx>, - lang_items: middle::lang_items::LanguageItems, stability: stability::Index<'tcx>, crate_name: &str, f: F) -> R @@ -1079,7 +1076,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { rcache: RefCell::new(FxHashMap()), normalized_cache: RefCell::new(FxHashMap()), inhabitedness_cache: RefCell::new(FxHashMap()), - lang_items, used_mut_nodes: RefCell::new(NodeSet()), stability: RefCell::new(stability), selection_cache: traits::SelectionCache::new(), @@ -1099,6 +1095,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let cname = self.crate_name(LOCAL_CRATE).as_str(); self.sess.consider_optimizing(&cname, msg) } + + pub fn lang_items(self) -> Rc { + self.get_lang_items(LOCAL_CRATE) + } } impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { @@ -2004,4 +2004,8 @@ pub fn provide(providers: &mut ty::maps::Providers) { assert_eq!(id, LOCAL_CRATE); tcx.crate_name }; + providers.get_lang_items = |tcx, id| { + assert_eq!(id, LOCAL_CRATE); + Rc::new(middle::lang_items::collect(tcx)) + }; } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index cf21a66d515..2348c4ae767 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1344,7 +1344,7 @@ impl<'a, 'tcx> Layout { } else { let st = Struct::new(dl, &fields, &def.repr, kind, ty)?; - let non_zero = Some(def.did) == tcx.lang_items.non_zero(); + let non_zero = Some(def.did) == tcx.lang_items().non_zero(); Univariant { variant: st, non_zero: non_zero } }; return success(layout); @@ -2043,7 +2043,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> { if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 { return Ok(SizeSkeleton::Pointer { non_zero: non_zero || - Some(def.did) == tcx.lang_items.non_zero(), + Some(def.did) == tcx.lang_items().non_zero(), tail, }); } else { diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 762b35793de..16364500790 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -22,6 +22,7 @@ use middle::privacy::AccessLevels; use middle::region; use middle::region::RegionMaps; use middle::resolve_lifetime::{Region, ObjectLifetimeDefault}; +use middle::lang_items::LanguageItems; use mir; use mir::transform::{MirSuite, MirPassIndex}; use session::CompileResult; @@ -687,6 +688,12 @@ impl<'tcx> QueryDescription for queries::extern_mod_stmt_cnum<'tcx> { } } +impl<'tcx> QueryDescription for queries::get_lang_items<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("calculating the lang items map") + } +} + // If enabled, send a message to the profile-queries thread macro_rules! profq_msg { ($tcx:expr, $msg:expr) => { @@ -1292,6 +1299,8 @@ define_maps! { <'tcx> [] crate_name: CrateName(CrateNum) -> Symbol, [] item_children: ItemChildren(DefId) -> Rc>, [] extern_mod_stmt_cnum: ExternModStmtCnum(HirId) -> Option, + + [] get_lang_items: get_lang_items_node(CrateNum) -> Rc, } fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> { @@ -1381,3 +1390,7 @@ fn implementations_of_trait_node<'tcx>((krate, trait_id): (CrateNum, DefId)) fn link_args_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { DepConstructor::LinkArgs } + +fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { + DepConstructor::GetLangItems +} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c58d9814704..ad14a311c54 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1447,10 +1447,10 @@ impl<'a, 'gcx, 'tcx> AdtDef { if attr::contains_name(&attrs, "fundamental") { flags = flags | AdtFlags::IS_FUNDAMENTAL; } - if Some(did) == tcx.lang_items.phantom_data() { + if Some(did) == tcx.lang_items().phantom_data() { flags = flags | AdtFlags::IS_PHANTOM_DATA; } - if Some(did) == tcx.lang_items.owned_box() { + if Some(did) == tcx.lang_items().owned_box() { flags = flags | AdtFlags::IS_BOX; } match kind { @@ -1746,7 +1746,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { // we know that `T` is Sized and do not need to check // it on the impl. - let sized_trait = match tcx.lang_items.sized_trait() { + let sized_trait = match tcx.lang_items().sized_trait() { Some(x) => x, _ => return vec![ty] }; diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 4e4c7b107c4..f21fc8414e7 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -418,7 +418,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { adt_did: DefId, validate: &mut FnMut(Self, DefId) -> Result<(), ErrorReported> ) -> Option { - let drop_trait = if let Some(def_id) = self.lang_items.drop_trait() { + let drop_trait = if let Some(def_id) = self.lang_items().drop_trait() { def_id } else { return None; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index cc581b07de5..c48bd5ac5be 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -159,7 +159,7 @@ pub fn parameterized(f: &mut fmt::Formatter, } write!(f, "{}", tcx.item_path_str(path_def_id))?; - Ok(tcx.lang_items.fn_trait_kind(path_def_id)) + Ok(tcx.lang_items().fn_trait_kind(path_def_id)) })?; if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { @@ -802,7 +802,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { for predicate in bounds.predicates { if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == tcx.lang_items.sized_trait() { + if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { is_sized = true; continue; } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 10b591432ee..afd89f70992 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -913,12 +913,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let time_passes = sess.time_passes(); - let lang_items = time(time_passes, "language item collection", || { - sess.track_errors(|| { - middle::lang_items::collect_language_items(&sess, &hir_map) - }) - })?; - let named_region_map = time(time_passes, "lifetime resolution", || middle::resolve_lifetime::krate(sess, &hir_map))?; @@ -1028,7 +1022,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, resolutions, named_region_map, hir_map, - lang_items, index, name, |tcx| { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 60d7a4ce87e..e0d82f3dafc 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -547,7 +547,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { _ => return, } - let debug = match cx.tcx.lang_items.debug_trait() { + let debug = match cx.tcx.lang_items().debug_trait() { Some(debug) => debug, None => return, }; diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 0893842eff0..d3b3396413c 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -991,7 +991,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { // "unsized info", else just store None let coerce_unsized_info = trait_ref.and_then(|t| { - if Some(t.def_id) == tcx.lang_items.coerce_unsized_trait() { + if Some(t.def_id) == tcx.lang_items().coerce_unsized_trait() { Some(tcx.at(item.span).coerce_unsized_info(def_id)) } else { None @@ -1322,7 +1322,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { fn encode_lang_items(&mut self, _: ()) -> LazySeq<(DefIndex, usize)> { let tcx = self.tcx; - let lang_items = tcx.lang_items.items().iter(); + let lang_items = tcx.lang_items(); + let lang_items = lang_items.items().iter(); self.lazy_seq(lang_items.enumerate().filter_map(|(i, &opt_def_id)| { if let Some(def_id) = opt_def_id { if def_id.is_local() { @@ -1335,7 +1336,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { fn encode_lang_items_missing(&mut self, _: ()) -> LazySeq { let tcx = self.tcx; - self.lazy_seq_ref(&tcx.lang_items.missing) + self.lazy_seq_ref(&tcx.lang_items().missing) } /// Encodes an index, mapping each trait to its (local) implementations. diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index dc15163ecc1..0b91e08fc6d 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -299,7 +299,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let fail = self.cfg.start_new_block(); if let ty::TyRef(_, mt) = ty.sty { assert!(ty.is_slice()); - let eq_def_id = self.hir.tcx().lang_items.eq_trait().unwrap(); + let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap(); let ty = mt.ty; let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty]); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index d3c886dab4e..023bec57b3f 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -47,7 +47,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, bug!("item {:?} passed to make_shim", instance), ty::InstanceDef::FnPtrShim(def_id, ty) => { let trait_ = tcx.trait_of_item(def_id).unwrap(); - let adjustment = match tcx.lang_items.fn_trait_kind(trait_) { + let adjustment = match tcx.lang_items().fn_trait_kind(trait_) { Some(ty::ClosureKind::FnOnce) => Adjustment::Identity, Some(ty::ClosureKind::FnMut) | Some(ty::ClosureKind::Fn) => Adjustment::Deref, @@ -82,7 +82,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, ) } ty::InstanceDef::ClosureOnceShim { call_once } => { - let fn_mut = tcx.lang_items.fn_mut_trait().unwrap(); + let fn_mut = tcx.lang_items().fn_mut_trait().unwrap(); let call_mut = tcx.global_tcx() .associated_items(fn_mut) .find(|it| it.kind == ty::AssociatedKind::Method) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index d1e0465f555..0fb34c96b06 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -715,7 +715,7 @@ impl MirPass for StateTransform { let gen_ty = mir.local_decls.raw[1].ty; // Compute GeneratorState - let state_did = tcx.lang_items.gen_state().unwrap(); + let state_did = tcx.lang_items().gen_state().unwrap(); let state_adt_ref = tcx.adt_def(state_did); let state_substs = tcx.mk_substs([Kind::from(yield_ty), Kind::from(mir.return_ty)].iter()); diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 3f8070fb3aa..46aa391897a 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -338,7 +338,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => { debug!("Inlined {:?} into {:?}", callsite.callee, self.source); - let is_box_free = Some(callsite.callee) == self.tcx.lang_items.box_free_fn(); + let is_box_free = Some(callsite.callee) == self.tcx.lang_items().box_free_fn(); let mut local_map = IndexVec::with_capacity(callee_mir.local_decls.len()); let mut scope_map = IndexVec::with_capacity(callee_mir.visibility_scopes.len()); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 415421757c5..3b36ff8ce57 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -252,7 +252,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } fn find_drop_implementation_method_span(&self) -> Option { - self.tcx.lang_items + self.tcx.lang_items() .drop_trait() .and_then(|drop_trait_id| { let mut span = None; @@ -795,7 +795,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { self.deny_drop(); } - if Some(def.did) == self.tcx.lang_items.unsafe_cell_type() { + if Some(def.did) == self.tcx.lang_items().unsafe_cell_type() { let ty = rvalue.ty(self.mir, self.tcx); self.add_type(ty); assert!(self.qualif.intersects(Qualif::MUTABLE_INTERIOR)); diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index d4da14ea96e..7fbeb9610f4 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -575,7 +575,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { value: ConstVal::Function(def_id, _), .. }, .. }) => { - Some(def_id) == self.tcx().lang_items.box_free_fn() + Some(def_id) == self.tcx().lang_items().box_free_fn() } _ => false, } diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index f3b121f2eed..8ea47c29910 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -515,7 +515,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> { debug!("destructor_call_block({:?}, {:?})", self, succ); let tcx = self.tcx(); - let drop_trait = tcx.lang_items.drop_trait().unwrap(); + let drop_trait = tcx.lang_items().drop_trait().unwrap(); let drop_fn = tcx.associated_items(drop_trait).next().unwrap(); let ty = self.lvalue_ty(self.lvalue); let substs = tcx.mk_substs(iter::once(Kind::from(ty))); diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index b4f4f565191..6f2c448ceb6 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -401,7 +401,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node hir::ExprStruct(..) => { if let ty::TyAdt(adt, ..) = v.tables.expr_ty(e).sty { // unsafe_cell_type doesn't necessarily exist with no_core - if Some(adt.did) == v.tcx.lang_items.unsafe_cell_type() { + if Some(adt.did) == v.tcx.lang_items().unsafe_cell_type() { v.promotable = false; } } diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 8b864a7fdcf..b56fa34e348 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -432,7 +432,7 @@ fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0); debug!(" => recursion depth={}", recursion_depth); - let recursion_depth = if Some(def_id) == tcx.lang_items.drop_in_place_fn() { + let recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() { // HACK: drop_in_place creates tight monomorphization loops. Give // it more margin. recursion_depth / 4 @@ -550,7 +550,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { mir::Rvalue::NullaryOp(mir::NullOp::Box, _) => { let tcx = self.scx.tcx(); let exchange_malloc_fn_def_id = tcx - .lang_items + .lang_items() .require(ExchangeMallocFnLangItem) .unwrap_or_else(|e| self.scx.sess().fatal(&e)); let instance = Instance::mono(tcx, exchange_malloc_fn_def_id); diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 261792735dc..d947cd8e719 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -423,7 +423,7 @@ pub fn langcall(tcx: TyCtxt, msg: &str, li: LangItem) -> DefId { - match tcx.lang_items.require(li) { + match tcx.lang_items().require(li) { Ok(id) => id, Err(s) => { let msg = format!("{} {}", msg, s); @@ -530,7 +530,7 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); sig.map_bound(|sig| { - let state_did = tcx.lang_items.gen_state().unwrap(); + let state_did = tcx.lang_items().gen_state().unwrap(); let state_adt_ref = tcx.adt_def(state_did); let state_substs = tcx.mk_substs([Kind::from(sig.yield_ty), Kind::from(sig.return_ty)].iter()); diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index f2b07cf6a58..a5830eb17ed 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -616,7 +616,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { return llpersonality } let tcx = self.tcx(); - let llfn = match tcx.lang_items.eh_personality() { + let llfn = match tcx.lang_items().eh_personality() { Some(def_id) if !base::wants_msvc_seh(self.sess()) => { callee::resolve_and_get_fn(self, def_id, tcx.intern_substs(&[])) } @@ -645,7 +645,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { let tcx = self.tcx(); assert!(self.sess().target.target.options.custom_unwind_resume); - if let Some(def_id) = tcx.lang_items.eh_unwind_resume() { + if let Some(def_id) = tcx.lang_items().eh_unwind_resume() { let llfn = callee::resolve_and_get_fn(self, def_id, tcx.intern_substs(&[])); unwresume.set(Some(llfn)); return llfn; diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 9a3c8a5079a..53e24191255 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -822,7 +822,7 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, catchswitch.add_handler(cs, catchpad.llbb()); let tcx = ccx.tcx(); - let tydesc = match tcx.lang_items.msvc_try_filter() { + let tydesc = match tcx.lang_items().msvc_try_filter() { Some(did) => ::consts::get_static(ccx, did), None => bug!("msvc_try_filter not defined"), }; diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 95b76d32bf8..949b9fe71ca 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -114,7 +114,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { }, .. }), ref args, .. - } if Some(def_id) == self.cx.ccx.tcx().lang_items.box_free_fn() => { + } if Some(def_id) == self.cx.ccx.tcx().lang_items().box_free_fn() => { // box_free(x) shares with `drop x` the property that it // is not guaranteed to be statically dominated by the // definition of x, so x must always be in an alloca. diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 9987c9c3310..e8b1430b4b0 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -610,7 +610,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { match operand.ty.sty { ty::TyClosure(def_id, substs) => { // Get the def_id for FnOnce::call_once - let fn_once = tcx.lang_items.fn_once_trait().unwrap(); + let fn_once = tcx.lang_items().fn_once_trait().unwrap(); let call_once = tcx .global_tcx().associated_items(fn_once) .find(|it| it.kind == ty::AssociatedKind::Method) diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 096f43e44ab..34dec57543a 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -482,7 +482,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let box_ty = bcx.tcx().mk_box(content_ty); // Allocate space: - let def_id = match bcx.tcx().lang_items.require(ExchangeMallocFnLangItem) { + let def_id = match bcx.tcx().lang_items().require(ExchangeMallocFnLangItem) { Ok(id) => id, Err(s) => { bcx.sess().fatal(&format!("allocation of `{}` {}", box_ty, s)); diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index 4989ca8cc93..9a7f1524d20 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -31,7 +31,7 @@ fn fn_once_adapter_instance<'a, 'tcx>( debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs); - let fn_once = tcx.lang_items.fn_once_trait().unwrap(); + let fn_once = tcx.lang_items().fn_once_trait().unwrap(); let call_once = tcx.associated_items(fn_once) .find(|it| it.kind == ty::AssociatedKind::Method) .unwrap().def_id; @@ -132,7 +132,7 @@ fn resolve_associated_item<'a, 'tcx>( } } traits::VtableClosure(closure_data) => { - let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap(); + let trait_closure_kind = tcx.lang_items().fn_trait_kind(trait_id).unwrap(); resolve_closure(scx, closure_data.closure_def_id, closure_data.substs, trait_closure_kind) } @@ -149,7 +149,7 @@ fn resolve_associated_item<'a, 'tcx>( substs: rcvr_substs } } - traits::VtableBuiltin(..) if Some(trait_id) == tcx.lang_items.clone_trait() => { + traits::VtableBuiltin(..) if Some(trait_id) == tcx.lang_items().clone_trait() => { Instance { def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()), substs: rcvr_substs @@ -187,7 +187,7 @@ pub fn resolve<'a, 'tcx>( ty::InstanceDef::Intrinsic(def_id) } _ => { - if Some(def_id) == scx.tcx().lang_items.drop_in_place_fn() { + if Some(def_id) == scx.tcx().lang_items().drop_in_place_fn() { let ty = substs.type_at(0); if glue::needs_drop_glue(scx, ty) { debug!(" => nontrivial drop glue"); @@ -224,7 +224,7 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx target_ty: Ty<'tcx>) -> CustomCoerceUnsized { let trait_ref = ty::Binder(ty::TraitRef { - def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(), + def_id: scx.tcx().lang_items().coerce_unsized_trait().unwrap(), substs: scx.tcx().mk_substs_trait(source_ty, &[target_ty]) }); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f391c2f9279..2583d18652d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1288,8 +1288,8 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, Def::Trait(trait_did) => { // Checks whether `trait_did` refers to one of the builtin // traits, like `Send`, and adds it to `auto_traits` if so. - if Some(trait_did) == tcx.lang_items.send_trait() || - Some(trait_did) == tcx.lang_items.sync_trait() { + if Some(trait_did) == tcx.lang_items().send_trait() || + Some(trait_did) == tcx.lang_items().sync_trait() { let segments = &bound.trait_ref.path.segments; let parameters = &segments[segments.len() - 1].parameters; if !parameters.types.is_empty() { @@ -1402,7 +1402,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> { // If it could be sized, and is, add the sized predicate if self.implicitly_sized { - if let Some(sized) = tcx.lang_items.sized_trait() { + if let Some(sized) = tcx.lang_items().sized_trait() { let trait_ref = ty::TraitRef { def_id: sized, substs: tcx.mk_substs_trait(param_ty, &[]) diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index e0e946a9c63..a25deb7685a 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -108,7 +108,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> { // let trait_ref = TraitRef { - def_id: match tcx.lang_items.deref_trait() { + def_id: match tcx.lang_items().deref_trait() { Some(f) => f, None => return None, }, diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 5b9d4af08e0..866949220b5 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -28,7 +28,7 @@ use rustc::hir; /// to `trait_id` (this only cares about the trait, not the specific /// method that is called) pub fn check_legal_trait_for_method_call(tcx: TyCtxt, span: Span, trait_id: DefId) { - if tcx.lang_items.drop_trait() == Some(trait_id) { + if tcx.lang_items().drop_trait() == Some(trait_id) { struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method") .span_label(span, "explicit destructor calls not allowed") .emit(); @@ -157,9 +157,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { MethodCallee<'tcx>)> { // Try the options that are least restrictive on the caller first. for &(opt_trait_def_id, method_name, borrow) in - &[(self.tcx.lang_items.fn_trait(), Symbol::intern("call"), true), - (self.tcx.lang_items.fn_mut_trait(), Symbol::intern("call_mut"), true), - (self.tcx.lang_items.fn_once_trait(), Symbol::intern("call_once"), false)] { + &[(self.tcx.lang_items().fn_trait(), Symbol::intern("call"), true), + (self.tcx.lang_items().fn_mut_trait(), Symbol::intern("call_mut"), true), + (self.tcx.lang_items().fn_once_trait(), Symbol::intern("call_once"), false)] { let trait_def_id = match opt_trait_def_id { Some(def_id) => def_id, None => continue, diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index a768271f3b8..aa2b9c1e038 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -139,7 +139,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }) .next(); let kind = object_type.principal() - .and_then(|p| self.tcx.lang_items.fn_trait_kind(p.def_id())); + .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id())); (sig, kind) } ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), @@ -204,7 +204,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Predicate::ClosureKind(..) => None, }; opt_trait_ref.and_then(|tr| self.self_type_matches_expected_vid(tr, expected_vid)) - .and_then(|tr| self.tcx.lang_items.fn_trait_kind(tr.def_id())) + .and_then(|tr| self.tcx.lang_items().fn_trait_kind(tr.def_id())) }) .fold(None, |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur)))); @@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let trait_ref = projection.to_poly_trait_ref(tcx); - if tcx.lang_items.fn_trait_kind(trait_ref.def_id()).is_none() { + if tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_none() { return None; } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index e406ce845a6..cfcdbcc1195 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -438,8 +438,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { fn coerce_unsized(&self, source: Ty<'tcx>, target: Ty<'tcx>) -> CoerceResult<'tcx> { debug!("coerce_unsized(source={:?}, target={:?})", source, target); - let traits = (self.tcx.lang_items.unsize_trait(), - self.tcx.lang_items.coerce_unsized_trait()); + let traits = (self.tcx.lang_items().unsize_trait(), + self.tcx.lang_items().coerce_unsized_trait()); let (unsize_did, coerce_unsized_did) = if let (Some(u), Some(cu)) = traits { (u, cu) } else { diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 08ec3bf74a7..852134bbee3 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -540,7 +540,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { fn predicates_require_illegal_sized_bound(&self, predicates: &ty::InstantiatedPredicates<'tcx>) -> bool { - let sized_def_id = match self.tcx.lang_items.sized_trait() { + let sized_def_id = match self.tcx.lang_items().sized_trait() { Some(def_id) => def_id, None => return false, }; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index ba74c902f55..3771d330f6d 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -393,6 +393,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_probe(&mut self, self_ty: Ty<'tcx>) { debug!("assemble_probe: self_ty={:?}", self_ty); + let lang_items = self.tcx.lang_items(); match self_ty.sty { ty::TyDynamic(ref data, ..) => { @@ -408,79 +409,79 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { self.assemble_inherent_candidates_from_param(self_ty, p); } ty::TyChar => { - let lang_def_id = self.tcx.lang_items.char_impl(); + let lang_def_id = lang_items.char_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyStr => { - let lang_def_id = self.tcx.lang_items.str_impl(); + let lang_def_id = lang_items.str_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TySlice(_) => { - let lang_def_id = self.tcx.lang_items.slice_impl(); + let lang_def_id = lang_items.slice_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => { - let lang_def_id = self.tcx.lang_items.const_ptr_impl(); + let lang_def_id = lang_items.const_ptr_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => { - let lang_def_id = self.tcx.lang_items.mut_ptr_impl(); + let lang_def_id = lang_items.mut_ptr_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyInt(ast::IntTy::I8) => { - let lang_def_id = self.tcx.lang_items.i8_impl(); + let lang_def_id = lang_items.i8_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyInt(ast::IntTy::I16) => { - let lang_def_id = self.tcx.lang_items.i16_impl(); + let lang_def_id = lang_items.i16_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyInt(ast::IntTy::I32) => { - let lang_def_id = self.tcx.lang_items.i32_impl(); + let lang_def_id = lang_items.i32_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyInt(ast::IntTy::I64) => { - let lang_def_id = self.tcx.lang_items.i64_impl(); + let lang_def_id = lang_items.i64_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyInt(ast::IntTy::I128) => { - let lang_def_id = self.tcx.lang_items.i128_impl(); + let lang_def_id = lang_items.i128_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyInt(ast::IntTy::Is) => { - let lang_def_id = self.tcx.lang_items.isize_impl(); + let lang_def_id = lang_items.isize_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyUint(ast::UintTy::U8) => { - let lang_def_id = self.tcx.lang_items.u8_impl(); + let lang_def_id = lang_items.u8_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyUint(ast::UintTy::U16) => { - let lang_def_id = self.tcx.lang_items.u16_impl(); + let lang_def_id = lang_items.u16_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyUint(ast::UintTy::U32) => { - let lang_def_id = self.tcx.lang_items.u32_impl(); + let lang_def_id = lang_items.u32_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyUint(ast::UintTy::U64) => { - let lang_def_id = self.tcx.lang_items.u64_impl(); + let lang_def_id = lang_items.u64_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyUint(ast::UintTy::U128) => { - let lang_def_id = self.tcx.lang_items.u128_impl(); + let lang_def_id = lang_items.u128_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyUint(ast::UintTy::Us) => { - let lang_def_id = self.tcx.lang_items.usize_impl(); + let lang_def_id = lang_items.usize_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyFloat(ast::FloatTy::F32) => { - let lang_def_id = self.tcx.lang_items.f32_impl(); + let lang_def_id = lang_items.f32_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } ty::TyFloat(ast::FloatTy::F64) => { - let lang_def_id = self.tcx.lang_items.f64_impl(); + let lang_def_id = lang_items.f64_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } _ => {} diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 5c8f237b2a7..5b327566a13 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -45,7 +45,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::TyFnPtr(_) => true, // If it's not a simple function, look for things which implement FnOnce _ => { - let fn_once = match tcx.lang_items.require(FnOnceTraitLangItem) { + let fn_once = match tcx.lang_items().require(FnOnceTraitLangItem) { Ok(fn_once) => fn_once, Err(..) => return false, }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3f210ea1737..0a8d2129a89 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2296,13 +2296,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn resolve_lvalue_op(&self, op: LvalueOp, is_mut: bool) -> (Option, Symbol) { let (tr, name) = match (op, is_mut) { (LvalueOp::Deref, false) => - (self.tcx.lang_items.deref_trait(), "deref"), + (self.tcx.lang_items().deref_trait(), "deref"), (LvalueOp::Deref, true) => - (self.tcx.lang_items.deref_mut_trait(), "deref_mut"), + (self.tcx.lang_items().deref_mut_trait(), "deref_mut"), (LvalueOp::Index, false) => - (self.tcx.lang_items.index_trait(), "index"), + (self.tcx.lang_items().index_trait(), "index"), (LvalueOp::Index, true) => - (self.tcx.lang_items.index_mut_trait(), "index_mut"), + (self.tcx.lang_items().index_mut_trait(), "index_mut"), }; (tr, Symbol::intern(name)) } diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index a4e1fdaf39e..a3dd81fddde 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -362,7 +362,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn lookup_op_method(&self, lhs_ty: Ty<'tcx>, other_tys: &[Ty<'tcx>], op: Op) -> Result, ()> { - let lang = &self.tcx.lang_items; + let lang = self.tcx.lang_items(); let span = match op { Op::Binary(op, _) => op.span, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 69f045ab4e9..9c19aef5992 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -539,7 +539,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { { let mut err = error_392(self.tcx, span, param_name); - let suggested_marker_id = self.tcx.lang_items.phantom_data(); + let suggested_marker_id = self.tcx.lang_items().phantom_data(); match suggested_marker_id { Some(def_id) => { err.help( diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index b421fdfe8d8..fedfa51d61d 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -28,9 +28,9 @@ use rustc::hir::{self, ItemImpl}; pub fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_def_id: DefId) { Checker { tcx, trait_def_id } - .check(tcx.lang_items.drop_trait(), visit_implementation_of_drop) - .check(tcx.lang_items.copy_trait(), visit_implementation_of_copy) - .check(tcx.lang_items.coerce_unsized_trait(), + .check(tcx.lang_items().drop_trait(), visit_implementation_of_drop) + .check(tcx.lang_items().copy_trait(), visit_implementation_of_copy) + .check(tcx.lang_items().coerce_unsized_trait(), visit_implementation_of_coerce_unsized); } @@ -176,9 +176,9 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) -> CoerceUnsizedInfo { debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did); - let coerce_unsized_trait = tcx.lang_items.coerce_unsized_trait().unwrap(); + let coerce_unsized_trait = tcx.lang_items().coerce_unsized_trait().unwrap(); - let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) { + let unsize_trait = match tcx.lang_items().require(UnsizeTraitLangItem) { Ok(id) => id, Err(err) => { tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err)); diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index e24d7660021..15e15abfb36 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -112,6 +112,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> { let def_id = self.tcx.hir.local_def_id(item.id); let self_ty = self.tcx.type_of(def_id); + let lang_items = self.tcx.lang_items(); match self_ty.sty { ty::TyAdt(def, _) => { self.check_def_id(item, def.did); @@ -121,133 +122,133 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> { } ty::TyChar => { self.check_primitive_impl(def_id, - self.tcx.lang_items.char_impl(), + lang_items.char_impl(), "char", "char", item.span); } ty::TyStr => { self.check_primitive_impl(def_id, - self.tcx.lang_items.str_impl(), + lang_items.str_impl(), "str", "str", item.span); } ty::TySlice(_) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.slice_impl(), + lang_items.slice_impl(), "slice", "[T]", item.span); } ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.const_ptr_impl(), + lang_items.const_ptr_impl(), "const_ptr", "*const T", item.span); } ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.mut_ptr_impl(), + lang_items.mut_ptr_impl(), "mut_ptr", "*mut T", item.span); } ty::TyInt(ast::IntTy::I8) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.i8_impl(), + lang_items.i8_impl(), "i8", "i8", item.span); } ty::TyInt(ast::IntTy::I16) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.i16_impl(), + lang_items.i16_impl(), "i16", "i16", item.span); } ty::TyInt(ast::IntTy::I32) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.i32_impl(), + lang_items.i32_impl(), "i32", "i32", item.span); } ty::TyInt(ast::IntTy::I64) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.i64_impl(), + lang_items.i64_impl(), "i64", "i64", item.span); } ty::TyInt(ast::IntTy::I128) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.i128_impl(), + lang_items.i128_impl(), "i128", "i128", item.span); } ty::TyInt(ast::IntTy::Is) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.isize_impl(), + lang_items.isize_impl(), "isize", "isize", item.span); } ty::TyUint(ast::UintTy::U8) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.u8_impl(), + lang_items.u8_impl(), "u8", "u8", item.span); } ty::TyUint(ast::UintTy::U16) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.u16_impl(), + lang_items.u16_impl(), "u16", "u16", item.span); } ty::TyUint(ast::UintTy::U32) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.u32_impl(), + lang_items.u32_impl(), "u32", "u32", item.span); } ty::TyUint(ast::UintTy::U64) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.u64_impl(), + lang_items.u64_impl(), "u64", "u64", item.span); } ty::TyUint(ast::UintTy::U128) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.u128_impl(), + lang_items.u128_impl(), "u128", "u128", item.span); } ty::TyUint(ast::UintTy::Us) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.usize_impl(), + lang_items.usize_impl(), "usize", "usize", item.span); } ty::TyFloat(ast::FloatTy::F32) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.f32_impl(), + lang_items.f32_impl(), "f32", "f32", item.span); } ty::TyFloat(ast::FloatTy::F64) => { self.check_primitive_impl(def_id, - self.tcx.lang_items.f64_impl(), + lang_items.f64_impl(), "f64", "f64", item.span); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 165be49f760..6109fc57b0d 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -51,7 +51,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_def_id: DefId) { let did = Some(trait_def_id); - let li = &tcx.lang_items; + let li = tcx.lang_items(); // Disallow *all* explicit impls of `Sized` and `Unsize` for now. if did == li.sized_trait() { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 38b72677bc6..e4ca0f82ea1 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1309,7 +1309,7 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, } } - let kind_id = tcx.lang_items.require(SizedTraitLangItem); + let kind_id = tcx.lang_items().require(SizedTraitLangItem); match unbound { Some(ref tpb) => { // FIXME(#8559) currently requires the unbound to be built-in. diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index c624b11c5ec..6062ac96ada 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -94,17 +94,18 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx> } fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId, Vec)> { + let lang_items = tcx.lang_items(); let all = vec![ - (tcx.lang_items.phantom_data(), vec![ty::Covariant]), - (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]), + (lang_items.phantom_data(), vec![ty::Covariant]), + (lang_items.unsafe_cell_type(), vec![ty::Invariant]), // Deprecated: - (tcx.lang_items.covariant_type(), vec![ty::Covariant]), - (tcx.lang_items.contravariant_type(), vec![ty::Contravariant]), - (tcx.lang_items.invariant_type(), vec![ty::Invariant]), - (tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]), - (tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]), - (tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]), + (lang_items.covariant_type(), vec![ty::Covariant]), + (lang_items.contravariant_type(), vec![ty::Contravariant]), + (lang_items.invariant_type(), vec![ty::Invariant]), + (lang_items.covariant_lifetime(), vec![ty::Covariant]), + (lang_items.contravariant_lifetime(), vec![ty::Contravariant]), + (lang_items.invariant_lifetime(), vec![ty::Invariant]), ];