Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c2afca3

Browse files
committedAug 31, 2018
Auto merge of #53403 - spastorino:move-out-lazily, r=nikomatsakis
Do not used Move data flow analysis, make it lazy instead Close #53394
2 parents 1114ab6 + a6aa5dd commit c2afca3

File tree

7 files changed

+172
-234
lines changed

7 files changed

+172
-234
lines changed
 

‎src/librustc/mir/mod.rs

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ use hir::def::CtorKind;
1717
use hir::def_id::DefId;
1818
use hir::{self, HirId, InlineAsm};
1919
use middle::region;
20-
use mir::interpret::{EvalErrorKind, Scalar, ScalarMaybeUndef, ConstValue};
20+
use mir::interpret::{ConstValue, EvalErrorKind, Scalar, ScalarMaybeUndef};
2121
use mir::visit::MirVisitable;
2222
use rustc_apfloat::ieee::{Double, Single};
2323
use rustc_apfloat::Float;
2424
use rustc_data_structures::graph::dominators::{dominators, Dominators};
2525
use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
2626
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
27-
use smallvec::SmallVec;
2827
use rustc_data_structures::sync::Lrc;
2928
use rustc_data_structures::sync::ReadGuard;
3029
use rustc_serialize as serialize;
30+
use smallvec::SmallVec;
3131
use std::borrow::Cow;
3232
use std::fmt::{self, Debug, Formatter, Write};
3333
use std::ops::{Index, IndexMut};
@@ -203,6 +203,35 @@ impl<'tcx> Mir<'tcx> {
203203
ReadGuard::map(self.predecessors(), |p| &p[bb])
204204
}
205205

206+
#[inline]
207+
pub fn predecessor_locations(&self, loc: Location) -> impl Iterator<Item = Location> + '_ {
208+
let if_zero_locations = if loc.statement_index == 0 {
209+
let predecessor_blocks = self.predecessors_for(loc.block);
210+
let num_predecessor_blocks = predecessor_blocks.len();
211+
Some(
212+
(0..num_predecessor_blocks)
213+
.map(move |i| predecessor_blocks[i])
214+
.map(move |bb| self.terminator_loc(bb)),
215+
)
216+
} else {
217+
None
218+
};
219+
220+
let if_not_zero_locations = if loc.statement_index == 0 {
221+
None
222+
} else {
223+
Some(Location {
224+
block: loc.block,
225+
statement_index: loc.statement_index - 1,
226+
})
227+
};
228+
229+
if_zero_locations
230+
.into_iter()
231+
.flatten()
232+
.chain(if_not_zero_locations)
233+
}
234+
206235
#[inline]
207236
pub fn dominators(&self) -> Dominators<BasicBlock> {
208237
dominators(self)
@@ -555,13 +584,15 @@ impl_stable_hash_for!(struct self::VarBindingForm<'tcx> {
555584
});
556585

