diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index e6591789a74..0908ffd249f 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1215,11 +1215,11 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(rbml_w, item.ident.name); encode_unsafety(rbml_w, unsafety); - let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id); + let trait_ref = ty::impl_trait_ref(tcx, local_def(item.id)).unwrap(); encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); rbml_w.end_tag(); } - ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => { + ast::ItemImpl(unsafety, polarity, _, _, ref ty, ref ast_items) => { // We need to encode information about the default methods we // have inherited, so we drive this based on the impl structure. let impl_items = tcx.impl_items.borrow(); @@ -1269,8 +1269,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } rbml_w.end_tag(); } - if opt_trait.is_some() { - let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id); + if let Some(trait_ref) = ty::impl_trait_ref(tcx, local_def(item.id)) { encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); } encode_path(rbml_w, path.clone()); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 64a82fec05c..4a95320b3f7 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -650,9 +650,7 @@ pub struct ctxt<'tcx> { /// A cache for the trait_items() routine pub trait_items_cache: RefCell>>>>, - pub impl_trait_cache: RefCell>>>, - - pub impl_trait_refs: RefCell>>, + pub impl_trait_refs: RefCell>>>, pub trait_defs: RefCell>>, /// Maps from the def-id of an item (trait/struct/enum/fn) to its @@ -675,7 +673,6 @@ pub struct ctxt<'tcx> { pub freevars: RefCell, pub tcache: RefCell>>, pub rcache: RefCell>>, - pub short_names_cache: RefCell, String>>, pub tc_cache: RefCell, TypeContents>>, pub ast_ty_to_ty_cache: RefCell>>, pub enum_var_cache: RefCell>>>>>, @@ -2741,7 +2738,7 @@ pub fn mk_ctxt<'tcx>(s: Session, def_map: def_map, node_types: RefCell::new(FnvHashMap()), item_substs: RefCell::new(NodeMap()), - impl_trait_refs: RefCell::new(NodeMap()), + impl_trait_refs: RefCell::new(DefIdMap()), trait_defs: RefCell::new(DefIdMap()), predicates: RefCell::new(DefIdMap()), super_predicates: RefCell::new(DefIdMap()), @@ -2750,14 +2747,12 @@ pub fn mk_ctxt<'tcx>(s: Session, freevars: freevars, tcache: RefCell::new(DefIdMap()), rcache: RefCell::new(FnvHashMap()), - short_names_cache: RefCell::new(FnvHashMap()), tc_cache: RefCell::new(FnvHashMap()), ast_ty_to_ty_cache: RefCell::new(NodeMap()), enum_var_cache: RefCell::new(DefIdMap()), impl_or_trait_items: RefCell::new(DefIdMap()), trait_item_def_ids: RefCell::new(DefIdMap()), trait_items_cache: RefCell::new(DefIdMap()), - impl_trait_cache: RefCell::new(DefIdMap()), ty_param_defs: RefCell::new(NodeMap()), adjustments: RefCell::new(NodeMap()), normalized_cache: RefCell::new(FnvHashMap()), @@ -4464,16 +4459,6 @@ pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>, } } -pub fn impl_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) - -> ty::TraitRef<'tcx> { - match cx.impl_trait_refs.borrow().get(&id) { - Some(ty) => *ty, - None => cx.sess.bug( - &format!("impl_id_to_trait_ref: no trait ref for impl `{}`", - cx.map.node_to_string(id))) - } -} - pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> { match node_id_to_type_opt(cx, id) { Some(ty) => ty, @@ -5268,12 +5253,12 @@ pub fn associated_consts<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) /// the future). fn lookup_locally_or_in_crate_store(descr: &str, def_id: ast::DefId, - map: &mut DefIdMap, + map: &RefCell>, load_external: F) -> V where V: Clone, F: FnOnce() -> V, { - match map.get(&def_id).cloned() { + match map.borrow().get(&def_id).cloned() { Some(v) => { return v; } None => { } } @@ -5282,7 +5267,7 @@ fn lookup_locally_or_in_crate_store(descr: &str, panic!("No def'n found for {:?} in tcx.{}", def_id, descr); } let v = load_external(); - map.insert(def_id, v.clone()); + map.borrow_mut().insert(def_id, v.clone()); v } @@ -5348,13 +5333,9 @@ pub fn custom_coerce_unsized_kind<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> ImplOrTraitItem<'tcx> { - lookup_locally_or_in_crate_store("impl_or_trait_items", - id, - &mut *cx.impl_or_trait_items - .borrow_mut(), - || { - csearch::get_impl_or_trait_item(cx, id) - }) + lookup_locally_or_in_crate_store( + "impl_or_trait_items", id, &cx.impl_or_trait_items, + || csearch::get_impl_or_trait_item(cx, id)) } /// Returns the parameter index that the given associated type corresponds to. @@ -5881,37 +5862,35 @@ pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> TypeScheme<'tcx> { lookup_locally_or_in_crate_store( - "tcache", did, &mut *cx.tcache.borrow_mut(), + "tcache", did, &cx.tcache, || csearch::get_type(cx, did)) } /// Given the did of a trait, returns its canonical trait ref. pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> &'tcx TraitDef<'tcx> { - memoized(&cx.trait_defs, did, |did: DefId| { - assert!(did.krate != ast::LOCAL_CRATE); - cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did)) - }) + lookup_locally_or_in_crate_store( + "trait_defs", did, &cx.trait_defs, + || cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did)) + ) } /// Given the did of an item, returns its full set of predicates. pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> GenericPredicates<'tcx> { - memoized(&cx.predicates, did, |did: DefId| { - assert!(did.krate != ast::LOCAL_CRATE); - csearch::get_predicates(cx, did) - }) + lookup_locally_or_in_crate_store( + "predicates", did, &cx.predicates, + || csearch::get_predicates(cx, did)) } /// Given the did of a trait, returns its superpredicates. pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> GenericPredicates<'tcx> { - memoized(&cx.super_predicates, did, |did: DefId| { - assert!(did.krate != ast::LOCAL_CRATE); - csearch::get_super_predicates(cx, did) - }) + lookup_locally_or_in_crate_store( + "super_predicates", did, &cx.super_predicates, + || csearch::get_super_predicates(cx, did)) } pub fn predicates<'tcx>( @@ -6281,7 +6260,7 @@ pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>, pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc { lookup_locally_or_in_crate_store( - "item_variance_map", item_id, &mut *tcx.item_variance_map.borrow_mut(), + "item_variance_map", item_id, &tcx.item_variance_map, || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id))) } diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 79736c08f37..8ec406ff41b 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -81,7 +81,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_impl(item); } ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => { - let trait_ref = ty::impl_id_to_trait_ref(ccx.tcx, item.id); + let trait_ref = ty::impl_trait_ref(ccx.tcx, + local_def(item.id)).unwrap(); ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id); match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) { Some(ty::BoundSend) | Some(ty::BoundSync) => {} diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 58ad8ce8628..622c116cdb9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -36,7 +36,7 @@ use std::cell::RefCell; use std::rc::Rc; use syntax::ast::{Crate, DefId}; use syntax::ast::{Item, ItemImpl}; -use syntax::ast::{LOCAL_CRATE, TraitRef}; +use syntax::ast::{LOCAL_CRATE}; use syntax::ast; use syntax::ast_map::NodeItem; use syntax::ast_map; @@ -100,11 +100,8 @@ struct CoherenceCheckVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &Item) { - - //debug!("(checking coherence) item '{}'", token::get_ident(item.ident)); - - if let ItemImpl(_, _, _, ref opt_trait, _, _) = item.node { - self.cc.check_implementation(item, opt_trait.as_ref()) + if let ItemImpl(..) = item.node { + self.cc.check_implementation(item) } visit::walk_item(self, item); @@ -141,7 +138,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { self.check_implementations_of_coerce_unsized(); } - fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) { + fn check_implementation(&self, item: &Item) { let tcx = self.crate_context.tcx; let impl_did = local_def(item.id); let self_type = ty::lookup_item_type(tcx, impl_did); @@ -151,8 +148,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { let impl_items = self.create_impl_from_item(item); - if opt_trait.is_some() { - let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, item.id); + if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx, + impl_did) { debug!("(checking implementation) adding impl for trait '{}', item '{}'", trait_ref.repr(self.crate_context.tcx), token::get_ident(item.ident)); @@ -161,22 +158,13 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { item.span, trait_ref.def_id); self.add_trait_impl(trait_ref, impl_did); - } - - // Add the implementation to the mapping from implementation to base - // type def ID, if there is a base type for this implementation and - // the implementation does not have any associated traits. - match get_base_type_def_id(&self.inference_context, - item.span, - self_type.ty) { - None => { - // Nothing to do. - } - Some(base_type_def_id) => { - // FIXME: Gather up default methods? - if opt_trait.is_none() { - self.add_inherent_impl(base_type_def_id, impl_did); - } + } else { + // Add the implementation to the mapping from implementation to base + // type def ID, if there is a base type for this implementation and + // the implementation does not have any associated traits. + if let Some(base_type_def_id) = get_base_type_def_id( + &self.inference_context, item.span, self_type.ty) { + self.add_inherent_impl(base_type_def_id, impl_did); } } @@ -267,7 +255,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Converts an implementation in the AST to a vector of items. fn create_impl_from_item(&self, item: &Item) -> Vec { match item.node { - ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => { + ItemImpl(_, _, _, _, _, ref impl_items) => { let mut items: Vec = impl_items.iter().map(|impl_item| { match impl_item.node { @@ -287,10 +275,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }).collect(); - if opt_trait.is_some() { - let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, - item.id); - + if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx, + local_def(item.id)) { self.instantiate_default_methods(local_def(item.id), &trait_ref, &mut items); @@ -453,8 +439,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } let source = ty::lookup_item_type(tcx, impl_did).ty; - let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, - impl_did.node); + let trait_ref = ty::impl_trait_ref(self.crate_context.tcx, + impl_did).unwrap(); let target = *trait_ref.substs.types.get(subst::TypeSpace, 0); debug!("check_implementations_of_coerce_unsized: {} -> {} (bound)", source.repr(tcx), target.repr(tcx)); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 48876c2a188..2fba967b3b2 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -820,7 +820,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ty::record_trait_has_default_impl(tcx, trait_ref.def_id); - tcx.impl_trait_refs.borrow_mut().insert(it.id, trait_ref); + tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), Some(trait_ref)); } ast::ItemImpl(_, _, ref generics, @@ -828,7 +828,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ref selfty, ref impl_items) => { // Create generics from the generics specified in the impl head. - debug!("convert: ast_generics={:?}", generics); let ty_generics = ty_generics_for_type_or_impl(ccx, generics); let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics); @@ -926,14 +925,16 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { } } - if let Some(ref ast_trait_ref) = *opt_trait_ref { - let trait_ref = - astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates), - &ExplicitRscope, - ast_trait_ref, - Some(selfty)); - - tcx.impl_trait_refs.borrow_mut().insert(it.id, trait_ref); + if let &Some(ref ast_trait_ref) = opt_trait_ref { + tcx.impl_trait_refs.borrow_mut().insert( + local_def(it.id), + Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates), + &ExplicitRscope, + ast_trait_ref, + Some(selfty))) + ); + } else { + tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None); } enforce_impl_params_are_constrained(tcx,