diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 1cce36606d2c0..1f6127b84b95b 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -430,3 +430,12 @@ impl Error for ThinBox { self.deref().source() } } + +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "thin_box", issue = "92791")] +impl From for ThinBox { + #[inline(always)] + fn from(value: T) -> Self { + Self::new(value) + } +} diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 529b583cdd2bc..47c962606b198 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -3816,6 +3816,15 @@ impl AsMut for UniqueRc { #[unstable(feature = "unique_rc_arc", issue = "112566")] impl Unpin for UniqueRc {} +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl From for UniqueRc { + #[inline(always)] + fn from(value: T) -> Self { + Self::new(value) + } +} + #[unstable(feature = "unique_rc_arc", issue = "112566")] impl PartialEq for UniqueRc { /// Equality for two `UniqueRc`s. diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index a21b6880674c6..836e66af2765d 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -4242,6 +4242,15 @@ impl AsMut for UniqueArc { } } +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl From for UniqueArc { + #[inline(always)] + fn from(value: T) -> Self { + Self::new(value) + } +} + #[unstable(feature = "unique_rc_arc", issue = "112566")] impl Unpin for UniqueArc {} diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index a1bd4c8571706..affff80210114 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -370,6 +370,16 @@ impl fmt::Debug for LazyCell { } } +#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")] +impl From for LazyCell { + /// Constructs a `LazyCell` that starts already initialized + /// with the provided value. + #[inline] + fn from(value: T) -> Self { + Self { state: UnsafeCell::new(State::Init(value)) } + } +} + #[cold] #[inline(never)] const fn panic_poisoned() -> ! { diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs index a60f0799c0eae..283e113c9c5e7 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -311,3 +311,16 @@ impl AsyncIterator for AssertUnwindSafe { self.0.size_hint() } } + +/// If a value's type is already `UnwindSafe`, +/// wrapping it in `AssertUnwindSafe` is never incorrect. +#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")] +impl From for AssertUnwindSafe +where + T: UnwindSafe, +{ + #[inline(always)] + fn from(value: T) -> Self { + Self(value) + } +} diff --git a/library/std/src/backtrace/tests.rs b/library/std/src/backtrace/tests.rs index 174d62813bd58..b68b528c18668 100644 --- a/library/std/src/backtrace/tests.rs +++ b/library/std/src/backtrace/tests.rs @@ -44,10 +44,9 @@ fn generate_fake_frames() -> Vec { #[test] fn test_debug() { let backtrace = Backtrace { - inner: Inner::Captured(LazyLock::preinit(Capture { - actual_start: 1, - frames: generate_fake_frames(), - })), + inner: Inner::Captured( + (Capture { actual_start: 1, frames: generate_fake_frames() }).into(), + ), }; #[rustfmt::skip] @@ -66,10 +65,9 @@ fn test_debug() { #[test] fn test_frames() { let backtrace = Backtrace { - inner: Inner::Captured(LazyLock::preinit(Capture { - actual_start: 1, - frames: generate_fake_frames(), - })), + inner: Inner::Captured( + (Capture { actual_start: 1, frames: generate_fake_frames() }).into(), + ), }; let frames = backtrace.frames(); diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 3231125f7a13a..def40a3d9696b 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -105,15 +105,6 @@ impl T> LazyLock { LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) } } - /// Creates a new lazy value that is already initialized. - #[inline] - #[cfg(test)] - pub(crate) fn preinit(value: T) -> LazyLock { - let once = Once::new(); - once.call_once(|| {}); - LazyLock { once, data: UnsafeCell::new(Data { value: ManuallyDrop::new(value) }) } - } - /// Consumes this `LazyLock` returning the stored value. /// /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. @@ -401,6 +392,19 @@ impl fmt::Debug for LazyLock { } } +#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")] +impl From for LazyLock { + /// Constructs a `LazyLock` that starts already initialized + /// with the provided value. + #[inline] + fn from(value: T) -> Self { + LazyLock { + once: Once::new_complete(), + data: UnsafeCell::new(Data { value: ManuallyDrop::new(value) }), + } + } +} + #[cold] #[inline(never)] fn panic_poisoned() -> ! { diff --git a/library/std/src/sync/poison/once.rs b/library/std/src/sync/poison/once.rs index faf2913c54730..c79f75978cf57 100644 --- a/library/std/src/sync/poison/once.rs +++ b/library/std/src/sync/poison/once.rs @@ -82,6 +82,13 @@ impl Once { Once { inner: sys::Once::new() } } + /// Creates a new `Once` value that starts already completed. + #[inline] + #[must_use] + pub(crate) const fn new_complete() -> Once { + Once { inner: sys::Once::new_complete() } + } + /// Performs an initialization routine once and only once. The given closure /// will be executed if this is the first time `call_once` has been called, /// and otherwise the routine will *not* be invoked. diff --git a/library/std/src/sys/sync/once/futex.rs b/library/std/src/sys/sync/once/futex.rs index 407fdcebcf5cc..ebdf62f6a3851 100644 --- a/library/std/src/sys/sync/once/futex.rs +++ b/library/std/src/sys/sync/once/futex.rs @@ -75,6 +75,11 @@ impl Once { Once { state_and_queued: Futex::new(INCOMPLETE) } } + #[inline] + pub const fn new_complete() -> Once { + Once { state_and_queued: Futex::new(COMPLETE) } + } + #[inline] pub fn is_completed(&self) -> bool { // Use acquire ordering to make all initialization changes visible to the diff --git a/library/std/src/sys/sync/once/no_threads.rs b/library/std/src/sys/sync/once/no_threads.rs index 2568059cfe3a8..07ae4abdb2457 100644 --- a/library/std/src/sys/sync/once/no_threads.rs +++ b/library/std/src/sys/sync/once/no_threads.rs @@ -39,6 +39,11 @@ impl Once { Once { state: Cell::new(State::Incomplete) } } + #[inline] + pub const fn new_complete() -> Once { + Once { state: Cell::new(State::Complete) } + } + #[inline] pub fn is_completed(&self) -> bool { self.state.get() == State::Complete diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs index 49e15d65f25a2..424a4a117f07e 100644 --- a/library/std/src/sys/sync/once/queue.rs +++ b/library/std/src/sys/sync/once/queue.rs @@ -121,6 +121,11 @@ impl Once { Once { state_and_queue: AtomicPtr::new(ptr::without_provenance_mut(INCOMPLETE)) } } + #[inline] + pub const fn new_complete() -> Once { + Once { state_and_queue: AtomicPtr::new(ptr::without_provenance_mut(COMPLETE)) } + } + #[inline] pub fn is_completed(&self) -> bool { // An `Acquire` load is enough because that makes all the initialization