@@ -131,7 +131,37 @@ pub enum DepNode<D: Clone + Debug> {
131131 // which would yield an overly conservative dep-graph.
132132 TraitItems ( D ) ,
133133 ReprHints ( D ) ,
134- TraitSelect ( Vec < D > ) ,
134+
135+ // Trait selection cache is a little funny. Given a trait
136+ // reference like `Foo: SomeTrait<Bar>`, there could be
137+ // arbitrarily many def-ids to map on in there (e.g., `Foo`,
138+ // `SomeTrait`, `Bar`). We could have a vector of them, but it
139+ // requires heap-allocation, and trait sel in general can be a
140+ // surprisingly hot path. So instead we pick two def-ids: the
141+ // trait def-id, and the first def-id in the input types. If there
142+ // is no def-id in the input types, then we use the trait def-id
143+ // again. So for example:
144+ //
145+ // - `i32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
146+ // - `u32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
147+ // - `Clone: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
148+ // - `Vec<i32>: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Vec }`
149+ // - `String: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: String }`
150+ // - `Foo: Trait<Bar>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
151+ // - `Foo: Trait<i32>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
152+ // - `(Foo, Bar): Trait` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
153+ // - `i32: Trait<Foo>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
154+ //
155+ // You can see that we map many trait refs to the same
156+ // trait-select node. This is not a problem, it just means
157+ // imprecision in our dep-graph tracking. The important thing is
158+ // that for any given trait-ref, we always map to the **same**
159+ // trait-select node.
160+ TraitSelect { trait_def_id : D , input_def_id : D } ,
161+
162+ // For proj. cache, we just keep a list of all def-ids, since it is
163+ // not a hotspot.
164+ ProjectionCache { def_ids : Vec < D > } ,
135165}
136166
137167impl < D : Clone + Debug > DepNode < D > {
@@ -236,9 +266,17 @@ impl<D: Clone + Debug> DepNode<D> {
236266 TraitImpls ( ref d) => op ( d) . map ( TraitImpls ) ,
237267 TraitItems ( ref d) => op ( d) . map ( TraitItems ) ,
238268 ReprHints ( ref d) => op ( d) . map ( ReprHints ) ,
239- TraitSelect ( ref type_ds) => {
240- let type_ds = try_opt ! ( type_ds. iter( ) . map( |d| op( d) ) . collect( ) ) ;
241- Some ( TraitSelect ( type_ds) )
269+ TraitSelect { ref trait_def_id, ref input_def_id } => {
270+ op ( trait_def_id) . and_then ( |trait_def_id| {
271+ op ( input_def_id) . and_then ( |input_def_id| {
272+ Some ( TraitSelect { trait_def_id : trait_def_id,
273+ input_def_id : input_def_id } )
274+ } )
275+ } )
276+ }
277+ ProjectionCache { ref def_ids } => {
278+ let def_ids: Option < Vec < E > > = def_ids. iter ( ) . map ( op) . collect ( ) ;
279+ def_ids. map ( |d| ProjectionCache { def_ids : d } )
242280 }
243281 }
244282 }
0 commit comments