557586
mod binding_form_impl {
558-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
559587
use ich::StableHashingContext;
588+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
560589

561590
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for super::BindingForm<'tcx> {
562-
fn hash_stable<W: StableHasherResult>(&self,
563-
hcx: &mut StableHashingContext<'a>,
564-
hasher: &mut StableHasher<W>) {
591+
fn hash_stable<W: StableHasherResult>(
592+
&self,
593+
hcx: &mut StableHashingContext<'a>,
594+
hasher: &mut StableHasher<W>,
595+
) {
565596
use super::BindingForm::*;
566597
::std::mem::discriminant(self).hash_stable(hcx, hasher);
567598

@@ -1478,16 +1509,17 @@ impl<'tcx> TerminatorKind<'tcx> {
14781509
.map(|&u| {
14791510
let mut s = String::new();
14801511
let c = ty::Const {
1481-
val: ConstValue::Scalar(Scalar::Bits {
1512+
val: ConstValue::Scalar(
1513+
Scalar::Bits {
14821514
bits: u,
14831515
size: size.bytes() as u8,
1484-
}.into()),
1516+
}.into(),
1517+
),
14851518
ty: switch_ty,
14861519
};
14871520
fmt_const_val(&mut s, &c).unwrap();
14881521
s.into()
1489-
})
1490-
.chain(iter::once(String::from("otherwise").into()))
1522+
}).chain(iter::once(String::from("otherwise").into()))
14911523
.collect()
14921524
}
14931525
Call {
@@ -2017,7 +2049,13 @@ pub enum AggregateKind<'tcx> {
20172049
/// active field number and is present only for union expressions
20182050
/// -- e.g. for a union expression `SomeUnion { c: .. }`, the
20192051
/// active field index would identity the field `c`
2020-
Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<CanonicalTy<'tcx>>, Option<usize>),
2052+
Adt(
2053+
&'tcx AdtDef,
2054+
usize,
2055+
&'tcx Substs<'tcx>,
2056+
Option<CanonicalTy<'tcx>>,
2057+
Option<usize>,
2058+
),
20212059

20222060
Closure(DefId, ClosureSubsts<'tcx>),
20232061
Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
@@ -2267,7 +2305,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: &ty::Const) -> fmt::Result {
22672305
return write!(f, "{:?}{}", ((bits as i128) << shift) >> shift, i);
22682306
}
22692307
Char => return write!(f, "{:?}", ::std::char::from_u32(bits as u32).unwrap()),
2270-
_ => {},
2308+
_ => {}
22712309
}
22722310
}
22732311
// print function definitons
@@ -2283,14 +2321,12 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: &ty::Const) -> fmt::Result {
22832321
let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
22842322
if let Some(interpret::AllocType::Memory(alloc)) = alloc {
22852323
assert_eq!(len as usize as u128, len);
2286-
let slice = &alloc
2287-
.bytes
2288-
[(ptr.offset.bytes() as usize)..]
2289-
[..(len as usize)];
2324+
let slice =
2325+
&alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
22902326
let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
22912327
write!(f, "{:?}", s)
22922328
} else {
2293-
write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
2329+
write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
22942330
}
22952331
});
22962332
}
@@ -2821,15 +2857,13 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
28212857
let kind = box match **kind {
28222858
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
28232859
AggregateKind::Tuple => AggregateKind::Tuple,
2824-
AggregateKind::Adt(def, v, substs, user_ty, n) => {
2825-
AggregateKind::Adt(
2826-
def,
2827-
v,
2828-
substs.fold_with(folder),
2829-
user_ty.fold_with(folder),
2830-
n,
2831-
)
2832-
}
2860+
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
2861+
def,
2862+
v,
2863+
substs.fold_with(folder),
2864+
user_ty.fold_with(folder),
2865+
n,
2866+
),
28332867
AggregateKind::Closure(id, substs) => {
28342868
AggregateKind::Closure(id, substs.fold_with(folder))
28352869
}
@@ -2860,8 +2894,9 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
28602894
(match **kind {
28612895
AggregateKind::Array(ty) => ty.visit_with(visitor),
28622896
AggregateKind::Tuple => false,
2863-
AggregateKind::Adt(_, _, substs, user_ty, _) =>
2864-
substs.visit_with(visitor) || user_ty.visit_with(visitor),
2897+
AggregateKind::Adt(_, _, substs, user_ty, _) => {
2898+
substs.visit_with(visitor) || user_ty.visit_with(visitor)
2899+
}
28652900
AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
28662901
AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
28672902
}) || fields.visit_with(visitor)

‎src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 103 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc::mir::{BindingForm, BorrowKind, ClearCrossCrate, Field, Local};
1515
use rustc::mir::{LocalDecl, LocalKind, Location, Operand, Place};
1616
use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind};
1717
use rustc::ty;
18+
use rustc_data_structures::fx::FxHashSet;
1819
use rustc_data_structures::indexed_vec::Idx;
1920
use rustc_data_structures::sync::Lrc;
2021
use rustc_errors::DiagnosticBuilder;
@@ -24,8 +25,9 @@ use super::borrow_set::BorrowData;
2425
use super::{Context, MirBorrowckCtxt};
2526
use super::{InitializationRequiringAction, PrefixSet};
2627

28+
use dataflow::drop_flag_effects;
29+
use dataflow::move_paths::indexes::MoveOutIndex;
2730
use dataflow::move_paths::MovePathIndex;
28-
use dataflow::{FlowAtLocation, MovingOutStatements};
2931
use util::borrowck_errors::{BorrowckErrors, Origin};
3032

