add StorageDead
handling
This commit is contained in:
parent
f93a4928c2
commit
830d65c1ff
@ -231,8 +231,13 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
|
||||
}
|
||||
}
|
||||
}
|
||||
mir::StatementKind::StorageDead(local) => {
|
||||
on_lookup_result_bits(tcx, mir, move_data,
|
||||
move_data.rev_lookup.find(&mir::Lvalue::Local(local)),
|
||||
|mpi| callback(mpi, DropFlagState::Absent))
|
||||
|
||||
}
|
||||
mir::StatementKind::StorageLive(_) |
|
||||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::InlineAsm { .. } |
|
||||
mir::StatementKind::EndRegion(_) |
|
||||
mir::StatementKind::Validate(..) |
|
||||
|
@ -456,14 +456,21 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
|
||||
let path_map = &move_data.path_map;
|
||||
let rev_lookup = &move_data.rev_lookup;
|
||||
|
||||
debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
|
||||
stmt, location, &loc_map[location]);
|
||||
for move_index in &loc_map[location] {
|
||||
// Every path deinitialized by a *particular move*
|
||||
// has corresponding bit, "gen'ed" (i.e. set)
|
||||
// here, in dataflow vector
|
||||
zero_to_one(sets.gen_set.words_mut(), *move_index);
|
||||
match stmt.kind {
|
||||
// skip move out for StorageDead
|
||||
mir::StatementKind::StorageDead(_) => {}
|
||||
_ => {
|
||||
debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
|
||||
stmt, location, &loc_map[location]);
|
||||
for move_index in &loc_map[location] {
|
||||
// Every path deinitialized by a *particular move*
|
||||
// has corresponding bit, "gen'ed" (i.e. set)
|
||||
// here, in dataflow vector
|
||||
zero_to_one(sets.gen_set.words_mut(), *move_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let bits_per_block = self.bits_per_block();
|
||||
match stmt.kind {
|
||||
mir::StatementKind::SetDiscriminant { .. } => {
|
||||
|
@ -250,8 +250,10 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
}
|
||||
self.gather_rvalue(rval);
|
||||
}
|
||||
StatementKind::StorageLive(_) |
|
||||
StatementKind::StorageDead(_) => {}
|
||||
StatementKind::StorageLive(_) => {}
|
||||
StatementKind::StorageDead(local) => {
|
||||
self.gather_move(&Lvalue::Local(local), true);
|
||||
}
|
||||
StatementKind::SetDiscriminant{ .. } => {
|
||||
span_bug!(stmt.source_info.span,
|
||||
"SetDiscriminant should not exist during borrowck");
|
||||
@ -309,7 +311,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
TerminatorKind::Unreachable => { }
|
||||
|
||||
TerminatorKind::Return => {
|
||||
self.gather_move(&Lvalue::Local(RETURN_POINTER));
|
||||
self.gather_move(&Lvalue::Local(RETURN_POINTER), false);
|
||||
}
|
||||
|
||||
TerminatorKind::Assert { .. } |
|
||||
@ -322,7 +324,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
|
||||
self.gather_move(location);
|
||||
self.gather_move(location, false);
|
||||
}
|
||||
TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
|
||||
self.create_move_path(location);
|
||||
@ -344,19 +346,19 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
match *operand {
|
||||
Operand::Constant(..) => {} // not-a-move
|
||||
Operand::Consume(ref lval) => { // a move
|
||||
self.gather_move(lval);
|
||||
self.gather_move(lval, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_move(&mut self, lval: &Lvalue<'tcx>) {
|
||||
fn gather_move(&mut self, lval: &Lvalue<'tcx>, force: bool) {
|
||||
debug!("gather_move({:?}, {:?})", self.loc, lval);
|
||||
|
||||
let tcx = self.builder.tcx;
|
||||
let gcx = tcx.global_tcx();
|
||||
let lv_ty = lval.ty(self.builder.mir, tcx).to_ty(tcx);
|
||||
let erased_ty = gcx.lift(&tcx.erase_regions(&lv_ty)).unwrap();
|
||||
if !erased_ty.moves_by_default(gcx, self.builder.param_env, DUMMY_SP) {
|
||||
if !force && !erased_ty.moves_by_default(gcx, self.builder.param_env, DUMMY_SP) {
|
||||
debug!("gather_move({:?}, {:?}) - {:?} is Copy. skipping", self.loc, lval, lv_ty);
|
||||
return
|
||||
}
|
||||
|
30
src/test/compile-fail/borrowck/borrowck-storage-dead.rs
Normal file
30
src/test/compile-fail/borrowck/borrowck-storage-dead.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Z emit-end-regions -Z borrowck-mir
|
||||
|
||||
fn ok() {
|
||||
loop {
|
||||
let _x = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn fail() {
|
||||
loop {
|
||||
let x: i32;
|
||||
let _ = x + 1; //~ERROR (Ast) [E0381]
|
||||
//~^ ERROR (Mir) [E0381]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
ok();
|
||||
fail();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user