use MaybeDangling in ManuallyDrop

This commit is contained in:
Waffle Lapkin 2025-10-29 19:26:26 +01:00
parent 4ea5cac7d4
commit 722e3102a2
No known key found for this signature in database
6 changed files with 75 additions and 18 deletions

View file

@ -1,4 +1,7 @@
use crate::marker::Destruct;
use crate::cmp::Ordering;
use crate::hash::{Hash, Hasher};
use crate::marker::{Destruct, StructuralPartialEq};
use crate::mem::MaybeDangling;
use crate::ops::{Deref, DerefMut, DerefPure};
use crate::ptr;
@ -152,11 +155,11 @@ use crate::ptr;
/// [`MaybeUninit`]: crate::mem::MaybeUninit
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(transparent)]
#[rustc_pub_transparent]
pub struct ManuallyDrop<T: ?Sized> {
value: T,
value: MaybeDangling<T>,
}
impl<T> ManuallyDrop<T> {
@ -179,7 +182,7 @@ impl<T> ManuallyDrop<T> {
#[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")]
#[inline(always)]
pub const fn new(value: T) -> ManuallyDrop<T> {
ManuallyDrop { value }
ManuallyDrop { value: MaybeDangling::new(value) }
}
/// Extracts the value from the `ManuallyDrop` container.
@ -197,7 +200,7 @@ impl<T> ManuallyDrop<T> {
#[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")]
#[inline(always)]
pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
slot.value
slot.value.into_inner()
}
/// Takes the value from the `ManuallyDrop<T>` container out.
@ -222,7 +225,7 @@ impl<T> ManuallyDrop<T> {
pub const unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
// SAFETY: we are reading from a reference, which is guaranteed
// to be valid for reads.
unsafe { ptr::read(&slot.value) }
unsafe { ptr::read(slot.value.as_ref()) }
}
}
@ -259,7 +262,7 @@ impl<T: ?Sized> ManuallyDrop<T> {
// 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.
unsafe { ptr::drop_in_place(&mut slot.value) }
unsafe { ptr::drop_in_place(slot.value.as_mut()) }
}
}
@ -269,7 +272,7 @@ impl<T: ?Sized> const Deref for ManuallyDrop<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.value
self.value.as_ref()
}
}
@ -278,9 +281,43 @@ impl<T: ?Sized> const Deref for ManuallyDrop<T> {
impl<T: ?Sized> const DerefMut for ManuallyDrop<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut T {
&mut self.value
self.value.as_mut()
}
}
#[unstable(feature = "deref_pure_trait", issue = "87121")]
unsafe impl<T: ?Sized> DerefPure for ManuallyDrop<T> {}
#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized + Eq> Eq for ManuallyDrop<T> {}
#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized + PartialEq> PartialEq for ManuallyDrop<T> {
fn eq(&self, other: &Self) -> bool {
self.value.as_ref().eq(other.value.as_ref())
}
}
#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> StructuralPartialEq for ManuallyDrop<T> {}
#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized + Ord> Ord for ManuallyDrop<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.value.as_ref().cmp(other.value.as_ref())
}
}
#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized + PartialOrd> PartialOrd for ManuallyDrop<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.value.as_ref().partial_cmp(other.value.as_ref())
}
}
#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized + Hash> Hash for ManuallyDrop<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.value.as_ref().hash(state);
}
}

View file

@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes
print-type-size variant `Panicked`: 0 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes
print-type-size field `.value`: 3077 bytes
print-type-size type: `std::mem::MaybeDangling<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes
print-type-size field `.0`: 3077 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 3077 bytes
print-type-size field `.uninit`: 0 bytes
@ -36,6 +38,8 @@ print-type-size variant `Panicked`: 1025 bytes
print-type-size upvar `.fut`: 1025 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes
print-type-size field `.value`: 1025 bytes
print-type-size type: `std::mem::MaybeDangling<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes
print-type-size field `.0`: 1025 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1025 bytes
print-type-size field `.uninit`: 0 bytes
@ -85,6 +89,10 @@ print-type-size type: `std::mem::ManuallyDrop<bool>`: 1 bytes, alignment: 1 byte
print-type-size field `.value`: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeDangling<bool>`: 1 bytes, alignment: 1 bytes
print-type-size field `.0`: 1 bytes
print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size field `.0`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<bool>`: 1 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1 bytes
print-type-size field `.uninit`: 0 bytes