3133
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
@@ -35,17 +37,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
3537
desired_action: InitializationRequiringAction,
3638
(place, span): (&Place<'tcx>, Span),
3739
mpi: MovePathIndex,
38-
curr_move_out: &FlowAtLocation<MovingOutStatements<'_, 'gcx, 'tcx>>,
3940
) {
4041
let use_spans = self
4142
.move_spans(place, context.loc)
4243
.or_else(|| self.borrow_spans(span, context.loc));
4344
let span = use_spans.args_or_use();
4445

45-
let mois = self.move_data.path_map[mpi]
46-
.iter()
47-
.filter(|moi| curr_move_out.contains(moi))
48-
.collect::<Vec<_>>();
46+
let mois = self.get_moved_indexes(context, mpi);
47+
debug!("report_use_of_moved_or_uninitialized: mois={:?}", mois);
4948

5049
if mois.is_empty() {
5150
let root_place = self.prefixes(&place, PrefixSet::All).last().unwrap();
@@ -93,7 +92,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
9392

9493
let mut is_loop_move = false;
9594
for moi in &mois {
96-
let move_out = self.move_data.moves[**moi];
95+
let move_out = self.move_data.moves[*moi];
9796
let moved_place = &self.move_data.move_paths[move_out.path].place;
9897

9998
let move_spans = self.move_spans(moved_place, move_out.source);
@@ -148,7 +147,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
148147
};
149148

150149
if needs_note {
151-
let mpi = self.move_data.moves[*mois[0]].path;
150+
let mpi = self.move_data.moves[mois[0]].path;
152151
let place = &self.move_data.move_paths[mpi].place;
153152

154153
if let Some(ty) = self.retrieve_type_for_place(place) {
@@ -348,10 +347,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
348347
if issued_spans == borrow_spans {
349348
borrow_spans.var_span_label(
350349
&mut err,
351-
format!(
352-
"borrows occur due to use of `{}` in closure",
353-
desc_place
354-
),
350+
format!("borrows occur due to use of `{}` in closure", desc_place),
355351
);
356352
} else {
357353
let borrow_place = &issued_borrow.borrowed_place;
@@ -366,7 +362,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
366362

367363
borrow_spans.var_span_label(
368364
&mut err,
369-
format!("second borrow occurs due to use of `{}` in closure", desc_place),
365+
format!(
366+
"second borrow occurs due to use of `{}` in closure",
367+
desc_place
368+
),
370369
);
371370
}
372371

@@ -413,10 +412,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
413412

414413
let mut err = match &self.describe_place(&borrow.borrowed_place) {
415414
Some(_) if self.is_place_thread_local(root_place) => {
416-
self.report_thread_local_value_does_not_live_long_enough(
417-
drop_span,
418-
borrow_span,
419-
)
415+
self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span)
420416
}
421417
Some(name) => self.report_local_value_does_not_live_long_enough(
422418
context,
@@ -462,7 +458,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
462458
);
463459

464460
let mut err = self.tcx.path_does_not_live_long_enough(
465-
borrow_span, &format!("`{}`", name), Origin::Mir);
461+
borrow_span,
462+
&format!("`{}`", name),
463+
Origin::Mir,
464+
);
466465

467466
err.span_label(borrow_span, "borrowed value does not live long enough");
468467
err.span_label(
@@ -486,11 +485,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
486485
drop_span, borrow_span
487486
);
488487

489-
let mut err = self.tcx.thread_local_value_does_not_live_long_enough(
490-
borrow_span, Origin::Mir);
488+
let mut err = self
489+
.tcx
490+
.thread_local_value_does_not_live_long_enough(borrow_span, Origin::Mir);
491491

492-
err.span_label(borrow_span,
493-
"thread-local variables cannot be borrowed beyond the end of the function");
492+
err.span_label(
493+
borrow_span,
494+
"thread-local variables cannot be borrowed beyond the end of the function",
495+
);
494496
err.span_label(drop_span, "end of enclosing function is here");
495497
err
496498
}
@@ -521,6 +523,80 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
521523
err
522524
}
523525

526+
fn get_moved_indexes(&mut self, context: Context, mpi: MovePathIndex) -> Vec<MoveOutIndex> {
527+
let mir = self.mir;
528+
529+
let mut stack = Vec::new();
530+
stack.extend(mir.predecessor_locations(context.loc));
531+
532+
let mut visited = FxHashSet();
533+
let mut result = vec![];
534+
535+
'dfs: while let Some(l) = stack.pop() {
536+
debug!(
537+
"report_use_of_moved_or_uninitialized: current_location={:?}",
538+
l
539+
);
540+
541+
if !visited.insert(l) {
542+
continue;
543+
}
544+
545+
// check for moves
546+
let stmt_kind = mir[l.block]
547+
.statements
548+
.get(l.statement_index)
549+
.map(|s| &s.kind);
550+
if let Some(StatementKind::StorageDead(..)) = stmt_kind {
551+
// this analysis only tries to find moves explicitly
552+
// written by the user, so we ignore the move-outs
553+
// created by `StorageDead` and at the beginning
554+
// of a function.
555+
} else {
556+
for moi in &self.move_data.loc_map[l] {
557+
debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi);
558+
if self.move_data.moves[*moi].path == mpi {
559+
debug!("report_use_of_moved_or_uninitialized: found");
560+
result.push(*moi);
561+
562+
// Strictly speaking, we could continue our DFS here. There may be
563+
// other moves that can reach the point of error. But it is kind of
564+
// confusing to highlight them.
565+
//
566+
// Example:
567+
//
568+
// ```
569+
// let a = vec![];
570+
// let b = a;
571+
// let c = a;
572+
// drop(a); // <-- current point of error
573+
// ```
574+
//
575+
// Because we stop the DFS here, we only highlight `let c = a`,
576+
// and not `let b = a`. We will of course also report an error at
577+
// `let c = a` which highlights `let b = a` as the move.
578+
continue 'dfs;
579+
}
580+
}
581+
}
582+
583+
// check for inits
584+
let mut any_match = false;
585+
drop_flag_effects::for_location_inits(self.tcx, self.mir, self.move_data, l, |m| {
586+
if m == mpi {
587+
any_match = true;
588+
}
589+
});
590+
if any_match {
591+
continue 'dfs;
592+
}
593+
594+
stack.extend(mir.predecessor_locations(l));
595+
}
596+
597+
result
598+
}
599+
524600
pub(super) fn report_illegal_mutation_of_borrowed(
525601
&mut self,
526602
context: Context,
@@ -890,8 +966,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
890966
let attrs = self.tcx.get_attrs(statik.def_id);
891967
let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));
892968

