Skip to content

Commit c6673db

Browse files
authored
Auto merge of #36353 - arielb1:union-drops, r=pnkfelix
a few move-checker improvements This fixes moves out of unions and prohibits moves out of slices (see the individual commits). r? @pnkfelix
2 parents 8394685 + 5c5f752 commit c6673db

File tree

16 files changed

+562
-729
lines changed

16 files changed

+562
-729
lines changed

src/librustc/mir/repr.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> {
12431243
type Iter = IntoIter<BasicBlock>;
12441244
}
12451245

1246-
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
1246+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
12471247
pub struct Location {
12481248
/// the location is within this block
12491249
pub block: BasicBlock,
@@ -1253,3 +1253,8 @@ pub struct Location {
12531253
pub statement_index: usize,
12541254
}
12551255

1256+
impl fmt::Debug for Location {
1257+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1258+
write!(fmt, "{:?}[{}]", self.block, self.statement_index)
1259+
}
1260+
}

src/librustc/mir/visit.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -774,9 +774,6 @@ pub enum LvalueContext<'tcx> {
774774
// Being borrowed
775775
Borrow { region: &'tcx Region, kind: BorrowKind },
776776

777-
// Being sliced -- this should be same as being borrowed, probably
778-
Slice { from_start: usize, from_end: usize },
779-
780777
// Used as base for another lvalue, e.g. `x` in `x.y`
781778
Projection,
782779

src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
185185
check_and_get_illegal_move_origin(bccx, b)
186186
}
187187
}
188+
ty::TySlice(..) => Some(cmt.clone()),
188189
_ => {
189190
check_and_get_illegal_move_origin(bccx, b)
190191
}

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc::ty;
1616
use syntax::ast;
1717
use syntax_pos;
1818
use errors::DiagnosticBuilder;
19-
use rustc::hir;
2019

2120
pub struct MoveErrorCollector<'tcx> {
2221
errors: Vec<MoveError<'tcx>>
@@ -131,17 +130,20 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
131130
err
132131
}
133132

134-
Categorization::Interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
135-
let expr = bccx.tcx.map.expect_expr(move_from.id);
136-
if let hir::ExprIndex(..) = expr.node {
137-
let mut err = struct_span_err!(bccx, move_from.span, E0508,
138-
"cannot move out of type `{}`, \
139-
a non-copy fixed-size array",
140-
b.ty);
141-
err.span_label(move_from.span, &format!("cannot move out of here"));
142-
err
143-
} else {
144-
span_bug!(move_from.span, "this path should not cause illegal move");
133+
Categorization::Interior(ref b, mc::InteriorElement(ik, _)) => {
134+
match (&b.ty.sty, ik) {
135+
(&ty::TySlice(..), _) |
136+
(_, Kind::Index) => {
137+
let mut err = struct_span_err!(bccx, move_from.span, E0508,
138+
"cannot move out of type `{}`, \
139+
a non-copy array",
140+
b.ty);
141+
err.span_label(move_from.span, &format!("cannot move out of here"));
142+
err
143+
}
144+
(_, Kind::Pattern) => {
145+
span_bug!(move_from.span, "this path should not cause illegal move");
146+
}
145147
}
146148
}
147149

src/librustc_borrowck/borrowck/mir/dataflow/impls.rs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use super::super::MoveDataParamEnv;
1717
use super::super::DropFlagState;
1818
use super::super::drop_flag_effects_for_function_entry;
1919
use super::super::drop_flag_effects_for_location;
20-
use super::super::on_all_children_bits;
20+
use super::super::on_lookup_result_bits;
2121

2222
use super::{BitDenotation, BlockSets, DataflowOperator};
2323

@@ -277,10 +277,9 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
277277
dest_lval: &repr::Lvalue) {
278278
// when a call returns successfully, that means we need to set
279279
// the bits for that dest_lval to 1 (initialized).
280-
let move_path_index = ctxt.move_data.rev_lookup.find(dest_lval);
281-
on_all_children_bits(self.tcx, self.mir, &ctxt.move_data,
282-
move_path_index,
283-
|mpi| { in_out.add(&mpi); });
280+
on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
281+
ctxt.move_data.rev_lookup.find(dest_lval),
282+
|mpi| { in_out.add(&mpi); });
284283
}
285284
}
286285

@@ -338,11 +337,10 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
338337
_dest_bb: repr::BasicBlock,
339338
dest_lval: &repr::Lvalue) {
340339
// when a call returns successfully, that means we need to set
341-
// the bits for that dest_lval to 1 (initialized).
342-
let move_path_index = ctxt.move_data.rev_lookup.find(dest_lval);
343-
on_all_children_bits(self.tcx, self.mir, &ctxt.move_data,
344-
move_path_index,
345-
|mpi| { in_out.remove(&mpi); });
340+
// the bits for that dest_lval to 0 (initialized).
341+
on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
342+
ctxt.move_data.rev_lookup.find(dest_lval),
343+
|mpi| { in_out.remove(&mpi); });
346344
}
347345
}
348346

