From 722e3102a22c529bade40c61f63bb3d88845360a Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Wed, 29 Oct 2025 19:26:26 +0100 Subject: [PATCH] use `MaybeDangling` in `ManuallyDrop` --- library/core/src/mem/manually_drop.rs | 55 ++++++++++++++++--- .../future-sizes/async-awaiting-fut.stdout | 8 +++ .../async-await/future-sizes/large-arg.stdout | 6 ++ tests/ui/print_type_sizes/async.stdout | 4 ++ .../coroutine_discr_placement.stdout | 2 + tests/ui/thir-print/offset_of.stdout | 18 +++--- 6 files changed, 75 insertions(+), 18 deletions(-) diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 7d49da850957..74f917bcf1cc 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -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 { - value: T, + value: MaybeDangling, } impl ManuallyDrop { @@ -179,7 +182,7 @@ impl ManuallyDrop { #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] pub const fn new(value: T) -> ManuallyDrop { - ManuallyDrop { value } + ManuallyDrop { value: MaybeDangling::new(value) } } /// Extracts the value from the `ManuallyDrop` container. @@ -197,7 +200,7 @@ impl ManuallyDrop { #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] pub const fn into_inner(slot: ManuallyDrop) -> T { - slot.value + slot.value.into_inner() } /// Takes the value from the `ManuallyDrop` container out. @@ -222,7 +225,7 @@ impl ManuallyDrop { pub const unsafe fn take(slot: &mut ManuallyDrop) -> 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 ManuallyDrop { // 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 const Deref for ManuallyDrop { type Target = T; #[inline(always)] fn deref(&self) -> &T { - &self.value + self.value.as_ref() } } @@ -278,9 +281,43 @@ impl const Deref for ManuallyDrop { impl const DerefMut for ManuallyDrop { #[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 DerefPure for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Eq for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialEq for ManuallyDrop { + fn eq(&self, other: &Self) -> bool { + self.value.as_ref().eq(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl StructuralPartialEq for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Ord for ManuallyDrop { + fn cmp(&self, other: &Self) -> Ordering { + self.value.as_ref().cmp(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialOrd for ManuallyDrop { + fn partial_cmp(&self, other: &Self) -> Option { + self.value.as_ref().partial_cmp(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Hash for ManuallyDrop { + fn hash(&self, state: &mut H) { + self.value.as_ref().hash(state); + } +} diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout index b30c15bcbe6e..13f03ffa65b5 100644 --- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout +++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout @@ -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`: 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`: 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`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/async-await/future-sizes/large-arg.stdout b/tests/ui/async-await/future-sizes/large-arg.stdout index e00420d1493f..d51afa33595c 100644 --- a/tests/ui/async-await/future-sizes/large-arg.stdout +++ b/tests/ui/async-await/future-sizes/large-arg.stdout @@ -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 diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index d3d6b6471c6e..d2adff80e3c9 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -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`: 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 diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout index 4ce1ce46f6e8..b51beb514ba8 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout @@ -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`: 4 bytes, alignment: 4 bytes print-type-size field `.value`: 4 bytes +print-type-size type: `std::mem::MaybeDangling`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `std::mem::MaybeUninit`: 4 bytes, alignment: 4 bytes print-type-size variant `MaybeUninit`: 4 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index 846817f47528..ab924091ba7a 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -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) } } ]