Rollup merge of #146187 - clarfonthey:const-drop-in-place, r=oli-obk
Unstably constify `ptr::drop_in_place` and related methods Tracking: rust-lang/rust#109342 Supercedes: rust-lang/rust#145725 Makes methods const: * `core::ptr::drop_in_place` * `core::mem::ManuallyDrop::drop` * `core::mem::MaybeUninit::assume_init_drop` * `<[core::mem::MaybeUninit<_>]>::assume_init_drop` * `<*mut _>::drop_in_place` * `core::ptr::NonNull::drop_in_place`
This commit is contained in:
commit
252974a717
9 changed files with 84 additions and 14 deletions
|
|
@ -1,3 +1,4 @@
|
|||
use crate::marker::Destruct;
|
||||
use crate::ops::{Deref, DerefMut, DerefPure};
|
||||
use crate::ptr;
|
||||
|
||||
|
|
@ -249,7 +250,11 @@ impl<T: ?Sized> ManuallyDrop<T> {
|
|||
/// [pinned]: crate::pin
|
||||
#[stable(feature = "manually_drop", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
|
||||
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
|
||||
pub const unsafe fn drop(slot: &mut ManuallyDrop<T>)
|
||||
where
|
||||
T: [const] Destruct,
|
||||
{
|
||||
// SAFETY: we are dropping the value pointed to by a mutable reference
|
||||
// which is guaranteed to be valid for writes.
|
||||
// It is up to the caller to make sure that `slot` isn't dropped again.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::any::type_name;
|
||||
use crate::marker::Destruct;
|
||||
use crate::mem::ManuallyDrop;
|
||||
use crate::{fmt, intrinsics, ptr, slice};
|
||||
|
||||
|
|
@ -714,7 +715,11 @@ impl<T> MaybeUninit<T> {
|
|||
///
|
||||
/// [`assume_init`]: MaybeUninit::assume_init
|
||||
#[stable(feature = "maybe_uninit_extra", since = "1.60.0")]
|
||||
pub unsafe fn assume_init_drop(&mut self) {
|
||||
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
|
||||
pub const unsafe fn assume_init_drop(&mut self)
|
||||
where
|
||||
T: [const] Destruct,
|
||||
{
|
||||
// SAFETY: the caller must guarantee that `self` is initialized and
|
||||
// satisfies all invariants of `T`.
|
||||
// Dropping the value in place is safe if that is the case.
|
||||
|
|
@ -1390,7 +1395,11 @@ impl<T> [MaybeUninit<T>] {
|
|||
/// behaviour.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn assume_init_drop(&mut self) {
|
||||
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
|
||||
pub const unsafe fn assume_init_drop(&mut self)
|
||||
where
|
||||
T: [const] Destruct,
|
||||
{
|
||||
if !self.is_empty() {
|
||||
// SAFETY: the caller must guarantee that every element of `self`
|
||||
// is initialized and satisfies all invariants of `T`.
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@
|
|||
|
||||
use crate::cmp::Ordering;
|
||||
use crate::intrinsics::const_eval_select;
|
||||
use crate::marker::{FnPtr, PointeeSized};
|
||||
use crate::marker::{Destruct, FnPtr, PointeeSized};
|
||||
use crate::mem::{self, MaybeUninit, SizedTypeProperties};
|
||||
use crate::num::NonZero;
|
||||
use crate::{fmt, hash, intrinsics, ub_checks};
|
||||
|
|
@ -801,7 +801,11 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
|||
#[lang = "drop_in_place"]
|
||||
#[allow(unconditional_recursion)]
|
||||
#[rustc_diagnostic_item = "ptr_drop_in_place"]
|
||||
pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
|
||||
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
|
||||
pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
|
||||
where
|
||||
T: [const] Destruct,
|
||||
{
|
||||
// Code here does not matter - this is replaced by the
|
||||
// real drop glue by the compiler.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::*;
|
||||
use crate::cmp::Ordering::{Equal, Greater, Less};
|
||||
use crate::intrinsics::const_eval_select;
|
||||
use crate::marker::PointeeSized;
|
||||
use crate::marker::{Destruct, PointeeSized};
|
||||
use crate::mem::{self, SizedTypeProperties};
|
||||
use crate::slice::{self, SliceIndex};
|
||||
|
||||
|
|
@ -1390,8 +1390,12 @@ impl<T: PointeeSized> *mut T {
|
|||
///
|
||||
/// [`ptr::drop_in_place`]: crate::ptr::drop_in_place()
|
||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn drop_in_place(self) {
|
||||
pub const unsafe fn drop_in_place(self)
|
||||
where
|
||||
T: [const] Destruct,
|
||||
{
|
||||
// SAFETY: the caller must uphold the safety contract for `drop_in_place`.
|
||||
unsafe { drop_in_place(self) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::cmp::Ordering;
|
||||
use crate::marker::{PointeeSized, Unsize};
|
||||
use crate::marker::{Destruct, PointeeSized, Unsize};
|
||||
use crate::mem::{MaybeUninit, SizedTypeProperties};
|
||||
use crate::num::NonZero;
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
|
|
@ -1118,7 +1118,11 @@ impl<T: PointeeSized> NonNull<T> {
|
|||
/// [`ptr::drop_in_place`]: crate::ptr::drop_in_place()
|
||||
#[inline(always)]
|
||||
#[stable(feature = "non_null_convenience", since = "1.80.0")]
|
||||
pub unsafe fn drop_in_place(self) {
|
||||
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
|
||||
pub const unsafe fn drop_in_place(self)
|
||||
where
|
||||
T: [const] Destruct,
|
||||
{
|
||||
// SAFETY: the caller must uphold the safety contract for `drop_in_place`.
|
||||
unsafe { ptr::drop_in_place(self.as_ptr()) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#![feature(const_cmp)]
|
||||
#![feature(const_convert)]
|
||||
#![feature(const_destruct)]
|
||||
#![feature(const_drop_in_place)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_mul_add)]
|
||||
#![feature(const_ops)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use core::cell::RefCell;
|
||||
use core::marker::Freeze;
|
||||
use core::mem::MaybeUninit;
|
||||
use core::mem::{ManuallyDrop, MaybeUninit};
|
||||
use core::num::NonZero;
|
||||
use core::ptr;
|
||||
use core::ptr::*;
|
||||
|
|
@ -1045,3 +1045,42 @@ fn test_ptr_default() {
|
|||
let default = PtrMutDefaultTest::default();
|
||||
assert!(default.ptr.is_null());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_const_drop_in_place() {
|
||||
const COUNTER: usize = {
|
||||
let mut counter = 0;
|
||||
let counter_ptr = &raw mut counter;
|
||||
|
||||
// only exists to make `Drop` indirect impl
|
||||
#[allow(dead_code)]
|
||||
struct Test(Dropped);
|
||||
|
||||
struct Dropped(*mut usize);
|
||||
impl const Drop for Dropped {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
*self.0 += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut one = ManuallyDrop::new(Test(Dropped(counter_ptr)));
|
||||
let mut two = ManuallyDrop::new(Test(Dropped(counter_ptr)));
|
||||
let mut three = ManuallyDrop::new(Test(Dropped(counter_ptr)));
|
||||
assert!(counter == 0);
|
||||
unsafe {
|
||||
ManuallyDrop::drop(&mut one);
|
||||
}
|
||||
assert!(counter == 1);
|
||||
unsafe {
|
||||
ManuallyDrop::drop(&mut two);
|
||||
}
|
||||
assert!(counter == 2);
|
||||
unsafe {
|
||||
ManuallyDrop::drop(&mut three);
|
||||
}
|
||||
counter
|
||||
};
|
||||
assert_eq!(COUNTER, 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
error: Undefined Behavior: trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location
|
||||
--> RUSTLIB/core/src/ptr/mod.rs:LL:CC
|
||||
|
|
||||
LL | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at ALLOC[0x0..0x1]
|
||||
LL | / pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
|
||||
LL | | where
|
||||
LL | | T: [const] Destruct,
|
||||
| |________________________^ this error occurs as part of retag at ALLOC[0x0..0x1]
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN)
|
||||
--> RUSTLIB/core/src/ptr/mod.rs:LL:CC
|
||||
|
|
||||
LL | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
||||
LL | / pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
|
||||
LL | | where
|
||||
LL | | T: [const] Destruct,
|
||||
| |________________________^ Undefined Behavior occurred here
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue