Skip to content

Commit

Permalink
Auto merge of #45936 - mikhail-m1:mir-borrowck-storage-dead, r=arielb1
Browse files Browse the repository at this point in the history
add `StorageDead` handling

fix #45642
r? @arielb1
  • Loading branch information
bors committed Nov 15, 2017
2 parents ce2b8a4 + 9e35fd2 commit 88a28ff
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 28 deletions.
12 changes: 0 additions & 12 deletions src/librustc_mir/dataflow/drop_flag_effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use syntax_pos::DUMMY_SP;

use rustc::mir::{self, Mir, Location};
use rustc::ty::{self, TyCtxt};
use util::elaborate_drops::DropFlagState;
Expand Down Expand Up @@ -187,23 +185,13 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
where F: FnMut(MovePathIndex, DropFlagState)
{
let move_data = &ctxt.move_data;
let param_env = ctxt.param_env;
debug!("drop_flag_effects_for_location({:?})", loc);

// first, move out of the RHS
for mi in &move_data.loc_map[loc] {
let path = mi.move_path_index(move_data);
debug!("moving out of path {:?}", move_data.move_paths[path]);

// don't move out of non-Copy things
let lvalue = &move_data.move_paths[path].lvalue;
let ty = lvalue.ty(mir, tcx).to_ty(tcx);
let gcx = tcx.global_tcx();
let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
if !erased_ty.moves_by_default(gcx, param_env, DUMMY_SP) {
continue;
}

on_all_children_bits(tcx, mir, move_data,
path,
|mpi| callback(mpi, DropFlagState::Absent))
Expand Down
24 changes: 17 additions & 7 deletions src/librustc_mir/dataflow/impls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,14 +456,24 @@ 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 {
// this analysis only tries to find moves explicitly
// written by the user, so we ignore the move-outs
// created by `StorageDead` and at the beginning
// of a function.
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 { .. } => {
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_mir/dataflow/move_paths/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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 { .. } |
Expand All @@ -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);
Expand All @@ -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
}
Expand Down
30 changes: 30 additions & 0 deletions src/test/compile-fail/borrowck/borrowck-storage-dead.rs
Original file line number Diff line number Diff line change
@@ -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();
}
3 changes: 1 addition & 2 deletions src/test/compile-fail/issue-25579.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ enum Sexpression {

fn causes_ice(mut l: &mut Sexpression) {
loop { match l {
&mut Sexpression::Num(ref mut n) => {}, //[mir]~ ERROR (Mir) [E0384]
&mut Sexpression::Num(ref mut n) => {},
&mut Sexpression::Cons(ref mut expr) => { //[ast]~ ERROR [E0499]
//[mir]~^ ERROR (Ast) [E0499]
//[mir]~| ERROR (Mir) [E0506]
//[mir]~| ERROR (Mir) [E0384]
//[mir]~| ERROR (Mir) [E0499]
l = &mut **expr; //[ast]~ ERROR [E0506]
//[mir]~^ ERROR (Ast) [E0506]
Expand Down

0 comments on commit 88a28ff

Please sign in to comment.