summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_transform/src/elaborate_drops.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_transform/src/elaborate_drops.rs')
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs30
1 files changed, 14 insertions, 16 deletions
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index a702113bd..fda0e1023 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -1,7 +1,7 @@
use crate::deref_separator::deref_finder;
use crate::MirPass;
-use rustc_data_structures::fx::FxHashMap;
use rustc_index::bit_set::BitSet;
+use rustc_index::IndexVec;
use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
@@ -14,7 +14,7 @@ use rustc_mir_dataflow::un_derefer::UnDerefer;
use rustc_mir_dataflow::MoveDataParamEnv;
use rustc_mir_dataflow::{on_all_children_bits, on_all_drop_children_bits};
use rustc_mir_dataflow::{Analysis, ResultsCursor};
-use rustc_span::{DesugaringKind, Span};
+use rustc_span::Span;
use rustc_target::abi::{FieldIdx, VariantIdx};
use std::fmt;
@@ -24,7 +24,7 @@ use std::fmt;
/// In general, the compiler cannot determine at compile time whether a destructor will run or not.
///
/// At a high level, this pass refines Drop to only run the destructor if the
-/// target is initialized. The way this is achievied is by inserting drop flags for every variable
+/// target is initialized. The way this is achieved is by inserting drop flags for every variable
/// that may be dropped, and then using those flags to determine whether a destructor should run.
/// Once this is complete, Drop terminators in the MIR correspond to a call to the "drop glue" or
/// "drop shim" for the type of the dropped place.
@@ -84,12 +84,13 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
let reachable = traversal::reachable_as_bitset(body);
+ let drop_flags = IndexVec::from_elem(None, &env.move_data.move_paths);
ElaborateDropsCtxt {
tcx,
body,
env: &env,
init_data: InitializationData { inits, uninits },
- drop_flags: Default::default(),
+ drop_flags,
patch: MirPatch::new(body),
un_derefer: un_derefer,
reachable,
@@ -293,7 +294,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
body: &'a Body<'tcx>,
env: &'a MoveDataParamEnv<'tcx>,
init_data: InitializationData<'a, 'tcx>,
- drop_flags: FxHashMap<MovePathIndex, Local>,
+ drop_flags: IndexVec<MovePathIndex, Option<Local>>,
patch: MirPatch<'tcx>,
un_derefer: UnDerefer<'tcx>,
reachable: BitSet<BasicBlock>,
@@ -312,11 +313,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let tcx = self.tcx;
let patch = &mut self.patch;
debug!("create_drop_flag({:?})", self.body.span);
- self.drop_flags.entry(index).or_insert_with(|| patch.new_internal(tcx.types.bool, span));
+ self.drop_flags[index].get_or_insert_with(|| patch.new_internal(tcx.types.bool, span));
}
fn drop_flag(&mut self, index: MovePathIndex) -> Option<Place<'tcx>> {
- self.drop_flags.get(&index).map(|t| Place::from(*t))
+ self.drop_flags[index].map(Place::from)
}
/// create a patch that elaborates all drops in the input
@@ -365,7 +366,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
if maybe_dead {
self.tcx.sess.delay_span_bug(
terminator.source_info.span,
- &format!(
+ format!(
"drop of untracked, uninitialized value {:?}, place {:?} ({:?})",
bb, place, path
),
@@ -400,7 +401,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let terminator = data.terminator();
match terminator.kind {
- TerminatorKind::Drop { mut place, target, unwind } => {
+ TerminatorKind::Drop { mut place, target, unwind, replace } => {
if let Some(new_place) = self.un_derefer.derefer(place.as_ref(), self.body) {
place = new_place;
}
@@ -433,13 +434,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
)
}
LookupResult::Parent(..) => {
- if !matches!(
- terminator.source_info.span.desugaring_kind(),
- Some(DesugaringKind::Replace),
- ) {
+ if !replace {
self.tcx.sess.delay_span_bug(
terminator.source_info.span,
- &format!("drop of untracked value {:?}", bb),
+ format!("drop of untracked value {:?}", bb),
);
}
// A drop and replace behind a pointer/array/whatever.
@@ -463,7 +461,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
}
fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagState) {
- if let Some(&flag) = self.drop_flags.get(&path) {
+ if let Some(flag) = self.drop_flags[path] {
let span = self.patch.source_info_for_location(self.body, loc).span;
let val = self.constant_bool(span, val.value());
self.patch.add_assign(loc, Place::from(flag), val);
@@ -474,7 +472,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let loc = Location::START;
let span = self.patch.source_info_for_location(self.body, loc).span;
let false_ = self.constant_bool(span, false);
- for flag in self.drop_flags.values() {
+ for flag in self.drop_flags.iter().flatten() {
self.patch.add_assign(loc, Place::from(*flag), false_.clone());
}
}