View file

@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes
print-type-size variant `Panicked`: 0 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes
print-type-size field `.value`: 3075 bytes
print-type-size type: `std::mem::MaybeDangling<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes
print-type-size field `.0`: 3075 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 3075 bytes
print-type-size field `.uninit`: 0 bytes
@ -24,6 +26,8 @@ print-type-size variant `Panicked`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes
print-type-size field `.value`: 2050 bytes
print-type-size type: `std::mem::MaybeDangling<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes
print-type-size field `.0`: 2050 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 2050 bytes
print-type-size field `.uninit`: 0 bytes
@ -41,6 +45,8 @@ print-type-size variant `Panicked`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes
print-type-size field `.value`: 1025 bytes
print-type-size type: `std::mem::MaybeDangling<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes
print-type-size field `.0`: 1025 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1025 bytes
print-type-size field `.uninit`: 0 bytes

View file

@ -12,6 +12,8 @@ print-type-size variant `Panicked`: 8192 bytes
print-type-size upvar `.arg`: 8192 bytes
print-type-size type: `std::mem::ManuallyDrop<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes
print-type-size field `.value`: 8192 bytes
print-type-size type: `std::mem::MaybeDangling<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes
print-type-size field `.0`: 8192 bytes
print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 8192 bytes
print-type-size field `.uninit`: 0 bytes
@ -47,6 +49,8 @@ print-type-size type: `std::ptr::NonNull<std::ptr::metadata::VTable>`: 8 bytes,
print-type-size field `.pointer`: 8 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size field `.0`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1 bytes
print-type-size field `.uninit`: 0 bytes

View file

@ -11,6 +11,8 @@ print-type-size variant `Returned`: 0 bytes
print-type-size variant `Panicked`: 0 bytes
print-type-size type: `std::mem::ManuallyDrop<i32>`: 4 bytes, alignment: 4 bytes
print-type-size field `.value`: 4 bytes
print-type-size type: `std::mem::MaybeDangling<i32>`: 4 bytes, alignment: 4 bytes
print-type-size field `.0`: 4 bytes
print-type-size type: `std::mem::MaybeUninit<i32>`: 4 bytes, alignment: 4 bytes
print-type-size variant `MaybeUninit`: 4 bytes
print-type-size field `.uninit`: 0 bytes

View file

@ -68,7 +68,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::concrete).10))
span: $DIR/offset_of.rs:37:5: 1433:57 (#0)
span: $DIR/offset_of.rs:37:5: 1437:57 (#0)
}
}
Stmt {
@ -117,7 +117,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::concrete).20))
span: $DIR/offset_of.rs:38:5: 1433:57 (#0)
span: $DIR/offset_of.rs:38:5: 1437:57 (#0)
}
}
Stmt {
@ -166,7 +166,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::concrete).30))
span: $DIR/offset_of.rs:39:5: 1433:57 (#0)
span: $DIR/offset_of.rs:39:5: 1437:57 (#0)
}
}
Stmt {
@ -215,7 +215,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::concrete).40))
span: $DIR/offset_of.rs:40:5: 1433:57 (#0)
span: $DIR/offset_of.rs:40:5: 1437:57 (#0)
}
}
Stmt {
@ -264,7 +264,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::concrete).50))
span: $DIR/offset_of.rs:41:5: 1433:57 (#0)
span: $DIR/offset_of.rs:41:5: 1437:57 (#0)
}
}
]
@ -864,7 +864,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::generic).12))
span: $DIR/offset_of.rs:45:5: 1433:57 (#0)
span: $DIR/offset_of.rs:45:5: 1437:57 (#0)
}
}
Stmt {
@ -913,7 +913,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::generic).24))
span: $DIR/offset_of.rs:46:5: 1433:57 (#0)
span: $DIR/offset_of.rs:46:5: 1437:57 (#0)
}
}
Stmt {
@ -962,7 +962,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::generic).36))
span: $DIR/offset_of.rs:47:5: 1433:57 (#0)
span: $DIR/offset_of.rs:47:5: 1437:57 (#0)
}
}
Stmt {
@ -1011,7 +1011,7 @@ body:
)
else_block: None
lint_level: Explicit(HirId(DefId(offset_of::generic).48))
span: $DIR/offset_of.rs:48:5: 1433:57 (#0)
span: $DIR/offset_of.rs:48:5: 1437:57 (#0)
}
}
]