@@ -82,9 +82,9 @@ impl<'tcx> MirPass<'tcx> for PromoteArraysOpt<'tcx> {
8282 }
8383
8484 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) ;
8686
87- let promotable_candidates = validate_candidates ( & ccx, & mut temps, & all_candidates) ;
87+ let promotable_candidates = validate_candidates ( & ccx, & mut temps, & mut all_candidates) ;
8888 debug ! ( candidates = ?promotable_candidates) ;
8989
9090 let promoted =
@@ -109,18 +109,16 @@ enum TempState {
109109 PromotedOut ,
110110}
111111
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 > ) ;
119114
120115struct Collector < ' a , ' tcx > {
121116 ccx : & ' a ConstCx < ' a , ' tcx > ,
122117 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 ,
124122 already_promoted : usize ,
125123}
126124
@@ -197,7 +195,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
197195 }
198196
199197 debug ! ( "pushing a candidate of type {:?} @ {:?}" , kind, location) ;
200- self . candidates . push ( Candidate { location } ) ;
198+ self . candidates . 0 . push ( location) ;
201199 }
202200
203201 // #[instrument(level = "debug", skip(self, constant))]
@@ -214,10 +212,10 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
214212
215213fn collect_temps_and_candidates < ' tcx > (
216214 ccx : & ConstCx < ' _ , ' tcx > ,
217- ) -> ( IndexVec < Local , TempState > , Vec < Candidate > , usize ) {
215+ ) -> ( IndexVec < Local , TempState > , Candidates , usize ) {
218216 let mut collector = Collector {
219217 temps : IndexVec :: from_elem ( TempState :: Undefined , & ccx. body . local_decls ) ,
220- candidates : vec ! [ ] ,
218+ candidates : Candidates ( vec ! [ ] ) ,
221219 ccx,
222220 already_promoted : 0 ,
223221 } ;
@@ -254,8 +252,8 @@ impl<'a, 'tcx> std::ops::Deref for Validator<'a, 'tcx> {
254252struct Unpromotable ;
255253
256254impl < ' 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 ! ( ) } ;
259257 let Some ( ( place, rvalue @ Rvalue :: Aggregate ( box kind, operands) ) ) =
260258 statement. kind . as_assign ( )
261259 else {
@@ -780,18 +778,15 @@ impl<'tcx> Validator<'_, 'tcx> {
780778 }
781779}
782780
783- fn validate_candidates (
781+ fn validate_candidates < ' a > (
784782 ccx : & ConstCx < ' _ , ' _ > ,
785783 temps : & mut IndexSlice < Local , TempState > ,
786- candidates : & [ Candidate ] ,
787- ) -> Vec < Candidate > {
784+ candidates : & ' a mut Candidates ,
785+ ) -> & ' a mut Candidates {
788786 let mut validator = Validator { ccx, temps, promotion_safe_blocks : None } ;
789787
788+ candidates. 0 . retain ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) ) ;
790789 candidates
791- . iter ( )
792- . copied ( )
793- . filter ( |& candidate| validator. validate_candidate ( candidate) . is_ok ( ) )
794- . collect ( )
795790}
796791
797792struct Promoter < ' a , ' tcx > {
@@ -946,7 +941,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
946941 new_temp
947942 }
948943
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 > {
950945 let def = self . source . source . def_id ( ) ;
951946 let promoted_id = Promoted :: new ( next_promoted_id) ;
952947 let ( mut rvalue, promoted_op, promoted_ref_rvalue) = {
@@ -963,7 +958,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
963958
964959 let blocks = self . source . basic_blocks . as_mut ( ) ;
965960 let local_decls = & mut self . source . local_decls ;
966- let loc = candidate. location ;
961+ let loc = candidate;
967962 let statement = & mut blocks[ loc. block ] . statements [ loc. statement_index ] ;
968963 let StatementKind :: Assign ( box ( place, Rvalue :: Aggregate ( _kind, _operands) ) ) =
969964 & mut statement. kind
@@ -1017,7 +1012,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
10171012
10181013 {
10191014 let blocks = self . source . basic_blocks_mut ( ) ;
1020- let loc = candidate. location ;
1015+ let loc = candidate;
10211016 let statement = & mut blocks[ loc. block ] . statements [ loc. statement_index ] ;
10221017 if let StatementKind :: Assign ( box ( _place, ref mut rvalue) ) = & mut statement. kind {
10231018 * rvalue = promoted_rvalue;
@@ -1068,20 +1063,20 @@ fn promote_candidates<'tcx>(
10681063 body : & mut Body < ' tcx > ,
10691064 tcx : TyCtxt < ' tcx > ,
10701065 mut temps : IndexVec < Local , TempState > ,
1071- candidates : Vec < Candidate > ,
1066+ candidates : & Candidates ,
10721067 already_promoted : usize ,
10731068) -> IndexVec < Promoted , Body < ' tcx > > {
10741069 // eagerly fail fast
1075- if candidates. is_empty ( ) {
1070+ if candidates. 0 . is_empty ( ) {
10761071 return IndexVec :: new ( ) ;
10771072 }
10781073
10791074 let mut promotions = IndexVec :: new ( ) ;
10801075
10811076 let mut extra_statements = vec ! [ ] ;
10821077 // 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;
10851080 if let StatementKind :: Assign ( box ( place, _) ) = & body[ block] . statements [ statement_index] . kind
10861081 {
10871082 if let Some ( local) = place. as_local ( ) {
@@ -1095,7 +1090,7 @@ fn promote_candidates<'tcx>(
10951090 // Declare return place local so that `mir::Body::new` doesn't complain.
10961091 let initial_locals = IndexVec :: from ( [ LocalDecl :: new ( tcx. types . never , body. span ) ] ) ;
10971092
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 ( ) ;
10991094 scope. parent_scope = None ;
11001095
11011096 let mut promoted = Body :: new (
0 commit comments