Skip to content

Commit 57c3635

Browse files
Add From<T> for Lazy{Cell,Lock}<T, F>
1 parent 39f4150 commit 57c3635

File tree

7 files changed

+51
-17
lines changed

7 files changed

+51
-17
lines changed

library/core/src/cell/lazy.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,16 @@ impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
370370
}
371371
}
372372

373+
#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")]
374+
impl<T, F> From<T> for LazyCell<T, F> {
375+
/// Constructs a `LazyCell` that starts already initialized
376+
/// with the provided value.
377+
#[inline]
378+
fn from(value: T) -> Self {
379+
Self { state: UnsafeCell::new(State::Init(value)) }
380+
}
381+
}
382+
373383
#[cold]
374384
#[inline(never)]
375385
const fn panic_poisoned() -> ! {

library/std/src/backtrace/tests.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ fn generate_fake_frames() -> Vec<BacktraceFrame> {
4444
#[test]
4545
fn test_debug() {
4646
let backtrace = Backtrace {
47-
inner: Inner::Captured(LazyLock::preinit(Capture {
48-
actual_start: 1,
49-
frames: generate_fake_frames(),
50-
})),
47+
inner: Inner::Captured(
48+
(Capture { actual_start: 1, frames: generate_fake_frames() }).into(),
49+
),
5150
};
5251

5352
#[rustfmt::skip]
@@ -66,10 +65,9 @@ fn test_debug() {
6665
#[test]
6766
fn test_frames() {
6867
let backtrace = Backtrace {
69-
inner: Inner::Captured(LazyLock::preinit(Capture {
70-
actual_start: 1,
71-
frames: generate_fake_frames(),
72-
})),
68+
inner: Inner::Captured(
69+
(Capture { actual_start: 1, frames: generate_fake_frames() }).into(),
70+
),
7371
};
7472

7573
let frames = backtrace.frames();

library/std/src/sync/lazy_lock.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,6 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
105105
LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) }
106106
}
107107

108-
/// Creates a new lazy value that is already initialized.
109-
#[inline]
110-
#[cfg(test)]
111-
pub(crate) fn preinit(value: T) -> LazyLock<T, F> {
112-
let once = Once::new();
113-
once.call_once(|| {});
114-
LazyLock { once, data: UnsafeCell::new(Data { value: ManuallyDrop::new(value) }) }
115-
}
116-
117108
/// Consumes this `LazyLock` returning the stored value.
118109
///
119110
/// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
@@ -401,6 +392,19 @@ impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
401392
}
402393
}
403394

395+
#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")]
396+
impl<T, F> From<T> for LazyLock<T, F> {
397+
/// Constructs a `LazyLock` that starts already initialized
398+
/// with the provided value.
399+
#[inline]
400+
fn from(value: T) -> Self {
401+
LazyLock {
402+
once: Once::new_complete(),
403+
data: UnsafeCell::new(Data { value: ManuallyDrop::new(value) }),
404+
}
405+
}
406+
}
407+
404408
#[cold]
405409
#[inline(never)]
406410
fn panic_poisoned() -> ! {

library/std/src/sync/poison/once.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ impl Once {
8282
Once { inner: sys::Once::new() }
8383
}
8484

85+
/// Creates a new `Once` value that starts already completed.
86+
#[inline]
87+
#[must_use]
88+
pub(crate) const fn new_complete() -> Once {
89+
Once { inner: sys::Once::new_complete() }
90+
}
91+
8592
/// Performs an initialization routine once and only once. The given closure
8693
/// will be executed if this is the first time `call_once` has been called,
8794
/// and otherwise the routine will *not* be invoked.

library/std/src/sys/sync/once/futex.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ impl Once {
7575
Once { state_and_queued: Futex::new(INCOMPLETE) }
7676
}
7777

78+
#[inline]
79+
pub const fn new_complete() -> Once {
80+
Once { state_and_queued: Futex::new(COMPLETE) }
81+
}
82+
7883
#[inline]
7984
pub fn is_completed(&self) -> bool {
8085
// Use acquire ordering to make all initialization changes visible to the

library/std/src/sys/sync/once/no_threads.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ impl Once {
3939
Once { state: Cell::new(State::Incomplete) }
4040
}
4141

42+
#[inline]
43+
pub const fn new_complete() -> Once {
44+
Once { state: Cell::new(State::Complete) }
45+
}
46+
4247
#[inline]
4348
pub fn is_completed(&self) -> bool {
4449
self.state.get() == State::Complete

library/std/src/sys/sync/once/queue.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ impl Once {
121121
Once { state_and_queue: AtomicPtr::new(ptr::without_provenance_mut(INCOMPLETE)) }
122122
}
123123

124+
#[inline]
125+
pub const fn new_complete() -> Once {
126+
Once { state_and_queue: AtomicPtr::new(ptr::without_provenance_mut(COMPLETE)) }
127+
}
128+
124129
#[inline]
125130
pub fn is_completed(&self) -> bool {
126131
// An `Acquire` load is enough because that makes all the initialization

0 commit comments

Comments
 (0)