@@ -596,6 +596,28 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
596
596
fn should_const_prop ( & self ) -> bool {
597
597
self . tcx . sess . opts . debugging_opts . mir_opt_level >= 2
598
598
}
599
+
600
+ fn should_const_prop_local ( & self , local : Local , rval : & Rvalue < ' tcx > ) -> bool {
601
+ trace ! ( "should_const_prop(local={:?}, rval={:?})" , local, rval) ;
602
+ if self . can_const_prop [ local] {
603
+ return true ;
604
+ }
605
+
606
+ // if we should not actually perform const propagation, then we're done
607
+ if !self . should_const_prop ( ) {
608
+ return false ;
609
+ }
610
+
611
+ // if `rval` is a read of a local that we already propagated into,
612
+ // then we can also propagate it
613
+ if let Rvalue :: Use ( Operand :: Move ( Place :: Projection ( proj) ) ) = rval {
614
+ if let Place :: Base ( PlaceBase :: Local ( l) ) = & proj. base {
615
+ return self . places [ * l] . is_some ( )
616
+ }
617
+ }
618
+
619
+ false
620
+ }
599
621
}
600
622
601
623
fn type_size_of < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
@@ -692,7 +714,7 @@ impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
692
714
if let Some ( value) = self . const_prop ( rval, place_layout, statement. source_info ) {
693
715
if let Place :: Base ( PlaceBase :: Local ( local) ) = * place {
694
716
trace ! ( "checking whether {:?} can be stored to {:?}" , value, local) ;
695
- if self . can_const_prop [ local] {
717
+ if self . should_const_prop_local ( local, rval ) {
696
718
trace ! ( "storing {:?} to {:?}" , value, local) ;
697
719
assert ! ( self . places[ local] . is_none( ) ) ;
698
720
self . places [ local] = Some ( value) ;
0 commit comments