diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c4192ffc697..36d1ae74e91 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2059,55 +2059,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn associated_item(self, def_id: DefId) -> AssociatedItem { - if !def_id.is_local() { - return queries::associated_item::get(self, DUMMY_SP, def_id); - } - - self.maps.associated_item.memoize(def_id, || { - // When the user asks for a given associated item, we - // always go ahead and convert all the associated items in - // the container. Note that we are also careful only to - // ever register a read on the *container* of the assoc - // item, not the assoc item itself. This prevents changes - // in the details of an item (for example, the type to - // which an associated type is bound) from contaminating - // those tasks that just need to scan the names of items - // and so forth. - - let id = self.hir.as_local_node_id(def_id).unwrap(); - let parent_id = self.hir.get_parent(id); - let parent_def_id = self.hir.local_def_id(parent_id); - let parent_item = self.hir.expect_item(parent_id); - match parent_item.node { - hir::ItemImpl(.., ref impl_trait_ref, _, ref impl_item_refs) => { - for impl_item_ref in impl_item_refs { - let assoc_item = - self.associated_item_from_impl_item_ref(parent_def_id, - impl_trait_ref.is_some(), - impl_item_ref); - self.maps.associated_item.borrow_mut() - .insert(assoc_item.def_id, assoc_item); - } - } - - hir::ItemTrait(.., ref trait_item_refs) => { - for trait_item_ref in trait_item_refs { - let assoc_item = - self.associated_item_from_trait_item_ref(parent_def_id, trait_item_ref); - self.maps.associated_item.borrow_mut() - .insert(assoc_item.def_id, assoc_item); - } - } - - ref r => { - panic!("unexpected container of associated items: {:?}", r) - } - } - - // memoize wants us to return something, so return - // the one we generated for this def-id - *self.maps.associated_item.borrow().get(&def_id).unwrap() - }) + queries::associated_item::get(self, DUMMY_SP, def_id) } fn associated_item_from_trait_item_ref(self, @@ -2643,3 +2595,45 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } } + +fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) + -> AssociatedItem +{ + let id = tcx.hir.as_local_node_id(def_id).unwrap(); + let parent_id = tcx.hir.get_parent(id); + let parent_def_id = tcx.hir.local_def_id(parent_id); + let parent_item = tcx.hir.expect_item(parent_id); + match parent_item.node { + hir::ItemImpl(.., ref impl_trait_ref, _, ref impl_item_refs) => { + if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.node_id == id) { + let assoc_item = + tcx.associated_item_from_impl_item_ref(parent_def_id, + impl_trait_ref.is_some(), + impl_item_ref); + debug_assert_eq!(assoc_item.def_id, def_id); + return assoc_item; + } + } + + hir::ItemTrait(.., ref trait_item_refs) => { + if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.node_id == id) { + let assoc_item = + tcx.associated_item_from_trait_item_ref(parent_def_id, trait_item_ref); + debug_assert_eq!(assoc_item.def_id, def_id); + return assoc_item; + } + } + + ref r => { + panic!("unexpected container of associated items: {:?}", r) + } + } + panic!("associated item not found for def_id: {:?}", def_id); +} + +pub fn provide(providers: &mut ty::maps::Providers) { + *providers = ty::maps::Providers { + associated_item, + ..*providers + }; +} diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 5d600270626..d37553d7d66 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -889,6 +889,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let mut local_providers = ty::maps::Providers::default(); mir::provide(&mut local_providers); typeck::provide(&mut local_providers); + ty::provide(&mut local_providers); let mut extern_providers = ty::maps::Providers::default(); cstore::provide(&mut extern_providers);