@@ -1755,7 +1755,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1755
1755
1756
1756
fn visit_place ( & mut self , place : & mut Place < ' tcx > , context : PlaceContext , location : Location ) {
1757
1757
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 ( ) {
1759
1759
// Non-local mutation maybe invalidate deref.
1760
1760
self . invalidate_derefs ( ) ;
1761
1761
}
@@ -1767,36 +1767,41 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1767
1767
self . super_operand ( operand, location) ;
1768
1768
}
1769
1769
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) )
1780
1785
{
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 ) ;
1797
1788
}
1798
1789
}
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
+ }
1800
1805
}
1801
1806
1802
1807
fn visit_terminator ( & mut self , terminator : & mut Terminator < ' tcx > , location : Location ) {
0 commit comments