File tree Expand file tree Collapse file tree 3 files changed +24
-8
lines changed Expand file tree Collapse file tree 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> {
127127 TraitItems ( D ) ,
128128 ReprHints ( D ) ,
129129 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 ) ,
130135}
131136
132137impl < D : Clone + Debug > DepNode < D > {
@@ -232,6 +237,7 @@ impl<D: Clone + Debug> DepNode<D> {
232237 let type_ds = try_opt ! ( type_ds. iter( ) . map( |d| op( d) ) . collect( ) ) ;
233238 Some ( TraitSelect ( type_ds) )
234239 }
240+ TraitSelectSingle ( ref d) => op ( d) . map ( TraitSelectSingle ) ,
235241 }
236242 }
237243}
Original file line number Diff line number Diff line change @@ -873,18 +873,26 @@ impl<'tcx> TraitPredicate<'tcx> {
873873 // `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
874874 // Note that it's always sound to conflate dep-nodes, it just
875875 // 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 =
877881 self . input_types ( )
878882 . flat_map ( |t| t. walk ( ) )
879883 . 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
884886 } )
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+ }
888896 }
889897
890898 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> {
209209 _ => None ,
210210 } )
211211 . collect ( ) ;
212+ // This code is not hot so it's not worth detecting if
213+ // `TraitSelectSingle` could be used instead of `TraitSelect`.
212214 DepNode :: TraitSelect ( def_ids)
213215 }
214216}
You can’t perform that action at this time.
0 commit comments