@@ -585,9 +585,29 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
585
585
sets. gen_all ( & init_loc_map[ location] ) ;
586
586
587
587
match stmt. kind {
588
- mir:: StatementKind :: StorageDead ( local) => {
589
- // End inits for StorageDead, so that an immutable variable can
590
- // be reinitialized on the next iteration of the loop.
588
+ mir:: StatementKind :: StorageDead ( local) |
589
+ mir:: StatementKind :: StorageLive ( local) => {
590
+ // End inits for StorageDead and StorageLive, so that an immutable
591
+ // variable can be reinitialized on the next iteration of the loop.
592
+ //
593
+ // FIXME(#46525): We *need* to do this for StorageLive as well as
594
+ // StorageDead, because lifetimes of match bindings with guards are
595
+ // weird - i.e. this code
596
+ //
597
+ // ```
598
+ // fn main() {
599
+ // match 0 {
600
+ // a | a
601
+ // if { println!("a={}", a); false } => {}
602
+ // _ => {}
603
+ // }
604
+ // }
605
+ // ```
606
+ //
607
+ // runs the guard twice, using the same binding for `a`, and only
608
+ // storagedeads after everything ends, so if we don't regard the
609
+ // storagelive as killing storage, we would have a multiple assignment
610
+ // to immutable data error.
591
611
if let LookupResult :: Exact ( mpi) = rev_lookup. find ( & mir:: Place :: Local ( local) ) {
592
612
debug ! ( "stmt {:?} at loc {:?} clears the ever initialized status of {:?}" ,
593
613
stmt, location, & init_path_map[ mpi] ) ;
0 commit comments