mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
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.
This commit is contained in:
@@ -430,3 +430,12 @@ fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
self.deref().source()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[unstable(feature = "thin_box", issue = "92791")]
|
||||
impl<T> From<T> for ThinBox<T> {
|
||||
#[inline(always)]
|
||||
fn from(value: T) -> Self {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3980,6 +3980,15 @@ fn as_mut(&mut self) -> &mut T {
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T: ?Sized, A: Allocator> Unpin for UniqueRc<T, A> {}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T> From<T> for UniqueRc<T> {
|
||||
#[inline(always)]
|
||||
fn from(value: T) -> Self {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for UniqueRc<T, A> {
|
||||
/// Equality for two `UniqueRc`s.
|
||||
|
||||
@@ -4424,6 +4424,15 @@ fn as_mut(&mut self) -> &mut T {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T> From<T> for UniqueArc<T> {
|
||||
#[inline(always)]
|
||||
fn from(value: T) -> Self {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T: ?Sized, A: Allocator> Unpin for UniqueArc<T, A> {}
|
||||
|
||||
|
||||
@@ -366,6 +366,16 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl<T, F> From<T> for LazyCell<T, F> {
|
||||
/// 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() -> ! {
|
||||
|
||||
@@ -313,3 +313,16 @@ fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
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<T> From<T> for AssertUnwindSafe<T>
|
||||
where
|
||||
T: UnwindSafe,
|
||||
{
|
||||
#[inline(always)]
|
||||
fn from(value: T) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,10 +44,9 @@ fn generate_fake_frames() -> Vec<BacktraceFrame> {
|
||||
#[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();
|
||||
|
||||
@@ -105,15 +105,6 @@ pub const fn new(f: F) -> LazyLock<T, F> {
|
||||
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<T, F> {
|
||||
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.
|
||||
@@ -404,6 +395,19 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "from_wrapper_impls", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl<T, F> From<T> for LazyLock<T, F> {
|
||||
/// 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() -> ! {
|
||||
|
||||
@@ -84,6 +84,13 @@ pub const fn new() -> 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.
|
||||
|
||||
@@ -75,6 +75,11 @@ pub const fn new() -> 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
|
||||
|
||||
@@ -39,6 +39,11 @@ pub const fn new() -> 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
|
||||
|
||||
@@ -121,6 +121,11 @@ pub const fn new() -> 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
|
||||
|
||||
Reference in New Issue
Block a user