893-
debug!("is_place_thread_local: attrs={:?} is_thread_local={:?}",
894-
attrs, is_thread_local);
969+
debug!(
970+
"is_place_thread_local: attrs={:?} is_thread_local={:?}",
971+
attrs, is_thread_local
972+
);
895973
is_thread_local
896974
} else {
897975
debug!("is_place_thread_local: no");
@@ -909,7 +987,7 @@ pub(super) enum UseSpans {
909987
// it's present.
910988
args_span: Span,
911989
// The span of the first use of the captured variable inside the closure.
912-
var_span: Span
990+
var_span: Span,
913991
},
914992
// This access has a single span associated to it: common case.
915993
OtherUse(Span),

‎src/librustc_mir/borrow_check/flows.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use polonius_engine::Output;
2424
use dataflow::move_paths::indexes::BorrowIndex;
2525
use dataflow::move_paths::HasMoveData;
2626
use dataflow::Borrows;
27-
use dataflow::{EverInitializedPlaces, MovingOutStatements};
27+
use dataflow::EverInitializedPlaces;
2828
use dataflow::{FlowAtLocation, FlowsAtLocation};
2929
use dataflow::MaybeUninitializedPlaces;
3030
use either::Either;
@@ -35,7 +35,6 @@ use std::rc::Rc;
3535
crate struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
3636
borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
3737
pub uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
38-
pub move_outs: FlowAtLocation<MovingOutStatements<'b, 'gcx, 'tcx>>,
3938
pub ever_inits: FlowAtLocation<EverInitializedPlaces<'b, 'gcx, 'tcx>>,
4039

4140
/// Polonius Output
@@ -46,14 +45,12 @@ impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
4645
crate fn new(
4746
borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
4847
uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
49-
move_outs: FlowAtLocation<MovingOutStatements<'b, 'gcx, 'tcx>>,
5048
ever_inits: FlowAtLocation<EverInitializedPlaces<'b, 'gcx, 'tcx>>,
5149
polonius_output: Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex>>>,
5250
) -> Self {
5351
Flows {
5452
borrows,
5553
uninits,
56-
move_outs,
5754
ever_inits,
5855
polonius_output,
5956
}
@@ -79,7 +76,6 @@ macro_rules! each_flow {
7976
($this:ident, $meth:ident($arg:ident)) => {
8077
FlowAtLocation::$meth(&mut $this.borrows, $arg);
8178
FlowAtLocation::$meth(&mut $this.uninits, $arg);
82-
FlowAtLocation::$meth(&mut $this.move_outs, $arg);
8379
FlowAtLocation::$meth(&mut $this.ever_inits, $arg);
8480
};
8581
}
@@ -146,18 +142,6 @@ impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> {
146142
});
147143
s.push_str("] ");
148144

149-
s.push_str("move_out: [");
150-
let mut saw_one = false;
151-
self.move_outs.each_state_bit(|mpi_move_out| {
152-
if saw_one {
153-
s.push_str(", ");
154-
};
155-
saw_one = true;
156-
let move_out = &self.move_outs.operator().move_data().moves[mpi_move_out];
157-
s.push_str(&format!("{:?}", move_out));
158-
});
159-
s.push_str("] ");
160-
161145
s.push_str("ever_init: [");
162146
let mut saw_one = false;
163147
self.ever_inits.each_state_bit(|mpi_ever_init| {

‎src/librustc_mir/borrow_check/mod.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use dataflow::DataflowResultsConsumer;
4343
use dataflow::FlowAtLocation;
4444
use dataflow::MoveDataParamEnv;
4545
use dataflow::{do_dataflow, DebugFormatted};
46-
use dataflow::{EverInitializedPlaces, MovingOutStatements};
46+
use dataflow::EverInitializedPlaces;
4747
use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
4848
use util::borrowck_errors::{BorrowckErrors, Origin};
4949

@@ -186,15 +186,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
186186
MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
187187
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
188188
));
189-
let flow_move_outs = FlowAtLocation::new(do_dataflow(
190-
tcx,
191-
mir,
192-
id,
193-
&attributes,
194-
&dead_unwinds,
195-
MovingOutStatements::new(tcx, mir, &mdpe),
196-
|bd, i| DebugFormatted::new(&bd.move_data().moves[i]),
197-
));
198189
let flow_ever_inits = FlowAtLocation::new(do_dataflow(
199190
tcx,
200191
mir,
@@ -268,7 +259,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
268259
let mut state = Flows::new(
269260
flow_borrows,
270261
flow_uninits,
271-
flow_move_outs,
272262
flow_ever_inits,
273263
polonius_output,
274264
);
@@ -1617,7 +1607,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16171607
let place = self.base_path(place_span.0);
16181608

16191609
let maybe_uninits = &flow_state.uninits;
1620-
let curr_move_outs = &flow_state.move_outs;
16211610

16221611
// Bad scenarios:
16231612
//
@@ -1663,7 +1652,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16631652
desired_action,
16641653
place_span,
16651654
mpi,
1666-
curr_move_outs,
16671655
);
16681656
return; // don't bother finding other problems.
16691657
}
@@ -1691,7 +1679,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16911679
let place = self.base_path(place_span.0);
16921680

16931681
let maybe_uninits = &flow_state.uninits;
1694-
let curr_move_outs = &flow_state.move_outs;
16951682

16961683
// Bad scenarios:
16971684
//
@@ -1727,7 +1714,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
17271714
desired_action,
17281715
place_span,
17291716
child_mpi,
1730-
curr_move_outs,
17311717
);
17321718
return; // don't bother finding other problems.
17331719
}

