Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::{CastTy, mir_cast_kind};
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, Ty, UpvarArgs};
use rustc_span::{DUMMY_SP, Span, Spanned};
use rustc_span::Span;
use tracing::debug;

use crate::builder::expr::as_place::PlaceBase;
Expand Down Expand Up @@ -74,6 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
NeedsTemporary::No
)
);
this.record_operand_moved(&value_operand);
block.and(Rvalue::Repeat(value_operand, count))
}
}
Expand Down Expand Up @@ -219,6 +220,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.collect();

for operand in fields.iter() {
this.record_operand_moved(operand);
}
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(el_ty)), fields))
}
ExprKind::Tuple { ref fields } => {
Expand All @@ -240,6 +244,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.collect();

for operand in fields.iter() {
this.record_operand_moved(operand);
}
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields))
}
ExprKind::Closure(ClosureExpr {
Expand Down Expand Up @@ -342,6 +349,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Box::new(AggregateKind::CoroutineClosure(closure_id.to_def_id(), args))
}
};
for operand in operands.iter() {
this.record_operand_moved(operand);
}
block.and(Rvalue::Aggregate(result, operands))
}
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
Expand Down Expand Up @@ -424,6 +434,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
NeedsTemporary::No,
)
);
this.record_operand_moved(&operand);
block.and(Rvalue::Use(operand, WithRetag::Yes))
}

Expand Down Expand Up @@ -647,7 +658,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.diverge_from(block);
block = success;
}
this.record_operands_moved(&[Spanned { node: value_operand, span: DUMMY_SP }]);
this.record_operand_moved(&value_operand);
}
block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), IndexVec::new()))
}
Expand Down
15 changes: 12 additions & 3 deletions compiler/rustc_mir_build/src/builder/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
use rustc_index::IndexVec;
use rustc_middle::mir::*;
use rustc_middle::span_bug;
use rustc_middle::thir::*;
Expand Down Expand Up @@ -490,7 +491,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

let success = this.cfg.start_new_block();

this.record_operands_moved(&args);
for operand in args.iter() {
this.record_operand_moved(&operand.node);
}

debug!("expr_into_dest: fn_span={:?}", fn_span);

Expand Down Expand Up @@ -629,7 +632,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let variant = adt_def.variant(variant_index);
let field_names = variant.fields.indices();

let fields = match base {
let fields: IndexVec<_, _> = match base {
AdtExprBase::None => {
field_names.filter_map(|n| fields_map.get(&n).cloned()).collect()
}
Expand Down Expand Up @@ -694,6 +697,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
user_ty,
active_field_index,
));
for operand in fields.iter() {
this.record_operand_moved(operand);
}
this.cfg.push_assign(
block,
source_info,
Expand Down Expand Up @@ -842,7 +848,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
debug_assert!(Category::of(&expr.kind) == Some(Category::Place));

let place = unpack!(block = this.as_place(block, expr_id));
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place), WithRetag::Yes);
let operand = this.consume_by_copy_or_move(place);
this.record_operand_moved(&operand);
let rvalue = Rvalue::Use(operand, WithRetag::Yes);
this.cfg.push_assign(block, source_info, destination, rvalue);
block.unit()
}
Expand All @@ -868,6 +876,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block =
this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No)
);
this.record_operand_moved(&value);
let resume = this.cfg.start_new_block();
this.cfg.terminate(
block,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir_build/src/builder/expr/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.collect();

this.record_operands_moved(&args);
for operand in args.iter() {
this.record_operand_moved(&operand.node);
}

debug!("expr_into_dest: fn_span={:?}", fn_span);

Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_mir_build/src/builder/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
}

