/// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
/// manually.
#[stable(feature = "drop_in_place", since = "1.8.0")]
+#[inline(always)]
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+ real_drop_in_place(&mut *to_drop)
+}
+
+// The real `drop_in_place` -- the one that gets called implicitly when variables go
+// out of scope -- should have a safe reference and not a raw pointer as argument
+// type. When we drop a local variable, we access it with a pointer that behaves
+// like a safe reference; transmuting that to a raw pointer does not mean we can
+// actually access it with raw pointers.
#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+unsafe fn real_drop_in_place<T: ?Sized>(to_drop: &mut T) {
// Code here does not matter - this is replaced by the
// real drop glue by the compiler.
- drop_in_place(to_drop);
+ real_drop_in_place(to_drop)
}
/// Creates a null raw pointer.
// that will take care to make it UB to leave the range, just
// like for transmute).
caller.value == callee.value,
+ (layout::Abi::ScalarPair(ref caller1, ref caller2),
+ layout::Abi::ScalarPair(ref callee1, ref callee2)) =>
+ caller1.value == callee1.value && caller2.value == callee2.value,
// Be conservative
_ => false
}
// The first argument (index 0), but add 1 for the return value.
let dropee_ptr = Place::Local(Local::new(1+0));
if tcx.sess.opts.debugging_opts.mir_emit_retag {
- // We use raw ptr operations, better prepare the alias tracking for that
+ // Function arguments should be retagged
mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
+ source_info,
+ kind: StatementKind::Retag { fn_entry: true, place: dropee_ptr.clone() },
+ });
+ // We use raw ptr operations, better prepare the alias tracking for that
+ mir.basic_blocks_mut()[START_BLOCK].statements.insert(1, Statement {
source_info,
kind: StatementKind::EscapeToRaw(Operand::Copy(dropee_ptr.clone())),
})