‎src/librustc_mir/dataflow/impls/mod.rs

Lines changed: 2 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ use super::MoveDataParamEnv;
2222

2323
use util::elaborate_drops::DropFlagState;
2424

25-
use super::move_paths::{HasMoveData, MoveData, MoveOutIndex, MovePathIndex, InitIndex};
25+
use super::move_paths::{HasMoveData, MoveData, MovePathIndex, InitIndex};
2626
use super::move_paths::{LookupResult, InitKind};
2727
use super::{BitDenotation, BlockSets, InitialFlow};
2828

2929
use super::drop_flag_effects_for_function_entry;
3030
use super::drop_flag_effects_for_location;
31-
use super::{on_lookup_result_bits, for_location_inits};
31+
use super::on_lookup_result_bits;
3232

3333
mod storage_liveness;
3434

@@ -211,40 +211,6 @@ impl<'a, 'gcx, 'tcx: 'a> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, '
211211
fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
212212
}
213213

214-
/// `MovingOutStatements` tracks the statements that perform moves out
215-
/// of particular places. More precisely, it tracks whether the
216-
/// *effect* of such moves (namely, the uninitialization of the
217-
/// place in question) can reach some point in the control-flow of
218-
/// the function, or if that effect is "killed" by some intervening
219-
/// operation reinitializing that place.
220-
///
221-
/// The resulting dataflow is a more enriched version of
222-
/// `MaybeUninitializedPlaces`. Both structures on their own only tell
223-
/// you if a place *might* be uninitialized at a given point in the
224-
/// control flow. But `MovingOutStatements` also includes the added
225-
/// data of *which* particular statement causing the deinitialization
226-
/// that the borrow checker's error message may need to report.
227-
#[allow(dead_code)]
228-
pub struct MovingOutStatements<'a, 'gcx: 'tcx, 'tcx: 'a> {
229-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
230-
mir: &'a Mir<'tcx>,
231-
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
232-
}
233-
234-
impl<'a, 'gcx: 'tcx, 'tcx: 'a> MovingOutStatements<'a, 'gcx, 'tcx> {
235-
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
236-
mir: &'a Mir<'tcx>,
237-
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
238-
-> Self
239-
{
240-
MovingOutStatements { tcx: tcx, mir: mir, mdpe: mdpe }
241-
}
242-
}
243-
244-
impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MovingOutStatements<'a, 'gcx, 'tcx> {
245-
fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
246-
}
247-
248214
/// `EverInitializedPlaces` tracks all places that might have ever been
249215
/// initialized upon reaching a particular point in the control flow
250216
/// for a function, without an intervening `Storage Dead`.
@@ -488,83 +454,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedPlaces<'a, 'gcx, 'tc
488454
}
489455
}
490456