/// Indicates that the "local operand" stored in `local` is
/// Indicates that the "local operand" stored in `operand` is
/// *moved* at some point during execution (see `local_scope` for
/// more information about what a "local operand" is -- in short,
/// it's an intermediate operand created as part of preparing some
Expand Down Expand Up @@ -1572,19 +1572,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// spurious borrow-check errors -- the problem, ironically, is
/// not the `DROP(_X)` itself, but the (spurious) unwind pathways
/// that it creates. See #64391 for an example.
pub(crate) fn record_operands_moved(&mut self, operands: &[Spanned<Operand<'tcx>>]) {
#[instrument(level = "debug", skip(self))]
pub(crate) fn record_operand_moved(&mut self, operand: &Operand<'tcx>) {
let local_scope = self.local_scope();
let scope = self.scopes.scopes.last_mut().unwrap();

assert_eq!(scope.region_scope, local_scope, "local scope is not the topmost scope!",);
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().flat_map(|operand| match operand.node {
let local_moved = match operand {
Operand::Copy(_) | Operand::Constant(_) | Operand::RuntimeChecks(_) => None,
Operand::Move(place) => place.as_local(),
});
};

for local in locals_moved {
if let Some(local) = local_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
Expand Down
62 changes: 26 additions & 36 deletions tests/mir-opt/box_partial_move.maybe_move.ElaborateDrops.diff
Original file line number Diff line number Diff line change
Expand Up @@ -19,76 +19,66 @@
+ _5 = const true;
StorageLive(_3);
_3 = copy _1;
switchInt(move _3) -> [0: bb3, otherwise: bb1];
switchInt(move _3) -> [0: bb2, otherwise: bb1];
}

bb1: {
StorageLive(_4);
+ _5 = const false;
_4 = move (*_2);
_0 = Option::<String>::Some(move _4);
- drop(_4) -> [return: bb2, unwind: bb6];
+ goto -> bb2;
}

bb2: {
StorageDead(_4);
goto -> bb4;
goto -> bb3;
}

bb3: {
bb2: {
_0 = Option::<String>::None;
goto -> bb4;
goto -> bb3;
}

bb4: {
bb3: {
StorageDead(_3);
- drop(_2) -> [return: bb5, unwind continue];
+ goto -> bb14;
- drop(_2) -> [return: bb4, unwind continue];
+ goto -> bb12;
}

bb5: {
bb4: {
return;
}

bb6 (cleanup): {
- drop(_2) -> [return: bb7, unwind terminate(cleanup)];
+ goto -> bb7;
}

bb7 (cleanup): {
resume;
+ }
+
+ bb8: {
+ goto -> bb5;
+ bb5 (cleanup): {
+ resume;
+ }
+
+ bb9: {
+ bb6: {
+ goto -> bb4;
+ }
+
+ bb7: {
+ _6 = &mut _2;
+ _7 = <Box<String> as Drop>::drop(move _6) -> [return: bb8, unwind: bb7];
+ _7 = <Box<String> as Drop>::drop(move _6) -> [return: bb6, unwind: bb5];
+ }
+
+ bb10 (cleanup): {
+ bb8 (cleanup): {
+ _8 = &mut _2;
+ _9 = <Box<String> as Drop>::drop(move _8) -> [return: bb7, unwind terminate(cleanup)];
+ _9 = <Box<String> as Drop>::drop(move _8) -> [return: bb5, unwind terminate(cleanup)];
+ }
+
+ bb11: {
+ goto -> bb13;
+ bb9: {
+ goto -> bb11;
+ }
+
+ bb12: {
+ drop((*_10)) -> [return: bb9, unwind: bb10];
+ bb10: {
+ drop((*_10)) -> [return: bb7, unwind: bb8];
+ }
+
+ bb13: {
+ switchInt(copy _5) -> [0: bb9, otherwise: bb12];
+ bb11: {
+ switchInt(copy _5) -> [0: bb7, otherwise: bb10];
+ }
+
+ bb14: {
+ bb12: {
+ _10 = copy ((_2.0: std::ptr::Unique<std::string::String>).0: std::ptr::NonNull<std::string::String>) as *const std::string::String (Transmute);
+ goto -> bb11;
+ goto -> bb9;
}
}

Loading
Loading