Skip to content

Commit 8fe1cea

Browse files
committed
use MaybeDangling in std
2 parents e71abfd + 7180f06 commit 8fe1cea

File tree

8 files changed

+47
-25
lines changed

8 files changed

+47
-25
lines changed

compiler/rustc_hir/src/lang_items.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ language_item_table! {
353353

354354
PhantomData, sym::phantom_data, phantom_data, Target::Struct, GenericRequirement::Exact(1);
355355

356-
ManuallyDrop, sym::manually_drop, manually_drop, Target::Struct, GenericRequirement::None;
356+
ManuallyDrop, sym::manually_drop, manually_drop, Target::Struct, GenericRequirement::Exact(1);
357+
MaybeDangling, sym::maybe_dangling, maybe_dangling, Target::Struct, GenericRequirement::Exact(1);
357358
BikeshedGuaranteedNoDrop, sym::bikeshed_guaranteed_no_drop, bikeshed_guaranteed_no_drop, Target::Trait, GenericRequirement::Exact(0);
358359

359360
MaybeUninit, sym::maybe_uninit, maybe_uninit, Target::Union, GenericRequirement::None;

compiler/rustc_middle/src/ty/adt.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ bitflags::bitflags! {
5959
const IS_PIN = 1 << 11;
6060
/// Indicates whether the type is `#[pin_project]`.
6161
const IS_PIN_PROJECT = 1 << 12;
62+
/// Indicates whether the type is `MaybeDangling<_>`.
63+
const IS_MAYBE_DANGLING = 1 << 13;
6264
}
6365
}
6466
rustc_data_structures::external_bitflags_debug! { AdtFlags }
@@ -315,6 +317,9 @@ impl AdtDefData {
315317
if tcx.is_lang_item(did, LangItem::ManuallyDrop) {
316318
flags |= AdtFlags::IS_MANUALLY_DROP;
317319
}
320+
if tcx.is_lang_item(did, LangItem::MaybeDangling) {
321+
flags |= AdtFlags::IS_MAYBE_DANGLING;
322+
}
318323
if tcx.is_lang_item(did, LangItem::UnsafeCell) {
319324
flags |= AdtFlags::IS_UNSAFE_CELL;
320325
}
@@ -439,6 +444,12 @@ impl<'tcx> AdtDef<'tcx> {
439444
self.flags().contains(AdtFlags::IS_MANUALLY_DROP)
440445
}
441446

447+
/// Returns `true` if this is `MaybeDangling<T>`.
448+
#[inline]
449+
pub fn is_maybe_dangling(self) -> bool {
450+
self.flags().contains(AdtFlags::IS_MAYBE_DANGLING)
451+
}
452+
442453
/// Returns `true` if this is `Pin<T>`.
443454
#[inline]
444455
pub fn is_pin(self) -> bool {

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,12 @@ where
10531053
})
10541054
}
10551055

1056+
ty::Adt(adt_def, ..) if adt_def.is_maybe_dangling() => {
1057+
// FIXME: what is the exact effect of maybe dangling?
1058+
Self::ty_and_layout_pointee_info_at(this.field(cx, 0), cx, offset)
1059+
.map(|info| PointeeInfo { safe: None, ..info })
1060+
}
1061+
10561062
_ => {
10571063
let mut data_variant = match &this.variants {
10581064
// Within the discriminant field, only the niche itself is
@@ -1091,7 +1097,7 @@ where
10911097
}
10921098
}
10931099
Variants::Multiple { .. } => None,
1094-
_ => Some(this),
1100+
Variants::Empty | Variants::Single { .. } => Some(this),
10951101
};
10961102