491-
impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
492-
type Idx = MoveOutIndex;
493-
fn name() -> &'static str { "moving_out" }
494-
fn bits_per_block(&self) -> usize {
495-
self.move_data().moves.len()
496-
}
497-
498-
fn start_block_effect(&self, _sets: &mut IdxSet<MoveOutIndex>) {
499-
// no move-statements have been executed prior to function
500-
// execution, so this method has no effect on `_sets`.
501-
}
502-
503-
fn statement_effect(&self,
504-
sets: &mut BlockSets<MoveOutIndex>,
505-
location: Location) {
506-
let (tcx, mir, move_data) = (self.tcx, self.mir, self.move_data());
507-
let stmt = &mir[location.block].statements[location.statement_index];
508-
let loc_map = &move_data.loc_map;
509-
let path_map = &move_data.path_map;
510-
511-
match stmt.kind {
512-
// this analysis only tries to find moves explicitly
513-
// written by the user, so we ignore the move-outs
514-
// created by `StorageDead` and at the beginning
515-
// of a function.
516-
mir::StatementKind::StorageDead(_) => {}
517-
_ => {
518-
debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
519-
stmt, location, &loc_map[location]);
520-
// Every path deinitialized by a *particular move*
521-
// has corresponding bit, "gen'ed" (i.e. set)
522-
// here, in dataflow vector
523-
sets.gen_all_and_assert_dead(&loc_map[location]);
524-
}
525-
}
526-
527-
for_location_inits(tcx, mir, move_data, location,
528-
|mpi| sets.kill_all(&path_map[mpi]));
529-
}
530-
531-
fn terminator_effect(&self,
532-
sets: &mut BlockSets<MoveOutIndex>,
533-
location: Location)
534-
{
535-
let (tcx, mir, move_data) = (self.tcx, self.mir, self.move_data());
536-
let term = mir[location.block].terminator();
537-
let loc_map = &move_data.loc_map;
538-
let path_map = &move_data.path_map;
539-
540-
debug!("terminator {:?} at loc {:?} moves out of move_indexes {:?}",
541-
term, location, &loc_map[location]);
542-
sets.gen_all_and_assert_dead(&loc_map[location]);
543-
544-
for_location_inits(tcx, mir, move_data, location,
545-
|mpi| sets.kill_all(&path_map[mpi]));
546-
}
547-
548-
fn propagate_call_return(&self,
549-
in_out: &mut IdxSet<MoveOutIndex>,
550-
_call_bb: mir::BasicBlock,
551-
_dest_bb: mir::BasicBlock,
552-
dest_place: &mir::Place) {
553-
let move_data = self.move_data();
554-
let bits_per_block = self.bits_per_block();
555-
556-
let path_map = &move_data.path_map;
557-
on_lookup_result_bits(self.tcx,
558-
self.mir,
559-
move_data,
560-
move_data.rev_lookup.find(dest_place),
561-
|mpi| for moi in &path_map[mpi] {
562-
assert!(moi.index() < bits_per_block);
563-
in_out.remove(&moi);
564-
});
565-
}
566-
}
567-
568457
impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedPlaces<'a, 'gcx, 'tcx> {
569458
type Idx = InitIndex;
570459
fn name() -> &'static str { "ever_init" }
@@ -682,13 +571,6 @@ impl<'a, 'gcx, 'tcx> BitwiseOperator for DefinitelyInitializedPlaces<'a, 'gcx, '
682571
}
683572
}
684573

