work around weird match arm lifetimes

This commit is contained in:
Ariel Ben-Yehuda 2017-12-06 02:10:24 +02:00
parent 66c032cb2d
commit 9d3558725b
2 changed files with 24 additions and 3 deletions

View File

@ -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]);

View File

@ -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