@@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
6060let ccx =ConstCx :: new ( tcx, body) ;
6161let ( mut temps, all_candidates) =collect_temps_and_candidates ( & ccx) ;
6262
63- let promotable_candidates =validate_candidates ( & ccx, & mut temps, & all_candidates) ;
63+ let promotable_candidates =validate_candidates ( & ccx, & mut temps, all_candidates) ;
6464
6565let promoted =promote_candidates ( body, tcx, temps, promotable_candidates) ;
6666self . promoted_fragments . set ( promoted) ;
@@ -98,8 +98,8 @@ struct Collector<'a, 'tcx> {
9898}
9999
100100impl < ' tcx > Visitor < ' tcx > for Collector < ' _ , ' tcx > {
101+ #[ instrument( level ="debug" , skip( self ) ) ]
101102fn visit_local ( & mut self , index : Local , context : PlaceContext , location : Location ) {
102- debug ! ( "visit_local: index={:?} context={:?} location={:?}" , index, context, location) ;
103103// We're only interested in temporaries and the return place
104104match self . ccx . body . local_kind ( index) {
105105LocalKind :: Arg =>return ,
@@ -111,20 +111,15 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
111111// then it's constant and thus drop is noop.
112112// Non-uses are also irrelevant.
113113if context. is_drop ( ) || !context. is_use ( ) {
114- debug ! (
115- "visit_local: context.is_drop={:?} context.is_use={:?}" ,
116- context. is_drop( ) ,
117- context. is_use( ) ,
118- ) ;
114+ debug ! ( is_drop = context. is_drop( ) , is_use = context. is_use( ) ) ;
119115return ;
120116}
121117
122118let temp =& mut self . temps [ index] ;
123- debug ! ( "visit_local: temp={:?}" , temp) ;
119+ debug ! ( ? temp) ;
124120* temp =match * temp{
125121TempState :: Undefined =>match context{
126- PlaceContext :: MutatingUse ( MutatingUseContext :: Store )
127- |PlaceContext :: MutatingUse ( MutatingUseContext :: Call ) =>{
122+ PlaceContext :: MutatingUse ( MutatingUseContext :: Store |MutatingUseContext :: Call ) =>{
128123TempState :: Defined { location, uses : 0 , valid : Err ( ( ) ) }
129124}
130125 _ =>TempState :: Unpromotable ,
@@ -137,7 +132,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
137132 |PlaceContext :: NonMutatingUse ( _) =>true ,
138133PlaceContext :: MutatingUse ( _) |PlaceContext :: NonUse ( _) =>false ,
139134} ;
140- debug ! ( "visit_local: allowed_use={:?}" , allowed_use) ;
135+ debug ! ( ? allowed_use) ;
141136if allowed_use{
142137* uses +=1 ;
143138return ;
@@ -146,6 +141,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
146141}
147142TempState :: Unpromotable |TempState :: PromotedOut =>TempState :: Unpromotable ,
148143} ;
144+ debug ! ( ?temp) ;
149145}
150146
151147fn visit_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
@@ -695,15 +691,12 @@ impl<'tcx> Validator<'_, 'tcx> {
695691fn validate_candidates (
696692ccx : & ConstCx < ' _ , ' _ > ,
697693temps : & mut IndexSlice < Local , TempState > ,
698- candidates : & [ Candidate ] ,
694+ mut candidates : Vec < Candidate > ,
699695) ->Vec < Candidate > {
700696let mut validator =Validator { ccx, temps, promotion_safe_blocks : None } ;
701697
698+ candidates. retain ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) ) ;
702699 candidates
703- . iter ( )
704- . copied ( )
705- . filter ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) )
706- . collect ( )
707700}
708701
709702struct Promoter < ' a , ' tcx > {
@@ -972,7 +965,12 @@ fn promote_candidates<'tcx>(
972965candidates : Vec < Candidate > ,
973966) ->IndexVec < Promoted , Body < ' tcx > > {
974967// Visit candidates in reverse, in case they're nested.
975- debug ! ( "promote_candidates({:?})" , candidates) ;
968+ debug ! ( promote_candidates = ?candidates) ;
969+
970+ // eagerly fail fast
971+ if candidates. is_empty ( ) {
972+ return IndexVec :: new ( ) ;
973+ }
976974
977975let mut promotions =IndexVec :: new ( ) ;
978976