Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion library/core/src/mem/manually_drop.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::marker::Destruct;
use crate::ops::{Deref, DerefMut, DerefPure};
use crate::ptr;

Expand Down Expand Up @@ -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.
Expand Down
13 changes: 11 additions & 2 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::any::type_name;
use crate::marker::Destruct;
use crate::mem::ManuallyDrop;
use crate::{fmt, intrinsics, ptr, slice};

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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`.
Expand Down
8 changes: 6 additions & 2 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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.

Expand Down
8 changes: 6 additions & 2 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -1438,8 +1438,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) }
}
Expand Down
8 changes: 6 additions & 2 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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()) }
}
Expand Down
1 change: 1 addition & 0 deletions library/coretests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#![feature(clone_to_uninit)]
#![feature(const_convert)]
#![feature(const_destruct)]
#![feature(const_drop_in_place)]
#![feature(const_eval_select)]
#![feature(const_ops)]
#![feature(const_option_ops)]
Expand Down
41 changes: 40 additions & 1 deletion library/coretests/tests/ptr.rs
Original file line number Diff line number Diff line change
@@ -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::*;
Expand Down Expand Up @@ -1036,3 +1036,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);
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading