Revert "Simplify unscheduling of drops after moves"
This reverts commit b766abc88f
.
This commit is contained in:
parent
bed69c6134
commit
dac354fc32
5 changed files with 80 additions and 31 deletions
|
@ -83,7 +83,7 @@ that contains only loops and breakable blocks. It tracks where a `break`,
|
|||
|
||||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG};
|
||||
use crate::thir::{Expr, ExprRef, LintLevel};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::*;
|
||||
|
@ -120,6 +120,8 @@ struct Scope {
|
|||
/// end of the vector (top of the stack) first.
|
||||
drops: Vec<DropData>,
|
||||
|
||||
moved_locals: Vec<Local>,
|
||||
|
||||
/// The drop index that will drop everything in and below this scope on an
|
||||
/// unwind path.
|
||||
cached_unwind_block: Option<DropIdx>,
|
||||
|
@ -403,6 +405,7 @@ impl<'tcx> Scopes<'tcx> {
|
|||
region_scope: region_scope.0,
|
||||
region_scope_span: region_scope.1.span,
|
||||
drops: vec![],
|
||||
moved_locals: vec![],
|
||||
cached_unwind_block: None,
|
||||
cached_generator_drop_block: None,
|
||||
});
|
||||
|
@ -890,19 +893,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
assert_eq!(scope.region_scope, local_scope, "local scope is not the topmost scope!",);
|
||||
|
||||
// look for moves of a local variable, like `MOVE(_X)`
|
||||
let locals_moved = operands
|
||||
.iter()
|
||||
.filter_map(|operand| match operand {
|
||||
Operand::Copy(_) | Operand::Constant(_) => None,
|
||||
Operand::Move(place) => place.as_local(),
|
||||
})
|
||||
.collect::<FxHashSet<_>>();
|
||||
let locals_moved = operands.iter().flat_map(|operand| match operand {
|
||||
Operand::Copy(_) | Operand::Constant(_) => None,
|
||||
Operand::Move(place) => place.as_local(),
|
||||
});
|
||||
|
||||
// Remove the drops for the moved operands.
|
||||
scope
|
||||
.drops
|
||||
.retain(|drop| drop.kind == DropKind::Storage || !locals_moved.contains(&drop.local));
|
||||
scope.invalidate_cache();
|
||||
for local in locals_moved {
|
||||
// check if we have a Drop for this operand and -- if so
|
||||
// -- add it to the list of moved operands. Note that this
|
||||
// local might not have been an operand created for this
|
||||
// call, it could come from other places too.
|
||||
if scope.drops.iter().any(|drop| drop.local == local && drop.kind == DropKind::Value) {
|
||||
scope.moved_locals.push(local);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Other
|
||||
|
@ -1147,6 +1151,14 @@ fn build_scope_drops<'tcx>(
|
|||
debug_assert_eq!(unwind_drops.drops[unwind_to].0.kind, drop_data.kind);
|
||||
unwind_to = unwind_drops.drops[unwind_to].1;
|
||||
|
||||
// If the operand has been moved, and we are not on an unwind
|
||||
// path, then don't generate the drop. (We only take this into
|
||||
// account for non-unwind paths so as not to disturb the
|
||||
// caching mechanism.)
|
||||
if scope.moved_locals.iter().any(|&o| o == local) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unwind_drops.add_entry(block, unwind_to);
|
||||
|
||||
let next = cfg.start_new_block();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue