Skip to content

Commit 0229281

Browse files
committed
Don't run Drop terminators on types that do not have drop glue in const eval
1 parent 37e0016 commit 0229281

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

compiler/rustc_const_eval/src/interpret/terminator.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
119119
}
120120

121121
Drop { place, target, unwind } => {
122+
let frame = self.frame();
123+
let ty = place.ty(&frame.body.local_decls, *self.tcx).ty;
124+
let ty = self.subst_from_frame_and_normalize_erasing_regions(frame, ty)?;
125+
let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
126+
if let ty::InstanceDef::DropGlue(_, None) = instance.def {
127+
// This is the branch we enter if and only if the dropped type has no drop glue
128+
// whatsoever. This can happen as a result of monomorphizing a drop of a
129+
// generic. In order to make sure that generic and non-generic code behaves
130+
// roughly the same (and in keeping with Mir semantics) we do nothing here.
131+
self.go_to_block(target);
132+
return Ok(());
133+
}
122134
let place = self.eval_place(place)?;
123-
let ty = place.layout.ty;
124135
trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
125-
126-
let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
127136
self.drop_in_place(&place, instance, target, unwind)?;
128137
}
129138

compiler/rustc_middle/src/mir/syntax.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -562,14 +562,13 @@ pub enum TerminatorKind<'tcx> {
562562
Unreachable,
563563

564564
/// The behavior of this statement differs significantly before and after drop elaboration.
565-
/// After drop elaboration, `Drop` executes the drop glue for the specified place, after which
566-
/// it continues execution/unwinds at the given basic blocks. It is possible that executing drop
567-
/// glue is special - this would be part of Rust's memory model. (**FIXME**: due we have an
568-
/// issue tracking if drop glue has any interesting semantics in addition to those of a function
569-
/// call?)
570-
///
571-
/// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically, the
572-
/// `Drop` will be executed if...
565+
///
566+
/// After drop elaboration: `Drop` terminators are a complete nop for types that have no drop
567+
/// glue. For other types, `Drop` terminators behave exactly like a call to
568+
/// `core::mem::drop_in_place` with a pointer to the given place.
569+
///
570+
/// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically,
571+
/// the `Drop` will be executed if...
573572
///
574573
/// **Needs clarification**: End of that sentence. This in effect should document the exact
575574
/// behavior of drop elaboration. The following sounds vaguely right, but I'm not quite sure:

src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//! Test that drop_in_place mutably retags the entire place,
2-
//! ensuring it is writeable
1+
//! Test that drop_in_place mutably retags the entire place, even for a type that does not need
2+
//! dropping, ensuring among other things that it is writeable
33
44
//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/
55

0 commit comments

Comments
 (0)