@@ -590,8 +590,12 @@ fn save_as_intervals<'tcx>(
590
590
twostep = TwoStepIndex :: from_u32 ( twostep. as_u32 ( ) + 1 ) ;
591
591
debug_assert_eq ! ( twostep, two_step_loc( loc, Effect :: After ) ) ;
592
592
append_at ( & mut values, & state, twostep) ;
593
- // Ensure we have a non-zero live range even for dead stores. This is done by marking
594
- // all the written-to locals as live in the second half of the statement.
593
+ // Like terminators, ensure we have a non-zero live range even for dead stores.
594
+ // Some rvalues interleave reads and writes, for instance `Rvalue::Aggregate`, see
595
+ // https://github.com/rust-lang/rust/issues/146383. By precaution, treat statements
596
+ // as behaving so by default.
597
+ // We make an exception for simple assignments `_a.stuff = {copy|move} _b.stuff`,
598
+ // as marking `_b` live here would prevent unification.
595
599
let is_simple_assignment =
596
600
matches ! ( stmt. kind, StatementKind :: Assign ( box ( _, Rvalue :: Use ( _) ) ) ) ;
597
601
VisitPlacesWith ( |place : Place < ' tcx > , ctxt| {
@@ -600,10 +604,12 @@ fn save_as_intervals<'tcx>(
600
604
DefUse :: Def | DefUse :: PartialWrite => {
601
605
values. insert ( relevant, twostep) ;
602
606
}
603
- DefUse :: Use if !is_simple_assignment => {
604
- values. insert ( relevant, twostep) ;
607
+ DefUse :: Use => {
608
+ if !is_simple_assignment {
609
+ values. insert ( relevant, twostep) ;
610
+ }
605
611
}
606
- DefUse :: Use | DefUse :: NonUse => { }
612
+ DefUse :: NonUse => { }
607
613
}
608
614
}
609
615
} )
0 commit comments