Skip to content

Commit 5a16ef4

Browse files
committed
Made move_paths::MoveError take span param in cannot_move_out_of ctor.
Implicitly threaded `Location` through MoveData construction via a `Gatherer` struct (so that we could look up the span corresponding to the location when we need to signal an error).
1 parent 117586e commit 5a16ef4

File tree

2 files changed

+79
-48
lines changed

2 files changed

+79
-48
lines changed

src/librustc_mir/dataflow/move_paths/builder.rs

Lines changed: 76 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
8484
assert_eq!(path_map_ent, move_path);
8585
move_path
8686
}
87+
}
8788

89+
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
8890
/// This creates a MovePath for a given lvalue, returning an `MovePathError`
8991
/// if that lvalue can't be moved from.
9092
///
@@ -97,8 +99,11 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
9799
{
98100
debug!("lookup({:?})", lval);
99101
match *lval {
100-
Lvalue::Local(local) => Ok(self.data.rev_lookup.locals[local]),
101-
Lvalue::Static(..) => Err(MoveError::cannot_move_out_of(Static)),
102+
Lvalue::Local(local) => Ok(self.builder.data.rev_lookup.locals[local]),
103+
Lvalue::Static(..) => {
104+
let span = self.builder.mir.source_info(self.loc).span;
105+
Err(MoveError::cannot_move_out_of(span, Static))
106+
}
102107
Lvalue::Projection(ref proj) => {
103108
self.move_path_for_projection(lval, proj)
104109
}
@@ -117,41 +122,49 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
117122
-> Result<MovePathIndex, MoveError<'tcx>>
118123
{
119124
let base = try!(self.move_path_for(&proj.base));
120-
let lv_ty = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx);
125+
let mir = self.builder.mir;
126+
let tcx = self.builder.tcx;
127+
let lv_ty = proj.base.ty(mir, tcx).to_ty(tcx);
121128
match lv_ty.sty {
122129
ty::TyRef(..) | ty::TyRawPtr(..) =>
123-
return Err(MoveError::cannot_move_out_of(BorrowedContent)),
124-
ty::TyAdt(adt, _) if adt.has_dtor(self.tcx) && !adt.is_box() =>
125-
return Err(MoveError::cannot_move_out_of(InteriorOfTypeWithDestructor {
130+
return Err(MoveError::cannot_move_out_of(mir.source_info(self.loc).span,
131+
BorrowedContent)),
132+
ty::TyAdt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
133+
return Err(MoveError::cannot_move_out_of(mir.source_info(self.loc).span,
134+
InteriorOfTypeWithDestructor {
126135
container_ty: lv_ty
127136
})),
128137
// move out of union - always move the entire union
129138
ty::TyAdt(adt, _) if adt.is_union() =>
130139
return Err(MoveError::UnionMove { path: base }),
131140
ty::TySlice(elem_ty) =>
132-
return Err(MoveError::cannot_move_out_of(InteriorOfSlice {
133-
elem_ty, is_index: match proj.elem {
134-
ProjectionElem::Index(..) => true,
135-
_ => false
136-
},
137-
})),
141+
return Err(MoveError::cannot_move_out_of(
142+
mir.source_info(self.loc).span,
143+
InteriorOfSlice {
144+
elem_ty, is_index: match proj.elem {
145+
ProjectionElem::Index(..) => true,
146+
_ => false
147+
},
148+
})),
138149
ty::TyArray(elem_ty, _num_elems) => match proj.elem {
139150
ProjectionElem::Index(..) =>
140-
return Err(MoveError::cannot_move_out_of(InteriorOfArray {
141-
elem_ty, is_index: true
142-
})),
151+
return Err(MoveError::cannot_move_out_of(
152+
mir.source_info(self.loc).span,
153+
InteriorOfArray {
154+
elem_ty, is_index: true
155+
})),
143156
_ => {
144157
// FIXME: still badly broken
145158
}
146159
},
147160
_ => {}
148161
};
149-
match self.data.rev_lookup.projections.entry((base, proj.elem.lift())) {
162+
match self.builder.data.rev_lookup.projections.entry((base, proj.elem.lift())) {
150163
Entry::Occupied(ent) => Ok(*ent.get()),
151164
Entry::Vacant(ent) => {
152-
let path = Self::new_move_path(
153-
&mut self.data.move_paths,
154-
&mut self.data.path_map,
165+
let path = MoveDataBuilder::new_move_path(
166+
&mut self.builder.data.move_paths,
167+
&mut self.builder.data.path_map,
155168
Some(base),
156169
lval.clone()
157170
);
@@ -160,7 +173,9 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
160173
}
161174
}
162175
}
176+
}
163177

178+
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
164179
fn finalize(self) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<MoveError<'tcx>>)> {
165180
debug!("{}", {
166181
debug!("moves for {:?}:", self.mir.span);
@@ -208,6 +223,22 @@ pub(super) fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
208223
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
209224
fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) {
210225
debug!("gather_statement({:?}, {:?})", loc, stmt);
226+
(Gatherer { builder: self, loc }).gather_statement(stmt);
227+
}
228+
229+
fn gather_terminator(&mut self, loc: Location, term: &Terminator<'tcx>) {
230+
debug!("gather_terminator({:?}, {:?})", loc, term);
231+
(Gatherer { builder: self, loc }).gather_terminator(term);
232+
}
233+
}
234+
235+
struct Gatherer<'b, 'a: 'b, 'tcx: 'a> {
236+
builder: &'b mut MoveDataBuilder<'a, 'tcx>,
237+
loc: Location,
238+
}
239+
240+
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
241+
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
211242
match stmt.kind {
212243
StatementKind::Assign(ref lval, ref rval) => {
213244
self.create_move_path(lval);
@@ -217,7 +248,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
217248
// the exterior.
218249
self.create_move_path(&lval.clone().deref());
219250
}
220-
self.gather_rvalue(loc, rval);
251+
self.gather_rvalue(rval);
221252
}
222253
StatementKind::StorageLive(_) |
223254
StatementKind::StorageDead(_) => {}
@@ -232,22 +263,22 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
232263
}
233264
}
234265

235-
fn gather_rvalue(&mut self, loc: Location, rvalue: &Rvalue<'tcx>) {
266+
fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
236267
match *rvalue {
237268
Rvalue::Use(ref operand) |
238269
Rvalue::Repeat(ref operand, _) |
239270
Rvalue::Cast(_, ref operand, _) |
240271
Rvalue::UnaryOp(_, ref operand) => {
241-
self.gather_operand(loc, operand)
272+
self.gather_operand(operand)
242273
}
243274
Rvalue::BinaryOp(ref _binop, ref lhs, ref rhs) |
244275
Rvalue::CheckedBinaryOp(ref _binop, ref lhs, ref rhs) => {
245-
self.gather_operand(loc, lhs);
246-
self.gather_operand(loc, rhs);
276+
self.gather_operand(lhs);
277+
self.gather_operand(rhs);
247278
}
248279
Rvalue::Aggregate(ref _kind, ref operands) => {
249280
for operand in operands {
250-
self.gather_operand(loc, operand);
281+
self.gather_operand(operand);
251282
}
252283
}
253284
Rvalue::Ref(..) |
@@ -269,16 +300,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
269300
}
270301
}
271302

272-
fn gather_terminator(&mut self, loc: Location, term: &Terminator<'tcx>) {
273-
debug!("gather_terminator({:?}, {:?})", loc, term);
303+
fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
274304
match term.kind {
275305
TerminatorKind::Goto { target: _ } |
276306
TerminatorKind::Resume |
277307
TerminatorKind::GeneratorDrop |
278308
TerminatorKind::Unreachable => { }
279309

280310
TerminatorKind::Return => {
281-
self.gather_move(loc, &Lvalue::Local(RETURN_POINTER));
311+
self.gather_move(&Lvalue::Local(RETURN_POINTER));
282312
}
283313

284314
TerminatorKind::Assert { .. } |
@@ -287,20 +317,20 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
287317
}
288318

289319
TerminatorKind::Yield { ref value, .. } => {
290-
self.gather_operand(loc, value);
320+
self.gather_operand(value);
291321
}
292322

293323
TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
294-
self.gather_move(loc, location);
324+
self.gather_move(location);
295325
}
296326
TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
297327
self.create_move_path(location);
298-
self.gather_operand(loc, value);
328+
self.gather_operand(value);
299329
}
300330
TerminatorKind::Call { ref func, ref args, ref destination, cleanup: _ } => {
301-
self.gather_operand(loc, func);
331+
self.gather_operand(func);
302332
for arg in args {
303-
self.gather_operand(loc, arg);
333+
self.gather_operand(arg);
304334
}
305335
if let Some((ref destination, _bb)) = *destination {
306336
self.create_move_path(destination);
@@ -309,37 +339,38 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
309339
}
310340
}
311341

312-
fn gather_operand(&mut self, loc: Location, operand: &Operand<'tcx>) {
342+
fn gather_operand(&mut self, operand: &Operand<'tcx>) {
313343
match *operand {
314344
Operand::Constant(..) => {} // not-a-move
315345
Operand::Consume(ref lval) => { // a move
316-
self.gather_move(loc, lval);
346+
self.gather_move(lval);
317347
}
318348
}
319349
}
320350

321-
fn gather_move(&mut self, loc: Location, lval: &Lvalue<'tcx>) {
322-
debug!("gather_move({:?}, {:?})", loc, lval);
351+
fn gather_move(&mut self, lval: &Lvalue<'tcx>) {
352+
debug!("gather_move({:?}, {:?})", self.loc, lval);
323353

324-
let lv_ty = lval.ty(self.mir, self.tcx).to_ty(self.tcx);
325-
if !lv_ty.moves_by_default(self.tcx, self.param_env, DUMMY_SP) {
326-
debug!("gather_move({:?}, {:?}) - {:?} is Copy. skipping", loc, lval, lv_ty);
354+
let tcx = self.builder.tcx;
355+
let lv_ty = lval.ty(self.builder.mir, tcx).to_ty(tcx);
356+
if !lv_ty.moves_by_default(tcx, self.builder.param_env, DUMMY_SP) {
357+
debug!("gather_move({:?}, {:?}) - {:?} is Copy. skipping", self.loc, lval, lv_ty);
327358
return
328359
}
329360

330361
let path = match self.move_path_for(lval) {
331362
Ok(path) | Err(MoveError::UnionMove { path }) => path,
332363
Err(error @ MoveError::IllegalMove { .. }) => {
333-
self.errors.push(error);
364+
self.builder.errors.push(error);
334365
return;
335366
}
336367
};
337-
let move_out = self.data.moves.push(MoveOut { path: path, source: loc });
368+
let move_out = self.builder.data.moves.push(MoveOut { path: path, source: self.loc });
338369

339370
debug!("gather_move({:?}, {:?}): adding move {:?} of {:?}",
340-
loc, lval, move_out, path);
371+
self.loc, lval, move_out, path);
341372

342-
self.data.path_map[path].push(move_out);
343-
self.data.loc_map[loc].push(move_out);
373+
self.builder.data.path_map[path].push(move_out);
374+
self.builder.data.loc_map[self.loc].push(move_out);
344375
}
345376
}

src/librustc_mir/dataflow/move_paths/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc::ty::{self, TyCtxt};
1313
use rustc::mir::*;
1414
use rustc::util::nodemap::FxHashMap;
1515
use rustc_data_structures::indexed_vec::{IndexVec};
16-
use syntax_pos::{DUMMY_SP, Span};
16+
use syntax_pos::{Span};
1717

1818
use std::fmt;
1919
use std::ops::{Index, IndexMut};
@@ -250,8 +250,8 @@ pub enum MoveError<'tcx> {
250250
}
251251

252252
impl<'tcx> MoveError<'tcx> {
253-
fn cannot_move_out_of(kind: IllegalMoveOriginKind<'tcx>) -> Self {
254-
let origin = IllegalMoveOrigin { span: DUMMY_SP, kind: kind, };
253+
fn cannot_move_out_of(span: Span, kind: IllegalMoveOriginKind<'tcx>) -> Self {
254+
let origin = IllegalMoveOrigin { span, kind };
255255
MoveError::IllegalMove { cannot_move_out_of: origin }
256256
}
257257
}

0 commit comments

Comments
 (0)