Skip to content

Commit c5be6f6

Browse files
committed
add cache to shared context for proj
1 parent 72694d5 commit c5be6f6

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

src/librustc_trans/context.rs

+46
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
8484

8585
translation_items: RefCell<FnvHashSet<TransItem<'tcx>>>,
8686
trait_cache: RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>>,
87+
project_cache: RefCell<DepTrackingMap<ProjectionCache<'tcx>>>,
8788
}
8889

8990
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
@@ -195,6 +196,46 @@ impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> {
195196
}
196197
}
197198

199+
// # Global Cache
200+
201+
pub struct ProjectionCache<'gcx> {
202+
data: PhantomData<&'gcx ()>
203+
}
204+
205+
impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
206+
type Key = Ty<'gcx>;
207+
type Value = Ty<'gcx>;
208+
fn to_dep_node(key: &Self::Key) -> DepNode<DefId> {
209+
// Ideally, we'd just put `key` into the dep-node, but we
210+
// can't put full types in there. So just collect up all the
211+
// def-ids of structs/enums as well as any traits that we
212+
// project out of. It doesn't matter so much what we do here,
213+
// except that if we are too coarse, we'll create overly
214+
// coarse edges between impls and the trans. For example, if
215+
// we just used the def-id of things we are projecting out of,
216+
// then the key for `<Foo as SomeTrait>::T` and `<Bar as
217+
// SomeTrait>::T` would both share a dep-node
218+
// (`TraitSelect(SomeTrait)`), and hence the impls for both
219+
// `Foo` and `Bar` would be considered inputs. So a change to
220+
// `Bar` would affect things that just normalized `Foo`.
221+
// Anyway, this heuristic is not ideal, but better than
222+
// nothing.
223+
let def_ids: Vec<DefId> =
224+
key.walk()
225+
.filter_map(|t| match t.sty {
226+
ty::TyStruct(adt_def, _) |
227+
ty::TyEnum(adt_def, _) =>
228+
Some(adt_def.did),
229+
ty::TyProjection(ref proj) =>
230+
Some(proj.trait_ref.def_id),
231+
_ =>
232+
None
233+
})
234+
.collect();
235+
DepNode::TraitSelect(def_ids)
236+
}
237+
}
238+
198239
/// This list owns a number of LocalCrateContexts and binds them to their common
199240
/// SharedCrateContext. This type just exists as a convenience, something to
200241
/// pass around all LocalCrateContexts with and get an iterator over them.
@@ -496,6 +537,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
496537
use_dll_storage_attrs: use_dll_storage_attrs,
497538
translation_items: RefCell::new(FnvHashSet()),
498539
trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
540+
project_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
499541
}
500542
}
501543

@@ -519,6 +561,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
519561
&self.trait_cache
520562
}
521563

564+
pub fn project_cache(&self) -> &RefCell<DepTrackingMap<ProjectionCache<'tcx>>> {
565+
&self.project_cache
566+
}
567+
522568
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
523569
&self.link_meta
524570
}

0 commit comments

Comments
 (0)