add cache to shared context for proj
This commit is contained in:
parent
72694d5829
commit
c5be6f6cc6
@ -84,6 +84,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
|||||||
|
|
||||||
translation_items: RefCell<FnvHashSet<TransItem<'tcx>>>,
|
translation_items: RefCell<FnvHashSet<TransItem<'tcx>>>,
|
||||||
trait_cache: RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>>,
|
trait_cache: RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>>,
|
||||||
|
project_cache: RefCell<DepTrackingMap<ProjectionCache<'tcx>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
|
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
|
||||||
@ -195,6 +196,46 @@ impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// # Global Cache
|
||||||
|
|
||||||
|
pub struct ProjectionCache<'gcx> {
|
||||||
|
data: PhantomData<&'gcx ()>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
|
||||||
|
type Key = Ty<'gcx>;
|
||||||
|
type Value = Ty<'gcx>;
|
||||||
|
fn to_dep_node(key: &Self::Key) -> DepNode<DefId> {
|
||||||
|
// Ideally, we'd just put `key` into the dep-node, but we
|
||||||
|
// can't put full types in there. So just collect up all the
|
||||||
|
// def-ids of structs/enums as well as any traits that we
|
||||||
|
// project out of. It doesn't matter so much what we do here,
|
||||||
|
// except that if we are too coarse, we'll create overly
|
||||||
|
// coarse edges between impls and the trans. For example, if
|
||||||
|
// we just used the def-id of things we are projecting out of,
|
||||||
|
// then the key for `<Foo as SomeTrait>::T` and `<Bar as
|
||||||
|
// SomeTrait>::T` would both share a dep-node
|
||||||
|
// (`TraitSelect(SomeTrait)`), and hence the impls for both
|
||||||
|
// `Foo` and `Bar` would be considered inputs. So a change to
|
||||||
|
// `Bar` would affect things that just normalized `Foo`.
|
||||||
|
// Anyway, this heuristic is not ideal, but better than
|
||||||
|
// nothing.
|
||||||
|
let def_ids: Vec<DefId> =
|
||||||
|
key.walk()
|
||||||
|
.filter_map(|t| match t.sty {
|
||||||
|
ty::TyStruct(adt_def, _) |
|
||||||
|
ty::TyEnum(adt_def, _) =>
|
||||||
|
Some(adt_def.did),
|
||||||
|
ty::TyProjection(ref proj) =>
|
||||||
|
Some(proj.trait_ref.def_id),
|
||||||
|
_ =>
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
DepNode::TraitSelect(def_ids)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This list owns a number of LocalCrateContexts and binds them to their common
|
/// This list owns a number of LocalCrateContexts and binds them to their common
|
||||||
/// SharedCrateContext. This type just exists as a convenience, something to
|
/// SharedCrateContext. This type just exists as a convenience, something to
|
||||||
/// pass around all LocalCrateContexts with and get an iterator over them.
|
/// pass around all LocalCrateContexts with and get an iterator over them.
|
||||||
@ -496,6 +537,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||||||
use_dll_storage_attrs: use_dll_storage_attrs,
|
use_dll_storage_attrs: use_dll_storage_attrs,
|
||||||
translation_items: RefCell::new(FnvHashSet()),
|
translation_items: RefCell::new(FnvHashSet()),
|
||||||
trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
|
trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
|
||||||
|
project_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,6 +561,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||||||
&self.trait_cache
|
&self.trait_cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn project_cache(&self) -> &RefCell<DepTrackingMap<ProjectionCache<'tcx>>> {
|
||||||
|
&self.project_cache
|
||||||
|
}
|
||||||
|
|
||||||
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
||||||
&self.link_meta
|
&self.link_meta
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user