Skip to content

Commit

Permalink
Don't run Drop terminators on types that do not have drop glue in c…
Browse files Browse the repository at this point in the history
…onst eval
  • Loading branch information
JakobDegen committed Dec 22, 2022
1 parent 37e0016 commit 0229281
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 13 deletions.
15 changes: 12 additions & 3 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

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

let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
self.drop_in_place(&place, instance, target, unwind)?;
}

Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,14 +562,13 @@ pub enum TerminatorKind<'tcx> {
Unreachable,

/// The behavior of this statement differs significantly before and after drop elaboration.
/// After drop elaboration, `Drop` executes the drop glue for the specified place, after which
/// it continues execution/unwinds at the given basic blocks. It is possible that executing drop
/// glue is special - this would be part of Rust's memory model. (**FIXME**: due we have an
/// issue tracking if drop glue has any interesting semantics in addition to those of a function
/// call?)
///
/// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically, the
/// `Drop` will be executed if...
///
/// After drop elaboration: `Drop` terminators are a complete nop for types that have no drop
/// glue. For other types, `Drop` terminators behave exactly like a call to
/// `core::mem::drop_in_place` with a pointer to the given place.
///
/// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically,
/// the `Drop` will be executed if...
///
/// **Needs clarification**: End of that sentence. This in effect should document the exact
/// behavior of drop elaboration. The following sounds vaguely right, but I'm not quite sure:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Test that drop_in_place mutably retags the entire place,
//! ensuring it is writeable
//! Test that drop_in_place mutably retags the entire place, even for a type that does not need
//! dropping, ensuring among other things that it is writeable

//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/

Expand Down

0 comments on commit 0229281

Please sign in to comment.