685-
impl<'a, 'gcx, 'tcx> BitwiseOperator for MovingOutStatements<'a, 'gcx, 'tcx> {
686-
#[inline]
687-
fn join(&self, pred1: Word, pred2: Word) -> Word {
688-
pred1 | pred2 // moves from both preds are in scope
689-
}
690-
}
691-
692574
impl<'a, 'gcx, 'tcx> BitwiseOperator for EverInitializedPlaces<'a, 'gcx, 'tcx> {
693575
#[inline]
694576
fn join(&self, pred1: Word, pred2: Word) -> Word {
@@ -727,13 +609,6 @@ impl<'a, 'gcx, 'tcx> InitialFlow for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx>
727609
}
728610
}
729611

730-
impl<'a, 'gcx, 'tcx> InitialFlow for MovingOutStatements<'a, 'gcx, 'tcx> {
731-
#[inline]
732-
fn bottom_value() -> bool {
733-
false // bottom = no loans in scope by default
734-
}
735-
}
736-
737612
impl<'a, 'gcx, 'tcx> InitialFlow for EverInitializedPlaces<'a, 'gcx, 'tcx> {
738613
#[inline]
739614
fn bottom_value() -> bool {

‎src/librustc_mir/dataflow/mod.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::usize;
2828

2929
pub use self::impls::{MaybeStorageLive};
3030
pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
31-
pub use self::impls::{DefinitelyInitializedPlaces, MovingOutStatements};
31+
pub use self::impls::DefinitelyInitializedPlaces;
3232
pub use self::impls::EverInitializedPlaces;
3333
pub use self::impls::borrows::Borrows;
3434
pub use self::impls::HaveBeenBorrowedLocals;
@@ -38,7 +38,7 @@ pub(crate) use self::drop_flag_effects::*;
3838
use self::move_paths::MoveData;
3939

4040
mod at_location;
41-
mod drop_flag_effects;
41+
pub mod drop_flag_effects;
4242
mod graphviz;
4343
mod impls;
4444
pub mod move_paths;
@@ -511,18 +511,6 @@ impl<'a, E:Idx> BlockSets<'a, E> {
511511
}
512512
}
513513

514-
fn gen_all_and_assert_dead<I>(&mut self, i: I)
515-
where I: IntoIterator,
516-
I::Item: Borrow<E>
517-
{
518-
for j in i {
519-
let j = j.borrow();
520-
let retval = self.gen_set.add(j);
521-
self.kill_set.remove(j);
522-
assert!(retval);
523-
}
524-
}
525-
526514
fn kill(&mut self, e: &E) {
527515
self.gen_set.remove(e);
528516
self.kill_set.add(e);

‎src/test/ui/hygiene/fields-move.nll.stderr

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
error[E0382]: use of moved value: `foo.x`
22
--> $DIR/fields-move.rs:28:9
33
|
4-
LL | $foo.x
5-
| ------ value moved here
6-
...
74
LL | $foo.x //~ ERROR use of moved value: `foo.x`
85
| ^^^^^^ value used here after move
96
...
@@ -28,14 +25,9 @@ LL | assert_two_copies(copy_modern!(foo), foo.x); //~ ERROR use of moved val
2825
error[E0382]: use of moved value: `foo.x`
2926
--> $DIR/fields-move.rs:39:42
3027
|
31-
LL | $foo.x
32-
| ------ value moved here
33-
...
3428
LL | $foo.x //~ ERROR use of moved value: `foo.x`
3529
| ------ value moved here
3630
...
37-
LL | assert_two_copies(copy_modern!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
38-
| ----- value moved here
3931
LL | assert_two_copies(copy_legacy!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
4032
| ^^^^^ value used here after move
4133
|

0 commit comments

Comments
 (0)
Please sign in to comment.