From 9d3558725b9110beaa6740e88847e3addc9c2d0d Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 6 Dec 2017 02:10:24 +0200 Subject: [PATCH] work around weird match arm lifetimes --- src/librustc_mir/dataflow/impls/mod.rs | 26 ++++++++++++++++++++++--- src/test/run-pass/match-pipe-binding.rs | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index e7a25c212c367..db8ca0628c4ed 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -585,9 +585,29 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> { sets.gen_all(&init_loc_map[location]); match stmt.kind { - mir::StatementKind::StorageDead(local) => { - // End inits for StorageDead, so that an immutable variable can - // be reinitialized on the next iteration of the loop. + mir::StatementKind::StorageDead(local) | + mir::StatementKind::StorageLive(local) => { + // End inits for StorageDead and StorageLive, so that an immutable + // variable can be reinitialized on the next iteration of the loop. + // + // FIXME(#46525): We *need* to do this for StorageLive as well as + // StorageDead, because lifetimes of match bindings with guards are + // weird - i.e. this code + // + // ``` + // fn main() { + // match 0 { + // a | a + // if { println!("a={}", a); false } => {} + // _ => {} + // } + // } + // ``` + // + // runs the guard twice, using the same binding for `a`, and only + // storagedeads after everything ends, so if we don't regard the + // storagelive as killing storage, we would have a multiple assignment + // to immutable data error. if let LookupResult::Exact(mpi) = rev_lookup.find(&mir::Place::Local(local)) { debug!("stmt {:?} at loc {:?} clears the ever initialized status of {:?}", stmt, location, &init_path_map[mpi]); diff --git a/src/test/run-pass/match-pipe-binding.rs b/src/test/run-pass/match-pipe-binding.rs index bda90d3aaecb4..9592da77a1b58 100644 --- a/src/test/run-pass/match-pipe-binding.rs +++ b/src/test/run-pass/match-pipe-binding.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z borrowck=compare fn test1() { // from issue 6338