@@ -58,9 +58,10 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
58
58
}
59
59
60
60
let ccx = ConstCx :: new ( tcx, body) ;
61
- let ( mut temps, all_candidates) = collect_temps_and_candidates ( & ccx) ;
61
+ let ( mut temps, mut all_candidates) = collect_temps_and_candidates ( & ccx) ;
62
62
63
- let promotable_candidates = validate_candidates ( & ccx, & mut temps, & all_candidates) ;
63
+ validate_candidates ( & ccx, & mut temps, & mut all_candidates) ;
64
+ let promotable_candidates = & all_candidates. 0 [ ..] ;
64
65
65
66
let promoted = promote_candidates ( body, tcx, temps, promotable_candidates) ;
66
67
self . promoted_fragments . set ( promoted) ;
@@ -83,18 +84,16 @@ enum TempState {
83
84
PromotedOut ,
84
85
}
85
86
86
- /// A "root candidate" for promotion, which will become the
87
- /// returned value in a promoted MIR, unless it's a subset
88
- /// of a larger candidate.
89
- #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
90
- struct Candidate {
91
- location : Location ,
92
- }
87
+ /// Each `[Location]` is a "root candidate" for promotion, which will become
88
+ /// the returned value in a promoted MIR, unless it's a subset of a larger
89
+ /// candidate.
90
+ #[ derive( Clone , Debug ) ]
91
+ struct Candidates ( Vec < Location > ) ;
93
92
94
93
struct Collector < ' a , ' tcx > {
95
94
ccx : & ' a ConstCx < ' a , ' tcx > ,
96
95
temps : IndexVec < Local , TempState > ,
97
- candidates : Vec < Candidate > ,
96
+ candidates : Candidates ,
98
97
}
99
98
100
99
impl < ' tcx > Visitor < ' tcx > for Collector < ' _ , ' tcx > {
@@ -141,24 +140,23 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
141
140
}
142
141
TempState :: Unpromotable | TempState :: PromotedOut => TempState :: Unpromotable ,
143
142
} ;
144
- debug ! ( ?temp) ;
145
143
}
146
144
147
145
fn visit_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
148
146
self . super_rvalue ( rvalue, location) ;
149
147
150
148
if let Rvalue :: Ref ( ..) = * rvalue {
151
- self . candidates . push ( Candidate { location } ) ;
149
+ self . candidates . 0 . push ( location) ;
152
150
}
153
151
}
154
152
}
155
153
156
154
fn collect_temps_and_candidates < ' tcx > (
157
155
ccx : & ConstCx < ' _ , ' tcx > ,
158
- ) -> ( IndexVec < Local , TempState > , Vec < Candidate > ) {
156
+ ) -> ( IndexVec < Local , TempState > , Candidates ) {
159
157
let mut collector = Collector {
160
158
temps : IndexVec :: from_elem ( TempState :: Undefined , & ccx. body . local_decls ) ,
161
- candidates : vec ! [ ] ,
159
+ candidates : Candidates ( vec ! [ ] ) ,
162
160
ccx,
163
161
} ;
164
162
for ( bb, data) in traversal:: reverse_postorder ( ccx. body ) {
@@ -192,8 +190,8 @@ impl<'a, 'tcx> std::ops::Deref for Validator<'a, 'tcx> {
192
190
struct Unpromotable ;
193
191
194
192
impl < ' tcx > Validator < ' _ , ' tcx > {
195
- fn validate_candidate ( & mut self , candidate : Candidate ) -> Result < ( ) , Unpromotable > {
196
- let Left ( statement) = self . body . stmt_at ( candidate. location ) else { bug ! ( ) } ;
193
+ fn validate_candidate ( & mut self , candidate : Location ) -> Result < ( ) , Unpromotable > {
194
+ let Left ( statement) = self . body . stmt_at ( candidate) else { bug ! ( ) } ;
197
195
let Some ( ( _, Rvalue :: Ref ( _, kind, place) ) ) = statement. kind . as_assign ( ) else { bug ! ( ) } ;
198
196
199
197
// We can only promote interior borrows of promotable temps (non-temps
@@ -691,15 +689,11 @@ impl<'tcx> Validator<'_, 'tcx> {
691
689
fn validate_candidates (
692
690
ccx : & ConstCx < ' _ , ' _ > ,
693
691
temps : & mut IndexSlice < Local , TempState > ,
694
- candidates : & [ Candidate ] ,
695
- ) -> Vec < Candidate > {
692
+ candidates : & mut Candidates ,
693
+ ) {
696
694
let mut validator = Validator { ccx, temps, promotion_safe_blocks : None } ;
697
695
698
- candidates
699
- . iter ( )
700
- . copied ( )
701
- . filter ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) )
702
- . collect ( )
696
+ candidates. 0 . retain ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) ) ;
703
697
}
704
698
705
699
struct Promoter < ' a , ' tcx > {
@@ -854,7 +848,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
854
848
new_temp
855
849
}
856
850
857
- fn promote_candidate ( mut self , candidate : Candidate , next_promoted_id : usize ) -> Body < ' tcx > {
851
+ fn promote_candidate ( mut self , candidate : Location , next_promoted_id : usize ) -> Body < ' tcx > {
858
852
let def = self . source . source . def_id ( ) ;
859
853
let ( mut rvalue, promoted_op) = {
860
854
let promoted = & mut self . promoted ;
@@ -871,7 +865,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
871
865
872
866
let blocks = self . source . basic_blocks . as_mut ( ) ;
873
867
let local_decls = & mut self . source . local_decls ;
874
- let loc = candidate. location ;
868
+ let loc = candidate;
875
869
let statement = & mut blocks[ loc. block ] . statements [ loc. statement_index ] ;
876
870
let StatementKind :: Assign ( box ( _, Rvalue :: Ref ( region, borrow_kind, place) ) ) =
877
871
& mut statement. kind
@@ -965,7 +959,7 @@ fn promote_candidates<'tcx>(
965
959
body : & mut Body < ' tcx > ,
966
960
tcx : TyCtxt < ' tcx > ,
967
961
mut temps : IndexVec < Local , TempState > ,
968
- candidates : Vec < Candidate > ,
962
+ candidates : & [ Location ] ,
969
963
) -> IndexVec < Promoted , Body < ' tcx > > {
970
964
// Visit candidates in reverse, in case they're nested.
971
965
debug ! ( promote_candidates = ?candidates) ;
@@ -978,8 +972,8 @@ fn promote_candidates<'tcx>(
978
972
let mut promotions = IndexVec :: new ( ) ;
979
973
980
974
let mut extra_statements = vec ! [ ] ;
981
- for candidate in candidates. into_iter ( ) . rev ( ) {
982
- let Location { block, statement_index } = candidate. location ;
975
+ for candidate in candidates. iter ( ) . copied ( ) . rev ( ) {
976
+ let Location { block, statement_index } = candidate;
983
977
if let StatementKind :: Assign ( box ( place, _) ) = & body[ block] . statements [ statement_index] . kind
984
978
{
985
979
if let Some ( local) = place. as_local ( ) {
@@ -993,7 +987,7 @@ fn promote_candidates<'tcx>(
993
987
// Declare return place local so that `mir::Body::new` doesn't complain.
994
988
let initial_locals = iter:: once ( LocalDecl :: new ( tcx. types . never , body. span ) ) . collect ( ) ;
995
989
996
- let mut scope = body. source_scopes [ body. source_info ( candidate. location ) . scope ] . clone ( ) ;
990
+ let mut scope = body. source_scopes [ body. source_info ( candidate) . scope ] . clone ( ) ;
997
991
scope. parent_scope = None ;
998
992
999
993
let mut promoted = Body :: new (
0 commit comments