Skip to content
Open
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
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@
#![feature(ip)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
#![feature(maybe_dangling)]
#![feature(maybe_uninit_array_assume_init)]
#![feature(maybe_uninit_fill)]
#![feature(panic_can_unwind)]
Expand Down
25 changes: 2 additions & 23 deletions library/std/src/thread/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::thread::Thread;
use super::{Result, spawnhook};
use crate::cell::UnsafeCell;
use crate::marker::PhantomData;
use crate::mem::{ManuallyDrop, MaybeUninit};
use crate::mem::MaybeDangling;
use crate::sync::Arc;
use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
use crate::sys::{AsInner, IntoInner, thread as imp};
Expand Down Expand Up @@ -57,29 +57,8 @@ where
Arc::new(Packet { scope: scope_data, result: UnsafeCell::new(None), _marker: PhantomData });
let their_packet = my_packet.clone();

// Pass `f` in `MaybeUninit` because actually that closure might *run longer than the lifetime of `F`*.
// Pass `f` in `MaybeDangling` because actually that closure might *run longer than the lifetime of `F`*.
// See <https://github.com/rust-lang/rust/issues/101983> for more details.
// To prevent leaks we use a wrapper that drops its contents.
#[repr(transparent)]
struct MaybeDangling<T>(MaybeUninit<T>);
impl<T> MaybeDangling<T> {
fn new(x: T) -> Self {
MaybeDangling(MaybeUninit::new(x))
}
fn into_inner(self) -> T {
// Make sure we don't drop.
let this = ManuallyDrop::new(self);
// SAFETY: we are always initialized.
unsafe { this.0.assume_init_read() }
}
}
impl<T> Drop for MaybeDangling<T> {
fn drop(&mut self) {
// SAFETY: we are always initialized.
unsafe { self.0.assume_init_drop() };
}
}

let f = MaybeDangling::new(f);

// The entrypoint of the Rust thread, after platform-specific thread
Expand Down
Loading