@@ -895,18 +895,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
895895
896896    fn  simplify_aggregate_to_copy ( 
897897        & mut  self , 
898-         lhs :  & Place < ' tcx > , 
899-         rvalue :  & mut  Rvalue < ' tcx > , 
900-         location :  Location , 
901-         fields :  & [ VnIndex ] , 
898+         ty :  Ty < ' tcx > , 
902899        variant_index :  VariantIdx , 
900+         fields :  & [ VnIndex ] , 
903901    )  -> Option < VnIndex >  { 
904-         let  Some ( & first_field)  = fields. first ( )  else  { 
905-             return  None ; 
906-         } ; 
907-         let  Value :: Projection ( copy_from_value,  _)  = * self . get ( first_field)  else  { 
908-             return  None ; 
909-         } ; 
902+         let  Some ( & first_field)  = fields. first ( )  else  {  return  None  } ; 
903+         let  Value :: Projection ( copy_from_value,  _)  = * self . get ( first_field)  else  {  return  None  } ; 
904+ 
910905        // All fields must correspond one-to-one and come from the same aggregate value. 
911906        if  fields. iter ( ) . enumerate ( ) . any ( |( index,  & v) | { 
912907            if  let  Value :: Projection ( pointer,  ProjectionElem :: Field ( from_index,  _) )  = * self . get ( v) 
@@ -933,21 +928,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
933928            } 
934929        } 
935930
936-         // Allow introducing places with non-constant offsets, as those are still better than 
937-         // reconstructing an aggregate. 
938-         if  self . ty ( copy_from_local_value)  == rvalue. ty ( self . local_decls ,  self . tcx ) 
939-             && let  Some ( place)  = self . try_as_place ( copy_from_local_value,  location,  true ) 
940-         { 
941-             // Avoid creating `*a = copy (*b)`, as they might be aliases resulting in overlapping assignments. 
942-             // FIXME: This also avoids any kind of projection, not just derefs. We can add allowed projections. 
943-             if  lhs. as_local ( ) . is_some ( )  { 
944-                 self . reused_locals . insert ( place. local ) ; 
945-                 * rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ; 
946-             } 
947-             return  Some ( copy_from_local_value) ; 
948-         } 
949- 
950-         None 
931+         // Both must be variants of the same type. 
932+         if  self . ty ( copy_from_local_value)  == ty {  Some ( copy_from_local_value)  }  else  {  None  } 
951933    } 
952934
953935    fn  simplify_aggregate ( 
@@ -1034,9 +1016,16 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10341016            } 
10351017        } 
10361018
1037-         if  let  Some ( value)  =
1038-             self . simplify_aggregate_to_copy ( lhs,  rvalue,  location,  & fields,  variant_index) 
1039-         { 
1019+         if  let  Some ( value)  = self . simplify_aggregate_to_copy ( ty,  variant_index,  & fields)  { 
1020+             // Allow introducing places with non-constant offsets, as those are still better than 
1021+             // reconstructing an aggregate. But avoid creating `*a = copy (*b)`, as they might be 
1022+             // aliases resulting in overlapping assignments. 
1023+             let  allow_complex_projection =
1024+                 lhs. projection [ ..] . iter ( ) . all ( PlaceElem :: is_stable_offset) ; 
1025+             if  let  Some ( place)  = self . try_as_place ( value,  location,  allow_complex_projection)  { 
1026+                 self . reused_locals . insert ( place. local ) ; 
1027+                 * rvalue = Rvalue :: Use ( Operand :: Copy ( place) ) ; 
1028+             } 
10401029            return  Some ( value) ; 
10411030        } 
10421031
0 commit comments