File tree 3 files changed +24
-8
lines changed
3 files changed +24
-8
lines changed Original file line number Diff line number Diff line change @@ -127,6 +127,11 @@ pub enum DepNode<D: Clone + Debug> {
127
127
TraitItems ( D ) ,
128
128
ReprHints ( D ) ,
129
129
TraitSelect ( Vec < D > ) ,
130
+
131
+ // An optional alternative to `TraitSelect` that avoids a heap allocation
132
+ // in the case where there is a single D. (Note that `TraitSelect` is still
133
+ // allowed to contain a Vec with a single D.)
134
+ TraitSelectSingle ( D ) ,
130
135
}
131
136
132
137
impl < D : Clone + Debug > DepNode < D > {
@@ -232,6 +237,7 @@ impl<D: Clone + Debug> DepNode<D> {
232
237
let type_ds = try_opt ! ( type_ds. iter( ) . map( |d| op( d) ) . collect( ) ) ;
233
238
Some ( TraitSelect ( type_ds) )
234
239
}
240
+ TraitSelectSingle ( ref d) => op ( d) . map ( TraitSelectSingle ) ,
235
241
}
236
242
}
237
243
}
Original file line number Diff line number Diff line change @@ -873,18 +873,26 @@ impl<'tcx> TraitPredicate<'tcx> {
873
873
// `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
874
874
// Note that it's always sound to conflate dep-nodes, it just
875
875
// leads to more recompilation.
876
- let def_ids: Vec < _ > =
876
+ //
877
+ // This code is hot enough that it's worth going to some effort (i.e.
878
+ // the peek()) to use `TraitSelectSingle` and avoid a heap allocation
879
+ // when possible.
880
+ let mut def_ids_base =
877
881
self . input_types ( )
878
882
. flat_map ( |t| t. walk ( ) )
879
883
. filter_map ( |t| match t. sty {
880
- ty:: TyAdt ( adt_def, _) =>
881
- Some ( adt_def. did ) ,
882
- _ =>
883
- None
884
+ ty:: TyAdt ( adt_def, _) => Some ( adt_def. did ) ,
885
+ _ => None
884
886
} )
885
- . chain ( iter:: once ( self . def_id ( ) ) )
886
- . collect ( ) ;
887
- DepNode :: TraitSelect ( def_ids)
887
+ . peekable ( ) ;
888
+ if let Some ( _) = def_ids_base. peek ( ) {
889
+ let def_ids = def_ids_base
890
+ . chain ( iter:: once ( self . def_id ( ) ) )
891
+ . collect ( ) ;
892
+ DepNode :: TraitSelect ( def_ids)
893
+ } else {
894
+ DepNode :: TraitSelectSingle ( self . def_id ( ) )
895
+ }
888
896
}
889
897
890
898
pub fn input_types < ' a > ( & ' a self ) -> impl DoubleEndedIterator < Item =Ty < ' tcx > > + ' a {
Original file line number Diff line number Diff line change @@ -209,6 +209,8 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
209
209
_ => None ,
210
210
} )
211
211
. collect ( ) ;
212
+ // This code is not hot so it's not worth detecting if
213
+ // `TraitSelectSingle` could be used instead of `TraitSelect`.
212
214
DepNode :: TraitSelect ( def_ids)
213
215
}
214
216
}
You can’t perform that action at this time.
0 commit comments