@@ -84,6 +84,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
84
84
85
85
translation_items : RefCell < FnvHashSet < TransItem < ' tcx > > > ,
86
86
trait_cache : RefCell < DepTrackingMap < TraitSelectionCache < ' tcx > > > ,
87
+ project_cache : RefCell < DepTrackingMap < ProjectionCache < ' tcx > > > ,
87
88
}
88
89
89
90
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
@@ -195,6 +196,46 @@ impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> {
195
196
}
196
197
}
197
198
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
+
198
239
/// This list owns a number of LocalCrateContexts and binds them to their common
199
240
/// SharedCrateContext. This type just exists as a convenience, something to
200
241
/// pass around all LocalCrateContexts with and get an iterator over them.
@@ -496,6 +537,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
496
537
use_dll_storage_attrs : use_dll_storage_attrs,
497
538
translation_items : RefCell :: new ( FnvHashSet ( ) ) ,
498
539
trait_cache : RefCell :: new ( DepTrackingMap :: new ( tcx. dep_graph . clone ( ) ) ) ,
540
+ project_cache : RefCell :: new ( DepTrackingMap :: new ( tcx. dep_graph . clone ( ) ) ) ,
499
541
}
500
542
}
501
543
@@ -519,6 +561,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
519
561
& self . trait_cache
520
562
}
521
563
564
+ pub fn project_cache ( & self ) -> & RefCell < DepTrackingMap < ProjectionCache < ' tcx > > > {
565
+ & self . project_cache
566
+ }
567
+
522
568
pub fn link_meta < ' a > ( & ' a self ) -> & ' a LinkMeta {
523
569
& self . link_meta
524
570
}
0 commit comments