Rollup merge of #40668 - cramertj:on-demandify-more, r=nikomatsakis
On-demandify associated item retrieval Part of #40614. I also started converting `adt_def`, but I decided to open a PR with just this bit first to make sure I'm going about this correctly. r? @nikomatsakis
This commit is contained in:
commit
2233c6dbf1
|
@ -2059,55 +2059,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn associated_item(self, def_id: DefId) -> AssociatedItem {
|
pub fn associated_item(self, def_id: DefId) -> AssociatedItem {
|
||||||
if !def_id.is_local() {
|
queries::associated_item::get(self, DUMMY_SP, def_id)
|
||||||
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()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn associated_item_from_trait_item_ref(self,
|
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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
let mut local_providers = ty::maps::Providers::default();
|
||||||
mir::provide(&mut local_providers);
|
mir::provide(&mut local_providers);
|
||||||
typeck::provide(&mut local_providers);
|
typeck::provide(&mut local_providers);
|
||||||
|
ty::provide(&mut local_providers);
|
||||||
|
|
||||||
let mut extern_providers = ty::maps::Providers::default();
|
let mut extern_providers = ty::maps::Providers::default();
|
||||||
cstore::provide(&mut extern_providers);
|
cstore::provide(&mut extern_providers);
|
||||||
|
|
Loading…
Reference in New Issue