10971103
if let Some(variant) = data_variant

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,7 @@ symbols! {
14011401
maxnumf128,
14021402
may_dangle,
14031403
may_unwind,
1404+
maybe_dangling,
14041405
maybe_uninit,
14051406
maybe_uninit_uninit,
14061407
maybe_uninit_zeroed,

library/core/src/mem/maybe_dangling.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use crate::{mem, ptr};
6161
#[repr(transparent)]
6262
#[rustc_pub_transparent]
6363
#[derive(Debug, Copy, Clone, Default)]
64+
#[lang = "maybe_dangling"]
6465
pub struct MaybeDangling<P: ?Sized>(P);
6566

6667
impl<P: ?Sized> MaybeDangling<P> {

library/std/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@
345345
#![feature(int_from_ascii)]
346346
#![feature(ip)]
347347
#![feature(lazy_get)]
348+
#![feature(maybe_dangling)]
348349
#![feature(maybe_uninit_array_assume_init)]
349350
#![feature(panic_can_unwind)]
350351
#![feature(panic_internals)]

library/std/src/thread/lifecycle.rs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use super::thread::Thread;
77
use super::{Result, spawnhook};
88
use crate::cell::UnsafeCell;
99
use crate::marker::PhantomData;
10-
use crate::mem::{ManuallyDrop, MaybeUninit};
10+
use crate::mem::MaybeDangling;
1111
use crate::sync::Arc;
1212
use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
1313
use crate::sys::thread as imp;
@@ -58,29 +58,8 @@ where
5858
Arc::new(Packet { scope: scope_data, result: UnsafeCell::new(None), _marker: PhantomData });
5959
let their_packet = my_packet.clone();
6060

61-
// Pass `f` in `MaybeUninit` because actually that closure might *run longer than the lifetime of `F`*.
61+
// Pass `f` in `MaybeDangling` because actually that closure might *run longer than the lifetime of `F`*.
6262
// See <https://github.com/rust-lang/rust/issues/101983> for more details.
63-
// To prevent leaks we use a wrapper that drops its contents.
64-
#[repr(transparent)]
65-
struct MaybeDangling<T>(MaybeUninit<T>);
66-
impl<T> MaybeDangling<T> {
67-
fn new(x: T) -> Self {
68-
MaybeDangling(MaybeUninit::new(x))
69-
}
70-
fn into_inner(self) -> T {
71-
// Make sure we don't drop.
72-
let this = ManuallyDrop::new(self);
73-
// SAFETY: we are always initialized.
74-
unsafe { this.0.assume_init_read() }
75-
}
76-
}
77-
impl<T> Drop for MaybeDangling<T> {
78-
fn drop(&mut self) {
79-
// SAFETY: we are always initialized.
80-
unsafe { self.0.assume_init_drop() };
81-
}
82-
}
83-
8463
let f = MaybeDangling::new(f);
8564

8665
// The entrypoint of the Rust thread, after platform-specific thread
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
2+
#![crate_type = "lib"]
3+
4+
use std::mem::ManuallyDrop;
5+
6+
// CHECK: define noundef nonnull ptr @f(ptr noundef nonnull readnone returned {{(captures\(ret: address, provenance\))?}} %x) unnamed_addr
7+
#[no_mangle]
8+
pub fn f(x: ManuallyDrop<Box<u8>>) -> ManuallyDrop<Box<u8>> {
9+
x
10+
}
11+
12+
// CHECK: define noundef nonnull ptr @g(ptr noundef nonnull readnone returned {{(captures\(ret: address, provenance\))?}} %x) unnamed_addr
13+
#[no_mangle]
14+
pub fn g(x: ManuallyDrop<&u8>) -> ManuallyDrop<&u8> {
15+
x
16+
}
17+
18+
// CHECK: define noundef nonnull ptr @h(ptr noundef nonnull readnone returned {{(captures\(ret: address, provenance\))?}} %x) unnamed_addr
19+
#[no_mangle]
20+
pub fn h(x: ManuallyDrop<&mut u8>) -> ManuallyDrop<&mut u8> {
21+
x
22+
}

0 commit comments

Comments
 (0)