Skip to content

Commit db531fb

Browse files
committed
Unstably constify ptr::drop_in_place and related methods
1 parent a1208bf commit db531fb

File tree

9 files changed

+84
-14
lines changed

9 files changed

+84
-14
lines changed

library/core/src/mem/manually_drop.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::marker::Destruct;
12
use crate::ops::{Deref, DerefMut, DerefPure};
23
use crate::ptr;
34

@@ -249,7 +250,11 @@ impl<T: ?Sized> ManuallyDrop<T> {
249250
/// [pinned]: crate::pin
250251
#[stable(feature = "manually_drop", since = "1.20.0")]
251252
#[inline]
252-
pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
253+
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
254+
pub const unsafe fn drop(slot: &mut ManuallyDrop<T>)
255+
where
256+
T: [const] Destruct,
257+
{
253258
// SAFETY: we are dropping the value pointed to by a mutable reference
254259
// which is guaranteed to be valid for writes.
255260
// It is up to the caller to make sure that `slot` isn't dropped again.

library/core/src/mem/maybe_uninit.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::any::type_name;
2+
use crate::marker::Destruct;
23
use crate::mem::ManuallyDrop;
34
use crate::{fmt, intrinsics, ptr, slice};
45

@@ -714,7 +715,11 @@ impl<T> MaybeUninit<T> {
714715
///
715716
/// [`assume_init`]: MaybeUninit::assume_init
716717
#[stable(feature = "maybe_uninit_extra", since = "1.60.0")]
717-
pub unsafe fn assume_init_drop(&mut self) {
718+
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
719+
pub const unsafe fn assume_init_drop(&mut self)
720+
where
721+
T: [const] Destruct,
722+
{
718723
// SAFETY: the caller must guarantee that `self` is initialized and
719724
// satisfies all invariants of `T`.
720725
// Dropping the value in place is safe if that is the case.
@@ -1390,7 +1395,11 @@ impl<T> [MaybeUninit<T>] {
13901395
/// behaviour.
13911396
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
13921397
#[inline(always)]
1393-
pub unsafe fn assume_init_drop(&mut self) {
1398+
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
1399+
pub const unsafe fn assume_init_drop(&mut self)
1400+
where
1401+
T: [const] Destruct,
1402+
{
13941403
if !self.is_empty() {
13951404
// SAFETY: the caller must guarantee that every element of `self`
13961405
// is initialized and satisfies all invariants of `T`.

library/core/src/ptr/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@
403403

404404
use crate::cmp::Ordering;
405405
use crate::intrinsics::const_eval_select;
406-
use crate::marker::{FnPtr, PointeeSized};
406+
use crate::marker::{Destruct, FnPtr, PointeeSized};
407407
use crate::mem::{self, MaybeUninit, SizedTypeProperties};
408408
use crate::num::NonZero;
409409
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) {
801801
#[lang = "drop_in_place"]
802802
#[allow(unconditional_recursion)]
803803
#[rustc_diagnostic_item = "ptr_drop_in_place"]
804-
pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
804+
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
805+
pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
806+
where
807+
T: [const] Destruct,
808+
{
805809
// Code here does not matter - this is replaced by the
806810
// real drop glue by the compiler.
807811

library/core/src/ptr/mut_ptr.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22
use crate::cmp::Ordering::{Equal, Greater, Less};
33
use crate::intrinsics::const_eval_select;
4-
use crate::marker::PointeeSized;
4+
use crate::marker::{Destruct, PointeeSized};
55
use crate::mem::{self, SizedTypeProperties};
66
use crate::slice::{self, SliceIndex};
77

@@ -1437,8 +1437,12 @@ impl<T: PointeeSized> *mut T {
14371437
///
14381438
/// [`ptr::drop_in_place`]: crate::ptr::drop_in_place()
14391439
#[stable(feature = "pointer_methods", since = "1.26.0")]
1440+
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
14401441
#[inline(always)]
1441-
pub unsafe fn drop_in_place(self) {
1442+
pub const unsafe fn drop_in_place(self)
1443+
where
1444+
T: [const] Destruct,
1445+
{
14421446
// SAFETY: the caller must uphold the safety contract for `drop_in_place`.
14431447
unsafe { drop_in_place(self) }
14441448
}

library/core/src/ptr/non_null.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cmp::Ordering;
2-
use crate::marker::{PointeeSized, Unsize};
2+
use crate::marker::{Destruct, PointeeSized, Unsize};
33
use crate::mem::{MaybeUninit, SizedTypeProperties};
44
use crate::num::NonZero;
55
use crate::ops::{CoerceUnsized, DispatchFromDyn};
@@ -1118,7 +1118,11 @@ impl<T: PointeeSized> NonNull<T> {
11181118
/// [`ptr::drop_in_place`]: crate::ptr::drop_in_place()
11191119
#[inline(always)]
11201120
#[stable(feature = "non_null_convenience", since = "1.80.0")]
1121-
pub unsafe fn drop_in_place(self) {
1121+
#[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")]
1122+
pub const unsafe fn drop_in_place(self)
1123+
where
1124+
T: [const] Destruct,
1125+
{
11221126
// SAFETY: the caller must uphold the safety contract for `drop_in_place`.
11231127
unsafe { ptr::drop_in_place(self.as_ptr()) }
11241128
}

library/coretests/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#![feature(clone_to_uninit)]
1818
#![feature(const_convert)]
1919
#![feature(const_destruct)]
20+
#![feature(const_drop_in_place)]
2021
#![feature(const_eval_select)]
2122
#![feature(const_ops)]
2223
#![feature(const_option_ops)]

library/coretests/tests/ptr.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::cell::RefCell;
22
use core::marker::Freeze;
3-
use core::mem::MaybeUninit;
3+
use core::mem::{ManuallyDrop, MaybeUninit};
44
use core::num::NonZero;
55
use core::ptr;
66
use core::ptr::*;
@@ -1036,3 +1036,42 @@ fn test_ptr_default() {
10361036
let default = PtrMutDefaultTest::default();
10371037
assert!(default.ptr.is_null());
10381038
}
1039+
1040+
#[test]
1041+
fn test_const_drop_in_place() {
1042+
const COUNTER: usize = {
1043+
let mut counter = 0;
1044+
let counter_ptr = &raw mut counter;
1045+
1046+
// only exists to make `Drop` indirect impl
1047+
#[allow(dead_code)]
1048+
struct Test(Dropped);
1049+
1050+
struct Dropped(*mut usize);
1051+
impl const Drop for Dropped {
1052+
fn drop(&mut self) {
1053+
unsafe {
1054+
*self.0 += 1;
1055+
}
1056+
}
1057+
}
1058+
1059+
let mut one = ManuallyDrop::new(Test(Dropped(counter_ptr)));
1060+
let mut two = ManuallyDrop::new(Test(Dropped(counter_ptr)));
1061+
let mut three = ManuallyDrop::new(Test(Dropped(counter_ptr)));
1062+
assert!(counter == 0);
1063+
unsafe {
1064+
ManuallyDrop::drop(&mut one);
1065+
}
1066+
assert!(counter == 1);
1067+
unsafe {
1068+
ManuallyDrop::drop(&mut two);
1069+
}
1070+
assert!(counter == 2);
1071+
unsafe {
1072+
ManuallyDrop::drop(&mut three);
1073+
}
1074+
counter
1075+
};
1076+
assert_eq!(COUNTER, 3);
1077+
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error: Undefined Behavior: trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location
22
--> RUSTLIB/core/src/ptr/mod.rs:LL:CC
33
|
4-
LL | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at ALLOC[0x0..0x1]
4+
LL | / pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
5+
LL | | where
6+
LL | | T: [const] Destruct,
7+
| |________________________^ this error occurs as part of retag at ALLOC[0x0..0x1]
68
|
79
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
810
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information

src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN)
22
--> RUSTLIB/core/src/ptr/mod.rs:LL:CC
33
|
4-
LL | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
4+
LL | / pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
5+
LL | | where
6+
LL | | T: [const] Destruct,
7+
| |________________________^ Undefined Behavior occurred here
68
|
79
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
810
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

0 commit comments

Comments
 (0)