Skip to content

Commit 6bdc342

Browse files
committed
Auto merge of #146013 - Jules-Bertholet:from-wrapper, r=Mark-Simulacrum
Add `From` impls for wrapper types - ~`From<T: Copy> for ManuallyDrop<T>`~ - `From<T: UnwindSafe> for AssertUnwindSafe<T>` - `From<T> for LazyCell<T, F>` - `From<T> for LazyLock<T, F>` - `From<T> for ThinBox<T>` (unstable) - `From<T> for UniqueRc<T>` (unstable) - `From<T> for UniqueArc<T>` (unstable) @rustbot label T-libs-api needs-fcp Also needs a crater run, as the insta-stable impls are technically breaking changes.
2 parents 3645249 + c5c1d94 commit 6bdc342

11 files changed

Lines changed: 91 additions & 17 deletions

File tree

library/alloc/src/boxed/thin.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,12 @@ impl<T: ?Sized + Error> Error for ThinBox<T> {
430430
self.deref().source()
431431
}
432432
}
433+
434+
#[cfg(not(no_global_oom_handling))]
435+
#[unstable(feature = "thin_box", issue = "92791")]
436+
impl<T> From<T> for ThinBox<T> {
437+
#[inline(always)]
438+
fn from(value: T) -> Self {
439+
Self::new(value)
440+
}
441+
}

library/alloc/src/rc.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3980,6 +3980,15 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for UniqueRc<T, A> {
39803980
#[unstable(feature = "unique_rc_arc", issue = "112566")]
39813981
impl<T: ?Sized, A: Allocator> Unpin for UniqueRc<T, A> {}
39823982

3983+
#[cfg(not(no_global_oom_handling))]
3984+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3985+
impl<T> From<T> for UniqueRc<T> {
3986+
#[inline(always)]
3987+
fn from(value: T) -> Self {
3988+
Self::new(value)
3989+
}
3990+
}
3991+
39833992
#[unstable(feature = "unique_rc_arc", issue = "112566")]
39843993
impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for UniqueRc<T, A> {
39853994
/// Equality for two `UniqueRc`s.

library/alloc/src/sync.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4424,6 +4424,15 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for UniqueArc<T, A> {
44244424
}
44254425
}
44264426

4427+
#[cfg(not(no_global_oom_handling))]
4428+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
4429+
impl<T> From<T> for UniqueArc<T> {
4430+
#[inline(always)]
4431+
fn from(value: T) -> Self {
4432+
Self::new(value)
4433+
}
4434+
}
4435+
44274436
#[unstable(feature = "unique_rc_arc", issue = "112566")]
44284437
impl<T: ?Sized, A: Allocator> Unpin for UniqueArc<T, A> {}
44294438

library/core/src/cell/lazy.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,16 @@ impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
366366
}
367367
}
368368

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

library/core/src/panic/unwind_safe.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,16 @@ impl<S: AsyncIterator> AsyncIterator for AssertUnwindSafe<S> {
313313
self.0.size_hint()
314314
}
315315
}
316+
317+
/// If a value's type is already `UnwindSafe`,
318+
/// wrapping it in `AssertUnwindSafe` is never incorrect.
319+
#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")]
320+
impl<T> From<T> for AssertUnwindSafe<T>
321+
where
322+
T: UnwindSafe,
323+
{
324+
#[inline(always)]
325+
fn from(value: T) -> Self {
326+
Self(value)
327+
}
328+
}

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.
@@ -404,6 +395,19 @@ impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
404395
}
405396
}
406397

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

library/std/src/sync/once.rs

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

87+
/// Creates a new `Once` value that starts already completed.
88+
#[inline]
89+
#[must_use]
90+
pub(crate) const fn new_complete() -> Once {
91+
Once { inner: sys::Once::new_complete() }
92+
}
93+
8794
/// Performs an initialization routine once and only once. The given closure
8895
/// will be executed if this is the first time `call_once` has been called,
8996
/// 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

0 commit comments

Comments
 (0)