@@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
60
60
let ccx = ConstCx :: new ( tcx, body) ;
61
61
let ( mut temps, all_candidates) = collect_temps_and_candidates ( & ccx) ;
62
62
63
- let promotable_candidates = validate_candidates ( & ccx, & mut temps, & all_candidates) ;
63
+ let promotable_candidates = validate_candidates ( & ccx, & mut temps, all_candidates) ;
64
64
65
65
let promoted = promote_candidates ( body, tcx, temps, promotable_candidates) ;
66
66
self . promoted_fragments . set ( promoted) ;
@@ -98,8 +98,8 @@ struct Collector<'a, 'tcx> {
98
98
}
99
99
100
100
impl < ' tcx > Visitor < ' tcx > for Collector < ' _ , ' tcx > {
101
+ #[ instrument( level = "debug" , skip( self ) ) ]
101
102
fn visit_local ( & mut self , index : Local , context : PlaceContext , location : Location ) {
102
- debug ! ( "visit_local: index={:?} context={:?} location={:?}" , index, context, location) ;
103
103
// We're only interested in temporaries and the return place
104
104
match self . ccx . body . local_kind ( index) {
105
105
LocalKind :: Arg => return ,
@@ -111,20 +111,15 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
111
111
// then it's constant and thus drop is noop.
112
112
// Non-uses are also irrelevant.
113
113
if 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( ) ) ;
119
115
return ;
120
116
}
121
117
122
118
let temp = & mut self . temps [ index] ;
123
- debug ! ( "visit_local: temp={:?}" , temp) ;
119
+ debug ! ( ? temp) ;
124
120
* temp = match * temp {
125
121
TempState :: Undefined => match context {
126
- PlaceContext :: MutatingUse ( MutatingUseContext :: Store )
127
- | PlaceContext :: MutatingUse ( MutatingUseContext :: Call ) => {
122
+ PlaceContext :: MutatingUse ( MutatingUseContext :: Store | MutatingUseContext :: Call ) => {
128
123
TempState :: Defined { location, uses : 0 , valid : Err ( ( ) ) }
129
124
}
130
125
_ => TempState :: Unpromotable ,
@@ -137,7 +132,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
137
132
| PlaceContext :: NonMutatingUse ( _) => true ,
138
133
PlaceContext :: MutatingUse ( _) | PlaceContext :: NonUse ( _) => false ,
139
134
} ;
140
- debug ! ( "visit_local: allowed_use={:?}" , allowed_use) ;
135
+ debug ! ( ? allowed_use) ;
141
136
if allowed_use {
142
137
* uses += 1 ;
143
138
return ;
@@ -146,6 +141,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
146
141
}
147
142
TempState :: Unpromotable | TempState :: PromotedOut => TempState :: Unpromotable ,
148
143
} ;
144
+ debug ! ( ?temp) ;
149
145
}
150
146
151
147
fn visit_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
@@ -695,15 +691,12 @@ impl<'tcx> Validator<'_, 'tcx> {
695
691
fn validate_candidates (
696
692
ccx : & ConstCx < ' _ , ' _ > ,
697
693
temps : & mut IndexSlice < Local , TempState > ,
698
- candidates : & [ Candidate ] ,
694
+ mut candidates : Vec < Candidate > ,
699
695
) -> Vec < Candidate > {
700
696
let mut validator = Validator { ccx, temps, promotion_safe_blocks : None } ;
701
697
698
+ candidates. retain ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) ) ;
702
699
candidates
703
- . iter ( )
704
- . copied ( )
705
- . filter ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) )
706
- . collect ( )
707
700
}
708
701
709
702
struct Promoter < ' a , ' tcx > {
@@ -972,7 +965,12 @@ fn promote_candidates<'tcx>(
972
965
candidates : Vec < Candidate > ,
973
966
) -> IndexVec < Promoted , Body < ' tcx > > {
974
967
// 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
+ }
976
974
977
975
let mut promotions = IndexVec :: new ( ) ;
978
976
0 commit comments