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