Skip to content

Commit

Permalink
On-demandify associated item retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
cramertj committed Mar 20, 2017
1 parent 6eb9960 commit 4cd28a7
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 49 deletions.
94 changes: 45 additions & 49 deletions src/librustc/ty/mod.rs
Expand Up @@ -2049,55 +2049,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,
Expand Down Expand Up @@ -2623,3 +2575,47 @@ 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) => {
for impl_item_ref in impl_item_refs {
let assoc_item =
tcx.associated_item_from_impl_item_ref(parent_def_id,
impl_trait_ref.is_some(),
impl_item_ref);
if assoc_item.def_id == def_id {
return assoc_item;
}
}
}

hir::ItemTrait(.., ref trait_item_refs) => {
for trait_item_ref in trait_item_refs {
let assoc_item =
tcx.associated_item_from_trait_item_ref(parent_def_id, trait_item_ref);
if 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
};
}
1 change: 1 addition & 0 deletions src/librustc_driver/driver.rs
Expand Up @@ -882,6 +882,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);
Expand Down

0 comments on commit 4cd28a7

Please sign in to comment.