@@ -400,10 +398,9 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
400398
dest_lval: &repr::Lvalue) {
401399
// when a call returns successfully, that means we need to set
402400
// the bits for that dest_lval to 1 (initialized).
403-
let move_path_index = ctxt.move_data.rev_lookup.find(dest_lval);
404-
on_all_children_bits(self.tcx, self.mir, &ctxt.move_data,
405-
move_path_index,
406-
|mpi| { in_out.add(&mpi); });
401+
on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
402+
ctxt.move_data.rev_lookup.find(dest_lval),
403+
|mpi| { in_out.add(&mpi); });
407404
}
408405
}
409406

@@ -448,11 +445,10 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
448445
// assigning into this `lvalue` kills all
449446
// MoveOuts from it, and *also* all MoveOuts
450447
// for children and associated fragment sets.
451-
let move_path_index = rev_lookup.find(lvalue);
452-
on_all_children_bits(tcx,
448+
on_lookup_result_bits(tcx,
453449
mir,
454450
move_data,
455-
move_path_index,
451+
rev_lookup.find(lvalue),
456452
|mpi| for moi in &path_map[mpi] {
457453
assert!(moi.index() < bits_per_block);
458454
sets.kill_set.add(&moi);
@@ -489,18 +485,17 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
489485
_dest_bb: repr::BasicBlock,
490486
dest_lval: &repr::Lvalue) {
491487
let move_data = &ctxt.move_data;
492-
let move_path_index = move_data.rev_lookup.find(dest_lval);
493488
let bits_per_block = self.bits_per_block(ctxt);
494489

495490
let path_map = &move_data.path_map;
496-
on_all_children_bits(self.tcx,
497-
self.mir,
498-
move_data,
499-
move_path_index,
500-
|mpi| for moi in &path_map[mpi] {
501-
assert!(moi.index() < bits_per_block);
502-
in_out.remove(&moi);
503-
});
491+
on_lookup_result_bits(self.tcx,
492+
self.mir,
493+
move_data,
494+
move_data.rev_lookup.find(dest_lval),
495+
|mpi| for moi in &path_map[mpi] {
496+
assert!(moi.index() < bits_per_block);
497+
in_out.remove(&moi);
498+
});
504499
}
505500
}
506501

src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc::ty::{self, TyCtxt};
1616
use rustc::mir::repr::{self, Mir};
1717
use rustc_data_structures::indexed_vec::Idx;
1818

19-
use super::super::gather_moves::{MovePathIndex};
19+
use super::super::gather_moves::{MovePathIndex, LookupResult};
2020
use super::super::MoveDataParamEnv;
2121
use super::BitDenotation;
2222
use super::DataflowResults;
@@ -116,20 +116,26 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
116116
repr::BorrowKind::Shared,
117117
ref peeking_at_lval) = *rvalue {
118118
// Okay, our search is over.
119-
let peek_mpi = move_data.rev_lookup.find(peeking_at_lval);
120-
let bit_state = sets.on_entry.contains(&peek_mpi);
121-
debug!("rustc_peek({:?} = &{:?}) bit_state: {}",
122-
lvalue, peeking_at_lval, bit_state);
123-
if !bit_state {
124-
tcx.sess.span_err(span, &format!("rustc_peek: bit not set"));
119+
match move_data.rev_lookup.find(peeking_at_lval) {
120+
LookupResult::Exact(peek_mpi) => {
121+
let bit_state = sets.on_entry.contains(&peek_mpi);
122+
debug!("rustc_peek({:?} = &{:?}) bit_state: {}",
123+
lvalue, peeking_at_lval, bit_state);
124+
if !bit_state {
125+
tcx.sess.span_err(span, "rustc_peek: bit not set");
126+
}
127+
}
128+
LookupResult::Parent(..) => {
129+
tcx.sess.span_err(span, "rustc_peek: argument untracked");
130+
}
125131
}
126132
return;
127133
} else {
128134
// Our search should have been over, but the input
129135
// does not match expectations of `rustc_peek` for
130136
// this sanity_check.
131-
let msg = &format!("rustc_peek: argument expression \
132-
must be immediate borrow of form `&expr`");
137+
let msg = "rustc_peek: argument expression \
138+
must be immediate borrow of form `&expr`";
133139
tcx.sess.span_err(span, msg);
134140
}
135141
}

0 commit comments

Comments
 (0)