@@ -58,9 +58,10 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
5858 }
5959
6060 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) ;
6262
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 [ ..] ;
6465
6566 let promoted = promote_candidates ( body, tcx, temps, promotable_candidates) ;
6667 self . promoted_fragments . set ( promoted) ;
@@ -83,18 +84,16 @@ enum TempState {
8384 PromotedOut ,
8485}
8586
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 > ) ;
9392
9493struct Collector < ' a , ' tcx > {
9594 ccx : & ' a ConstCx < ' a , ' tcx > ,
9695 temps : IndexVec < Local , TempState > ,
97- candidates : Vec < Candidate > ,
96+ candidates : Candidates ,
9897}
9998
10099impl < ' tcx > Visitor < ' tcx > for Collector < ' _ , ' tcx > {
@@ -141,24 +140,23 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
141140 }
142141 TempState :: Unpromotable | TempState :: PromotedOut => TempState :: Unpromotable ,
143142 } ;
144- debug ! ( ?temp) ;
145143 }
146144
147145 fn visit_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
148146 self . super_rvalue ( rvalue, location) ;
149147
150148 if let Rvalue :: Ref ( ..) = * rvalue {
151- self . candidates . push ( Candidate { location } ) ;
149+ self . candidates . 0 . push ( location) ;
152150 }
153151 }
154152}
155153
156154fn collect_temps_and_candidates < ' tcx > (
157155 ccx : & ConstCx < ' _ , ' tcx > ,
158- ) -> ( IndexVec < Local , TempState > , Vec < Candidate > ) {
156+ ) -> ( IndexVec < Local , TempState > , Candidates ) {
159157 let mut collector = Collector {
160158 temps : IndexVec :: from_elem ( TempState :: Undefined , & ccx. body . local_decls ) ,
161- candidates : vec ! [ ] ,
159+ candidates : Candidates ( vec ! [ ] ) ,
162160 ccx,
163161 } ;
164162 for ( bb, data) in traversal:: reverse_postorder ( ccx. body ) {
@@ -192,8 +190,8 @@ impl<'a, 'tcx> std::ops::Deref for Validator<'a, 'tcx> {
192190struct Unpromotable ;
193191
194192impl < ' 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 ! ( ) } ;
197195 let Some ( ( _, Rvalue :: Ref ( _, kind, place) ) ) = statement. kind . as_assign ( ) else { bug ! ( ) } ;
198196
199197 // We can only promote interior borrows of promotable temps (non-temps
@@ -691,15 +689,11 @@ impl<'tcx> Validator<'_, 'tcx> {
691689fn validate_candidates (
692690 ccx : & ConstCx < ' _ , ' _ > ,
693691 temps : & mut IndexSlice < Local , TempState > ,
694- candidates : & [ Candidate ] ,
695- ) -> Vec < Candidate > {
692+ candidates : & mut Candidates ,
693+ ) {
696694 let mut validator = Validator { ccx, temps, promotion_safe_blocks : None } ;
697695
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 ( ) ) ;
703697}
704698
705699struct Promoter < ' a , ' tcx > {
@@ -854,7 +848,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
854848 new_temp
855849 }
856850
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 > {
858852 let def = self . source . source . def_id ( ) ;
859853 let ( mut rvalue, promoted_op) = {
860854 let promoted = & mut self . promoted ;
@@ -871,7 +865,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
871865
872866 let blocks = self . source . basic_blocks . as_mut ( ) ;
873867 let local_decls = & mut self . source . local_decls ;
874- let loc = candidate. location ;
868+ let loc = candidate;
875869 let statement = & mut blocks[ loc. block ] . statements [ loc. statement_index ] ;
876870 let StatementKind :: Assign ( box ( _, Rvalue :: Ref ( region, borrow_kind, place) ) ) =
877871 & mut statement. kind
@@ -965,7 +959,7 @@ fn promote_candidates<'tcx>(
965959 body : & mut Body < ' tcx > ,
966960 tcx : TyCtxt < ' tcx > ,
967961 mut temps : IndexVec < Local , TempState > ,
968- candidates : Vec < Candidate > ,
962+ candidates : & [ Location ] ,
969963) -> IndexVec < Promoted , Body < ' tcx > > {
970964 // Visit candidates in reverse, in case they're nested.
971965 debug ! ( promote_candidates = ?candidates) ;
@@ -978,8 +972,8 @@ fn promote_candidates<'tcx>(
978972 let mut promotions = IndexVec :: new ( ) ;
979973
980974 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;
983977 if let StatementKind :: Assign ( box ( place, _) ) = & body[ block] . statements [ statement_index] . kind
984978 {
985979 if let Some ( local) = place. as_local ( ) {
@@ -993,7 +987,7 @@ fn promote_candidates<'tcx>(
993987 // Declare return place local so that `mir::Body::new` doesn't complain.
994988 let initial_locals = iter:: once ( LocalDecl :: new ( tcx. types . never , body. span ) ) . collect ( ) ;
995989
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 ( ) ;
997991 scope. parent_scope = None ;
998992
999993 let mut promoted = Body :: new (
0 commit comments