@@ -82,9 +82,9 @@ impl<'tcx> MirPass<'tcx> for PromoteArraysOpt<'tcx> {
82
82
}
83
83
84
84
let ccx = ConstCx :: new ( tcx, body) ;
85
- let ( mut temps, all_candidates, already_promoted) = collect_temps_and_candidates ( & ccx) ;
85
+ let ( mut temps, mut all_candidates, already_promoted) = collect_temps_and_candidates ( & ccx) ;
86
86
87
- let promotable_candidates = validate_candidates ( & ccx, & mut temps, & all_candidates) ;
87
+ let promotable_candidates = validate_candidates ( & ccx, & mut temps, & mut all_candidates) ;
88
88
debug ! ( candidates = ?promotable_candidates) ;
89
89
90
90
let promoted =
@@ -109,18 +109,16 @@ enum TempState {
109
109
PromotedOut ,
110
110
}
111
111
112
- /// A "root candidate" for promotion, which will become the
113
- /// returned value in a promoted MIR, unless it's a subset
114
- /// of a larger candidate.
115
- #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
116
- struct Candidate {
117
- location : Location ,
118
- }
112
+ #[ derive( Clone , Debug ) ]
113
+ struct Candidates ( Vec < Location > ) ;
119
114
120
115
struct Collector < ' a , ' tcx > {
121
116
ccx : & ' a ConstCx < ' a , ' tcx > ,
122
117
temps : IndexVec < Local , TempState > ,
123
- candidates : Vec < Candidate > ,
118
+ /// A "root candidate" for promotion, which will become the
119
+ /// returned value in a promoted MIR, unless it's a subset
120
+ /// of a larger candidate.
121
+ candidates : Candidates ,
124
122
already_promoted : usize ,
125
123
}
126
124
@@ -197,7 +195,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
197
195
}
198
196
199
197
debug ! ( "pushing a candidate of type {:?} @ {:?}" , kind, location) ;
200
- self . candidates . push ( Candidate { location } ) ;
198
+ self . candidates . 0 . push ( location) ;
201
199
}
202
200
203
201
// #[instrument(level = "debug", skip(self, constant))]
@@ -214,10 +212,10 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
214
212
215
213
fn collect_temps_and_candidates < ' tcx > (
216
214
ccx : & ConstCx < ' _ , ' tcx > ,
217
- ) -> ( IndexVec < Local , TempState > , Vec < Candidate > , usize ) {
215
+ ) -> ( IndexVec < Local , TempState > , Candidates , usize ) {
218
216
let mut collector = Collector {
219
217
temps : IndexVec :: from_elem ( TempState :: Undefined , & ccx. body . local_decls ) ,
220
- candidates : vec ! [ ] ,
218
+ candidates : Candidates ( vec ! [ ] ) ,
221
219
ccx,
222
220
already_promoted : 0 ,
223
221
} ;
@@ -254,8 +252,8 @@ impl<'a, 'tcx> std::ops::Deref for Validator<'a, 'tcx> {
254
252
struct Unpromotable ;
255
253
256
254
impl < ' tcx > Validator < ' _ , ' tcx > {
257
- fn validate_candidate ( & mut self , candidate : Candidate ) -> Result < ( ) , Unpromotable > {
258
- let Left ( statement) = self . body . stmt_at ( candidate. location ) else { bug ! ( ) } ;
255
+ fn validate_candidate ( & mut self , candidate : Location ) -> Result < ( ) , Unpromotable > {
256
+ let Left ( statement) = self . body . stmt_at ( candidate) else { bug ! ( ) } ;
259
257
let Some ( ( place, rvalue @ Rvalue :: Aggregate ( box kind, operands) ) ) =
260
258
statement. kind . as_assign ( )
261
259
else {
@@ -780,18 +778,15 @@ impl<'tcx> Validator<'_, 'tcx> {
780
778
}
781
779
}
782
780
783
- fn validate_candidates (
781
+ fn validate_candidates < ' a > (
784
782
ccx : & ConstCx < ' _ , ' _ > ,
785
783
temps : & mut IndexSlice < Local , TempState > ,
786
- candidates : & [ Candidate ] ,
787
- ) -> Vec < Candidate > {
784
+ candidates : & ' a mut Candidates ,
785
+ ) -> & ' a mut Candidates {
788
786
let mut validator = Validator { ccx, temps, promotion_safe_blocks : None } ;
789
787
788
+ candidates. 0 . retain ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) ) ;
790
789
candidates
791
- . iter ( )
792
- . copied ( )
793
- . filter ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) )
794
- . collect ( )
795
790
}
796
791
797
792
struct Promoter < ' a , ' tcx > {
@@ -946,7 +941,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
946
941
new_temp
947
942
}
948
943
949
- fn promote_candidate ( mut self , candidate : Candidate , next_promoted_id : usize ) -> Body < ' tcx > {
944
+ fn promote_candidate ( mut self , candidate : Location , next_promoted_id : usize ) -> Body < ' tcx > {
950
945
let def = self . source . source . def_id ( ) ;
951
946
let promoted_id = Promoted :: new ( next_promoted_id) ;
952
947
let ( mut rvalue, promoted_op, promoted_ref_rvalue) = {
@@ -963,7 +958,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
963
958
964
959
let blocks = self . source . basic_blocks . as_mut ( ) ;
965
960
let local_decls = & mut self . source . local_decls ;
966
- let loc = candidate. location ;
961
+ let loc = candidate;
967
962
let statement = & mut blocks[ loc. block ] . statements [ loc. statement_index ] ;
968
963
let StatementKind :: Assign ( box ( place, Rvalue :: Aggregate ( _kind, _operands) ) ) =
969
964
& mut statement. kind
@@ -1017,7 +1012,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
1017
1012
1018
1013
{
1019
1014
let blocks = self . source . basic_blocks_mut ( ) ;
1020
- let loc = candidate. location ;
1015
+ let loc = candidate;
1021
1016
let statement = & mut blocks[ loc. block ] . statements [ loc. statement_index ] ;
1022
1017
if let StatementKind :: Assign ( box ( _place, ref mut rvalue) ) = & mut statement. kind {
1023
1018
* rvalue = promoted_rvalue;
@@ -1068,20 +1063,20 @@ fn promote_candidates<'tcx>(
1068
1063
body : & mut Body < ' tcx > ,
1069
1064
tcx : TyCtxt < ' tcx > ,
1070
1065
mut temps : IndexVec < Local , TempState > ,
1071
- candidates : Vec < Candidate > ,
1066
+ candidates : & Candidates ,
1072
1067
already_promoted : usize ,
1073
1068
) -> IndexVec < Promoted , Body < ' tcx > > {
1074
1069
// eagerly fail fast
1075
- if candidates. is_empty ( ) {
1070
+ if candidates. 0 . is_empty ( ) {
1076
1071
return IndexVec :: new ( ) ;
1077
1072
}
1078
1073
1079
1074
let mut promotions = IndexVec :: new ( ) ;
1080
1075
1081
1076
let mut extra_statements = vec ! [ ] ;
1082
1077
// Visit candidates in reverse, in case they're nested.
1083
- for candidate in candidates. into_iter ( ) . rev ( ) {
1084
- let Location { block, statement_index } = candidate. location ;
1078
+ for candidate in candidates. 0 . iter ( ) . copied ( ) . rev ( ) {
1079
+ let Location { block, statement_index } = candidate;
1085
1080
if let StatementKind :: Assign ( box ( place, _) ) = & body[ block] . statements [ statement_index] . kind
1086
1081
{
1087
1082
if let Some ( local) = place. as_local ( ) {
@@ -1095,7 +1090,7 @@ fn promote_candidates<'tcx>(
1095
1090
// Declare return place local so that `mir::Body::new` doesn't complain.
1096
1091
let initial_locals = IndexVec :: from ( [ LocalDecl :: new ( tcx. types . never , body. span ) ] ) ;
1097
1092
1098
- let mut scope = body. source_scopes [ body. source_info ( candidate. location ) . scope ] . clone ( ) ;
1093
+ let mut scope = body. source_scopes [ body. source_info ( candidate) . scope ] . clone ( ) ;
1099
1094
scope. parent_scope = None ;
1100
1095
1101
1096
let mut promoted = Body :: new (
0 commit comments