Skip to content

Commit 830d65c

Browse files
committed
add StorageDead handling
1 parent f93a492 commit 830d65c

File tree

4 files changed

+59
-15
lines changed

4 files changed

+59
-15
lines changed

src/librustc_mir/dataflow/drop_flag_effects.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,13 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
231231
}
232232
}
233233
}
234+
mir::StatementKind::StorageDead(local) => {
235+
on_lookup_result_bits(tcx, mir, move_data,
236+
move_data.rev_lookup.find(&mir::Lvalue::Local(local)),
237+
|mpi| callback(mpi, DropFlagState::Absent))
238+
239+
}
234240
mir::StatementKind::StorageLive(_) |
235-
mir::StatementKind::StorageDead(_) |
236241
mir::StatementKind::InlineAsm { .. } |
237242
mir::StatementKind::EndRegion(_) |
238243
mir::StatementKind::Validate(..) |

src/librustc_mir/dataflow/impls/mod.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -456,14 +456,21 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
456456
let path_map = &move_data.path_map;
457457
let rev_lookup = &move_data.rev_lookup;
458458

459-
debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
460-
stmt, location, &loc_map[location]);
461-
for move_index in &loc_map[location] {
462-
// Every path deinitialized by a *particular move*
463-
// has corresponding bit, "gen'ed" (i.e. set)
464-
// here, in dataflow vector
465-
zero_to_one(sets.gen_set.words_mut(), *move_index);
459+
match stmt.kind {
460+
// skip move out for StorageDead
461+
mir::StatementKind::StorageDead(_) => {}
462+
_ => {
463+
debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
464+
stmt, location, &loc_map[location]);
465+
for move_index in &loc_map[location] {
466+
// Every path deinitialized by a *particular move*
467+
// has corresponding bit, "gen'ed" (i.e. set)
468+
// here, in dataflow vector
469+
zero_to_one(sets.gen_set.words_mut(), *move_index);
470+
}
471+
}
466472
}
473+
467474
let bits_per_block = self.bits_per_block();
468475
match stmt.kind {
469476
mir::StatementKind::SetDiscriminant { .. } => {

src/librustc_mir/dataflow/move_paths/builder.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,10 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
250250
}
251251
self.gather_rvalue(rval);
252252
}
253-
StatementKind::StorageLive(_) |
254-
StatementKind::StorageDead(_) => {}
253+
StatementKind::StorageLive(_) => {}
254+
StatementKind::StorageDead(local) => {
255+
self.gather_move(&Lvalue::Local(local), true);
256+
}
255257
StatementKind::SetDiscriminant{ .. } => {
256258
span_bug!(stmt.source_info.span,
257259
"SetDiscriminant should not exist during borrowck");
@@ -309,7 +311,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
309311
TerminatorKind::Unreachable => { }
310312

311313
TerminatorKind::Return => {
312-
self.gather_move(&Lvalue::Local(RETURN_POINTER));
314+
self.gather_move(&Lvalue::Local(RETURN_POINTER), false);
313315
}
314316

315317
TerminatorKind::Assert { .. } |
@@ -322,7 +324,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
322324
}
323325

324326
TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
325-
self.gather_move(location);
327+
self.gather_move(location, false);
326328
}
327329
TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
328330
self.create_move_path(location);
@@ -344,19 +346,19 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
344346
match *operand {
345347
Operand::Constant(..) => {} // not-a-move
346348
Operand::Consume(ref lval) => { // a move
347-
self.gather_move(lval);
349+
self.gather_move(lval, false);
348350
}
349351
}
350352
}
351353

352-
fn gather_move(&mut self, lval: &Lvalue<'tcx>) {
354+
fn gather_move(&mut self, lval: &Lvalue<'tcx>, force: bool) {
353355
debug!("gather_move({:?}, {:?})", self.loc, lval);
354356

355357
let tcx = self.builder.tcx;
356358
let gcx = tcx.global_tcx();
357359
let lv_ty = lval.ty(self.builder.mir, tcx).to_ty(tcx);
358360
let erased_ty = gcx.lift(&tcx.erase_regions(&lv_ty)).unwrap();
359-
if !erased_ty.moves_by_default(gcx, self.builder.param_env, DUMMY_SP) {
361+
if !force && !erased_ty.moves_by_default(gcx, self.builder.param_env, DUMMY_SP) {
360362
debug!("gather_move({:?}, {:?}) - {:?} is Copy. skipping", self.loc, lval, lv_ty);
361363
return
362364
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -Z emit-end-regions -Z borrowck-mir
12+
13+
fn ok() {
14+
loop {
15+
let _x = 1;
16+
}
17+
}
18+
19+
fn fail() {
20+
loop {
21+
let x: i32;
22+
let _ = x + 1; //~ERROR (Ast) [E0381]
23+
//~^ ERROR (Mir) [E0381]
24+
}
25+
}
26+
27+
fn main() {
28+
ok();
29+
fail();
30+
}

0 commit comments

Comments
 (0)