@@ -1755,7 +1755,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
17551755
17561756 fn visit_place ( & mut self , place : & mut Place < ' tcx > , context : PlaceContext , location : Location ) {
17571757 self . simplify_place_projection ( place, location) ;
1758- if context. is_mutating_use ( ) && ! place. projection . is_empty ( ) {
1758+ if context. is_mutating_use ( ) && place. is_indirect ( ) {
17591759 // Non-local mutation maybe invalidate deref.
17601760 self . invalidate_derefs ( ) ;
17611761 }
@@ -1767,36 +1767,41 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
17671767 self . super_operand ( operand, location) ;
17681768 }
17691769
1770- fn visit_statement ( & mut self , stmt : & mut Statement < ' tcx > , location : Location ) {
1771- if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
1772- self . simplify_place_projection ( lhs, location) ;
1773-
1774- let value = self . simplify_rvalue ( lhs, rvalue, location) ;
1775- let value = if let Some ( local) = lhs. as_local ( )
1776- && self . ssa . is_ssa ( local)
1777- // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
1778- // `local` as reusable if we have an exact type match.
1779- && self . local_decls [ local] . ty == rvalue. ty ( self . local_decls , self . tcx )
1770+ fn visit_assign (
1771+ & mut self ,
1772+ lhs : & mut Place < ' tcx > ,
1773+ rvalue : & mut Rvalue < ' tcx > ,
1774+ location : Location ,
1775+ ) {
1776+ self . simplify_place_projection ( lhs, location) ;
1777+
1778+ let value = self . simplify_rvalue ( lhs, rvalue, location) ;
1779+ if let Some ( value) = value {
1780+ if let Some ( const_) = self . try_as_constant ( value) {
1781+ * rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( const_) ) ) ;
1782+ } else if let Some ( place) = self . try_as_place ( value, location, false )
1783+ && * rvalue != Rvalue :: Use ( Operand :: Move ( place) )
1784+ && * rvalue != Rvalue :: Use ( Operand :: Copy ( place) )
17801785 {
1781- let value = value. unwrap_or_else ( || self . new_opaque ( ) ) ;
1782- self . assign ( local, value) ;
1783- Some ( value)
1784- } else {
1785- value
1786- } ;
1787- if let Some ( value) = value {
1788- if let Some ( const_) = self . try_as_constant ( value) {
1789- * rvalue = Rvalue :: Use ( Operand :: Constant ( Box :: new ( const_) ) ) ;
1790- } else if let Some ( place) = self . try_as_place ( value, location, false )
1791- && * rvalue != Rvalue :: Use ( Operand :: Move ( place) )
1792- && * rvalue != Rvalue :: Use ( Operand :: Copy ( place) )
1793- {
1794- * rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ;
1795- self . reused_locals . insert ( place. local ) ;
1796- }
1786+ * rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ;
1787+ self . reused_locals . insert ( place. local ) ;
17971788 }
17981789 }
1799- self . super_statement ( stmt, location) ;
1790+
1791+ if lhs. is_indirect ( ) {
1792+ // Non-local mutation maybe invalidate deref.
1793+ self . invalidate_derefs ( ) ;
1794+ }
1795+
1796+ if let Some ( local) = lhs. as_local ( )
1797+ && self . ssa . is_ssa ( local)
1798+ // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
1799+ // `local` as reusable if we have an exact type match.
1800+ && self . local_decls [ local] . ty == rvalue. ty ( self . local_decls , self . tcx )
1801+ {
1802+ let value = value. unwrap_or_else ( || self . new_opaque ( ) ) ;
1803+ self . assign ( local, value) ;
1804+ }
18001805 }
18011806
18021807 fn visit_terminator ( & mut self , terminator : & mut Terminator < ' tcx > , location : Location ) {
0 commit comments