mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Don't run Drop
terminators on types that do not have drop glue in const eval
This commit is contained in:
parent
37e00165e4
commit
0229281d03
@ -119,11 +119,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Drop { place, target, unwind } => {
|
Drop { place, target, unwind } => {
|
||||||
let place = self.eval_place(place)?;
|
let frame = self.frame();
|
||||||
let ty = place.layout.ty;
|
let ty = place.ty(&frame.body.local_decls, *self.tcx).ty;
|
||||||
trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
|
let ty = self.subst_from_frame_and_normalize_erasing_regions(frame, ty)?;
|
||||||
|
|
||||||
let instance = Instance::resolve_drop_in_place(*self.tcx, 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)?;
|
||||||
|
trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
|
||||||
self.drop_in_place(&place, instance, target, unwind)?;
|
self.drop_in_place(&place, instance, target, unwind)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,14 +562,13 @@ pub enum TerminatorKind<'tcx> {
|
|||||||
Unreachable,
|
Unreachable,
|
||||||
|
|
||||||
/// The behavior of this statement differs significantly before and after drop elaboration.
|
/// 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
|
/// After drop elaboration: `Drop` terminators are a complete nop for types that have no drop
|
||||||
/// `Drop` will be executed if...
|
/// 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
|
/// **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:
|
/// behavior of drop elaboration. The following sounds vaguely right, but I'm not quite sure:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Test that drop_in_place mutably retags the entire place,
|
//! Test that drop_in_place mutably retags the entire place, even for a type that does not need
|
||||||
//! ensuring it is writeable
|
//! dropping, ensuring among other things that it is writeable
|
||||||
|
|
||||||
//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/
|
//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user