diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 2b767ffe02bee..f714a87c18687 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -184,7 +184,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use core::borrow::{Borrow, BorrowMut}; -#[cfg(not(no_global_oom_handling))] use core::clone::CloneToUninit; use core::cmp::Ordering; use core::error::{self, Error}; @@ -733,6 +732,128 @@ impl Box { } } +impl Box { + /// Allocates memory on the heap then clones `src` into it. + /// + /// This doesn't actually allocate if `src` is zero-sized. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// + /// let hello: Box = Box::clone_from_ref("hello"); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + #[must_use] + #[inline] + pub fn clone_from_ref(src: &T) -> Box { + Box::clone_from_ref_in(src, Global) + } + + /// Allocates memory on the heap then clones `src` into it, returning an error if allocation fails. + /// + /// This doesn't actually allocate if `src` is zero-sized. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// + /// let hello: Box = Box::try_clone_from_ref("hello")?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + #[must_use] + #[inline] + pub fn try_clone_from_ref(src: &T) -> Result, AllocError> { + Box::try_clone_from_ref_in(src, Global) + } +} + +impl Box { + /// Allocates memory in the given allocator then clones `src` into it. + /// + /// This doesn't actually allocate if `src` is zero-sized. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// + /// let hello: Box = Box::clone_from_ref_in("hello", System); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + #[must_use] + #[inline] + pub fn clone_from_ref_in(src: &T, alloc: A) -> Box { + let layout = Layout::for_value::(src); + match Box::try_clone_from_ref_in(src, alloc) { + Ok(bx) => bx, + Err(_) => handle_alloc_error(layout), + } + } + + /// Allocates memory in the given allocator then clones `src` into it, returning an error if allocation fails. + /// + /// This doesn't actually allocate if `src` is zero-sized. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// + /// let hello: Box = Box::try_clone_from_ref_in("hello", System)?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + #[must_use] + #[inline] + pub fn try_clone_from_ref_in(src: &T, alloc: A) -> Result, AllocError> { + struct DeallocDropGuard<'a, A: Allocator>(Layout, &'a A, NonNull); + impl<'a, A: Allocator> Drop for DeallocDropGuard<'a, A> { + fn drop(&mut self) { + let &mut DeallocDropGuard(layout, alloc, ptr) = self; + // Safety: `ptr` was allocated by `*alloc` with layout `layout` + unsafe { + alloc.deallocate(ptr, layout); + } + } + } + let layout = Layout::for_value::(src); + let (ptr, guard) = if layout.size() == 0 { + (layout.dangling(), None) + } else { + // Safety: layout is non-zero-sized + let ptr = alloc.allocate(layout)?.cast(); + (ptr, Some(DeallocDropGuard(layout, &alloc, ptr))) + }; + let ptr = ptr.as_ptr(); + // Safety: `*ptr` is newly allocated, correctly aligned to `align_of_val(src)`, + // and is valid for writes for `size_of_val(src)`. + // If this panics, then `guard` will deallocate for us (if allocation occuured) + unsafe { + ::clone_to_uninit(src, ptr); + } + // Defuse the deallocate guard + core::mem::forget(guard); + // Safety: We just initialized `*ptr` as a clone of `src` + Ok(unsafe { Box::from_raw_in(ptr.with_metadata_of(src), alloc) }) + } +} + impl Box<[T]> { /// Constructs a new boxed slice with uninitialized contents. /// diff --git a/library/alloc/src/boxed/convert.rs b/library/alloc/src/boxed/convert.rs index 73940db5d2f50..d6a8e78991b84 100644 --- a/library/alloc/src/boxed/convert.rs +++ b/library/alloc/src/boxed/convert.rs @@ -1,21 +1,15 @@ use core::any::Any; -#[cfg(not(no_global_oom_handling))] -use core::clone::TrivialClone; use core::error::Error; +#[cfg(not(no_global_oom_handling))] +use core::fmt; use core::mem; use core::pin::Pin; -#[cfg(not(no_global_oom_handling))] -use core::{fmt, ptr}; use crate::alloc::Allocator; #[cfg(not(no_global_oom_handling))] use crate::borrow::Cow; use crate::boxed::Box; #[cfg(not(no_global_oom_handling))] -use crate::raw_vec::RawVec; -#[cfg(not(no_global_oom_handling))] -use crate::str::from_boxed_utf8_unchecked; -#[cfg(not(no_global_oom_handling))] use crate::string::String; #[cfg(not(no_global_oom_handling))] use crate::vec::Vec; @@ -62,35 +56,6 @@ where } } -/// Specialization trait used for `From<&[T]>`. -#[cfg(not(no_global_oom_handling))] -trait BoxFromSlice { - fn from_slice(slice: &[T]) -> Self; -} - -#[cfg(not(no_global_oom_handling))] -impl BoxFromSlice for Box<[T]> { - #[inline] - default fn from_slice(slice: &[T]) -> Self { - slice.to_vec().into_boxed_slice() - } -} - -#[cfg(not(no_global_oom_handling))] -impl BoxFromSlice for Box<[T]> { - #[inline] - fn from_slice(slice: &[T]) -> Self { - let len = slice.len(); - let buf = RawVec::with_capacity(len); - // SAFETY: since `T` implements `TrivialClone`, this is sound and - // equivalent to the above. - unsafe { - ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); - buf.into_box(slice.len()).assume_init() - } - } -} - #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_slice", since = "1.17.0")] impl From<&[T]> for Box<[T]> { @@ -109,7 +74,7 @@ impl From<&[T]> for Box<[T]> { /// ``` #[inline] fn from(slice: &[T]) -> Box<[T]> { - >::from_slice(slice) + Box::clone_from_ref(slice) } } @@ -170,7 +135,7 @@ impl From<&str> for Box { /// ``` #[inline] fn from(s: &str) -> Box { - unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) } + Box::clone_from_ref(s) } } diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 3e78d680ea68a..59f5857b97aa1 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -766,8 +766,7 @@ impl From<&CStr> for Box { /// Converts a `&CStr` into a `Box`, /// by copying the contents into a newly allocated [`Box`]. fn from(s: &CStr) -> Box { - let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul()); - unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) } + Box::clone_from_ref(s) } } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 0ab019a68ea05..a3ebbbbaae05f 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -243,9 +243,9 @@ use core::any::Any; use core::cell::{Cell, CloneFromCell}; -use core::clone::UseCloned; #[cfg(not(no_global_oom_handling))] -use core::clone::{CloneToUninit, TrivialClone}; +use core::clone::TrivialClone; +use core::clone::{CloneToUninit, UseCloned}; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; @@ -1290,6 +1290,104 @@ impl Rc, A> { } } +impl Rc { + /// Constructs a new `Rc` with a clone of `value`. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// use std::rc::Rc; + /// + /// let hello: Rc = Rc::clone_from_ref("hello"); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + pub fn clone_from_ref(value: &T) -> Rc { + Rc::clone_from_ref_in(value, Global) + } + + /// Constructs a new `Rc` with a clone of `value`, returning an error if allocation fails + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// use std::rc::Rc; + /// + /// let hello: Rc = Rc::try_clone_from_ref("hello")?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + pub fn try_clone_from_ref(value: &T) -> Result, AllocError> { + Rc::try_clone_from_ref_in(value, Global) + } +} + +impl Rc { + /// Constructs a new `Rc` with a clone of `value` in the provided allocator. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// use std::rc::Rc; + /// use std::alloc::System; + /// + /// let hello: Rc = Rc::clone_from_ref_in("hello", System); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + pub fn clone_from_ref_in(value: &T, alloc: A) -> Rc { + // `in_progress` drops the allocation if we panic before finishing initializing it. + let mut in_progress: UniqueRcUninit = UniqueRcUninit::new(value, alloc); + + // Initialize with clone of value. + let initialized_clone = unsafe { + // Clone. If the clone panics, `in_progress` will be dropped and clean up. + value.clone_to_uninit(in_progress.data_ptr().cast()); + // Cast type of pointer, now that it is initialized. + in_progress.into_rc() + }; + + initialized_clone + } + + /// Constructs a new `Rc` with a clone of `value` in the provided allocator, returning an error if allocation fails + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// use std::rc::Rc; + /// use std::alloc::System; + /// + /// let hello: Rc = Rc::try_clone_from_ref_in("hello", System)?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + pub fn try_clone_from_ref_in(value: &T, alloc: A) -> Result, AllocError> { + // `in_progress` drops the allocation if we panic before finishing initializing it. + let mut in_progress: UniqueRcUninit = UniqueRcUninit::try_new(value, alloc)?; + + // Initialize with clone of value. + let initialized_clone = unsafe { + // Clone. If the clone panics, `in_progress` will be dropped and clean up. + value.clone_to_uninit(in_progress.data_ptr().cast()); + // Cast type of pointer, now that it is initialized. + in_progress.into_rc() + }; + + Ok(initialized_clone) + } +} + impl Rc<[mem::MaybeUninit], A> { /// Converts to `Rc<[T]>`. /// @@ -1969,22 +2067,7 @@ impl Rc { if Rc::strong_count(this) != 1 { // Gotta clone the data, there are other Rcs. - - let this_data_ref: &T = &**this; - // `in_progress` drops the allocation if we panic before finishing initializing it. - let mut in_progress: UniqueRcUninit = - UniqueRcUninit::new(this_data_ref, this.alloc.clone()); - - // Initialize with clone of this. - let initialized_clone = unsafe { - // Clone. If the clone panics, `in_progress` will be dropped and clean up. - this_data_ref.clone_to_uninit(in_progress.data_ptr().cast()); - // Cast type of pointer, now that it is initialized. - in_progress.into_rc() - }; - - // Replace `this` with newly constructed Rc. - *this = initialized_clone; + *this = Rc::clone_from_ref_in(&**this, this.alloc.clone()); } else if Rc::weak_count(this) != 0 { // Can just steal the data, all that's left is Weaks @@ -4358,16 +4441,15 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc { /// This is a helper for [`Rc::make_mut()`] to ensure correct cleanup on panic. /// It is nearly a duplicate of `UniqueRc, A>` except that it allows `T: !Sized`, /// which `MaybeUninit` does not. -#[cfg(not(no_global_oom_handling))] struct UniqueRcUninit { ptr: NonNull>, layout_for_value: Layout, alloc: Option, } -#[cfg(not(no_global_oom_handling))] impl UniqueRcUninit { /// Allocates a RcInner with layout suitable to contain `for_value` or a clone of it. + #[cfg(not(no_global_oom_handling))] fn new(for_value: &T, alloc: A) -> UniqueRcUninit { let layout = Layout::for_value(for_value); let ptr = unsafe { @@ -4380,6 +4462,20 @@ impl UniqueRcUninit { Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) } } + /// Allocates a RcInner with layout suitable to contain `for_value` or a clone of it, + /// returning an error if allocation fails. + fn try_new(for_value: &T, alloc: A) -> Result, AllocError> { + let layout = Layout::for_value(for_value); + let ptr = unsafe { + Rc::try_allocate_for_layout( + layout, + |layout_for_rc_inner| alloc.allocate(layout_for_rc_inner), + |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const RcInner), + )? + }; + Ok(Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) }) + } + /// Returns the pointer to be written into to initialize the [`Rc`]. fn data_ptr(&mut self) -> *mut T { let offset = data_offset_align(self.layout_for_value.align()); @@ -4402,7 +4498,6 @@ impl UniqueRcUninit { } } -#[cfg(not(no_global_oom_handling))] impl Drop for UniqueRcUninit { fn drop(&mut self) { // SAFETY: diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index c302f35e5ed6e..6a49017a82767 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -11,10 +11,8 @@ use core::any::Any; use core::cell::CloneFromCell; #[cfg(not(no_global_oom_handling))] -use core::clone::CloneToUninit; -#[cfg(not(no_global_oom_handling))] use core::clone::TrivialClone; -use core::clone::UseCloned; +use core::clone::{CloneToUninit, UseCloned}; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; @@ -1442,6 +1440,104 @@ impl Arc, A> { } } +impl Arc { + /// Constructs a new `Arc` with a clone of `value`. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// use std::sync::Arc; + /// + /// let hello: Arc = Arc::clone_from_ref("hello"); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + pub fn clone_from_ref(value: &T) -> Arc { + Arc::clone_from_ref_in(value, Global) + } + + /// Constructs a new `Arc` with a clone of `value`, returning an error if allocation fails + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// use std::sync::Arc; + /// + /// let hello: Arc = Arc::try_clone_from_ref("hello")?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + pub fn try_clone_from_ref(value: &T) -> Result, AllocError> { + Arc::try_clone_from_ref_in(value, Global) + } +} + +impl Arc { + /// Constructs a new `Arc` with a clone of `value` in the provided allocator. + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let hello: Arc = Arc::clone_from_ref_in("hello", System); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + pub fn clone_from_ref_in(value: &T, alloc: A) -> Arc { + // `in_progress` drops the allocation if we panic before finishing initializing it. + let mut in_progress: UniqueArcUninit = UniqueArcUninit::new(value, alloc); + + // Initialize with clone of value. + let initialized_clone = unsafe { + // Clone. If the clone panics, `in_progress` will be dropped and clean up. + value.clone_to_uninit(in_progress.data_ptr().cast()); + // Cast type of pointer, now that it is initialized. + in_progress.into_arc() + }; + + initialized_clone + } + + /// Constructs a new `Arc` with a clone of `value` in the provided allocator, returning an error if allocation fails + /// + /// # Examples + /// + /// ``` + /// #![feature(clone_from_ref)] + /// #![feature(allocator_api)] + /// use std::sync::Arc; + /// use std::alloc::System; + /// + /// let hello: Arc = Arc::try_clone_from_ref_in("hello", System)?; + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "clone_from_ref", issue = "149075")] + //#[unstable(feature = "allocator_api", issue = "32838")] + pub fn try_clone_from_ref_in(value: &T, alloc: A) -> Result, AllocError> { + // `in_progress` drops the allocation if we panic before finishing initializing it. + let mut in_progress: UniqueArcUninit = UniqueArcUninit::try_new(value, alloc)?; + + // Initialize with clone of value. + let initialized_clone = unsafe { + // Clone. If the clone panics, `in_progress` will be dropped and clean up. + value.clone_to_uninit(in_progress.data_ptr().cast()); + // Cast type of pointer, now that it is initialized. + in_progress.into_arc() + }; + + Ok(initialized_clone) + } +} + impl Arc<[mem::MaybeUninit], A> { /// Converts to `Arc<[T]>`. /// @@ -2406,19 +2502,7 @@ impl Arc { // deallocated. if this.inner().strong.compare_exchange(1, 0, Acquire, Relaxed).is_err() { // Another strong pointer exists, so we must clone. - - let this_data_ref: &T = &**this; - // `in_progress` drops the allocation if we panic before finishing initializing it. - let mut in_progress: UniqueArcUninit = - UniqueArcUninit::new(this_data_ref, this.alloc.clone()); - - let initialized_clone = unsafe { - // Clone. If the clone panics, `in_progress` will be dropped and clean up. - this_data_ref.clone_to_uninit(in_progress.data_ptr().cast()); - // Cast type of pointer, now that it is initialized. - in_progress.into_arc() - }; - *this = initialized_clone; + *this = Arc::clone_from_ref_in(&**this, this.alloc.clone()); } else if this.inner().weak.load(Relaxed) != 1 { // Relaxed suffices in the above because this is fundamentally an // optimization: we are always racing with weak pointers being @@ -4137,16 +4221,15 @@ fn data_offset_align(align: usize) -> usize { /// but will deallocate it (without dropping the value) when dropped. /// /// This is a helper for [`Arc::make_mut()`] to ensure correct cleanup on panic. -#[cfg(not(no_global_oom_handling))] struct UniqueArcUninit { ptr: NonNull>, layout_for_value: Layout, alloc: Option, } -#[cfg(not(no_global_oom_handling))] impl UniqueArcUninit { /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it. + #[cfg(not(no_global_oom_handling))] fn new(for_value: &T, alloc: A) -> UniqueArcUninit { let layout = Layout::for_value(for_value); let ptr = unsafe { @@ -4159,6 +4242,20 @@ impl UniqueArcUninit { Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) } } + /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it, + /// returning an error if allocation fails. + fn try_new(for_value: &T, alloc: A) -> Result, AllocError> { + let layout = Layout::for_value(for_value); + let ptr = unsafe { + Arc::try_allocate_for_layout( + layout, + |layout_for_arcinner| alloc.allocate(layout_for_arcinner), + |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const ArcInner), + )? + }; + Ok(Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) }) + } + /// Returns the pointer to be written into to initialize the [`Arc`]. fn data_ptr(&mut self) -> *mut T { let offset = data_offset_align(self.layout_for_value.align()); diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 09bd911aa769a..a1dd8e5f86f4c 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1285,8 +1285,7 @@ impl From<&OsStr> for Box { /// Copies the string into a newly allocated [Box]<[OsStr]>. #[inline] fn from(s: &OsStr) -> Box { - let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr; - unsafe { Box::from_raw(rw) } + Box::clone_from_ref(s) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 07618550a9cb2..32f166e112e99 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -374,6 +374,7 @@ // tidy-alphabetical-start #![feature(alloc_layout_extra)] #![feature(allocator_api)] +#![feature(clone_from_ref)] #![feature(get_mut_unchecked)] #![feature(map_try_insert)] #![feature(slice_concat_trait)] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 114fcc796c525..2a57a1ed59600 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1877,9 +1877,7 @@ impl From<&Path> for Box { /// /// This will allocate and clone `path` to it. fn from(path: &Path) -> Box { - let boxed: Box = path.inner.into(); - let rw = Box::into_raw(boxed) as *mut Path; - unsafe { Box::from_raw(rw) } + Box::clone_from_ref(path) } } diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 9373982c455fa..258279bd4a60d 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -321,12 +321,6 @@ impl Slice { self.inner.clone_into(&mut buf.inner) } - #[inline] - pub fn into_box(&self) -> Box { - let boxed: Box<[u8]> = self.inner.into(); - unsafe { mem::transmute(boxed) } - } - #[inline] pub fn empty_box() -> Box { let boxed: Box<[u8]> = Default::default(); diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 208755cd5b9c7..5050fd2794333 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -271,11 +271,6 @@ impl Slice { self.inner.clone_into(&mut buf.inner) } - #[inline] - pub fn into_box(&self) -> Box { - unsafe { mem::transmute(self.inner.into_box()) } - } - #[inline] pub fn empty_box() -> Box { unsafe { mem::transmute(Wtf8::empty_box()) } diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index 7df293e1e1d94..566f31fc305eb 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), | - = and 13 other candidates + = and 15 other candidates help: consider using the `Default` trait | LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); | - = and 14 other candidates + = and 16 other candidates help: consider using the `Default` trait | LL - let _ = Box {}; @@ -146,7 +146,7 @@ LL + let _ = Box::::map(_, _); LL - let _ = Box:: {}; LL + let _ = Box::::into_inner(_); | - = and 5 other candidates + = and 7 other candidates help: consider using the `Default` trait | LL - let _ = Box:: {}; diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr index 4bd6c19e0829b..bb14eb2fb5729 100644 --- a/tests/ui/suggestions/multi-suggestion.ascii.stderr +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), | - = and 13 other candidates + = and 15 other candidates help: consider using the `Default` trait | LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); | - = and 14 other candidates + = and 16 other candidates help: consider using the `Default` trait | LL - let _ = Box {}; diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr index b11570f34161c..e7f9e7153d194 100644 --- a/tests/ui/suggestions/multi-suggestion.unicode.stderr +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -63,7 +63,7 @@ LL - x: (), LL - })), LL + wtf: Some(Box::new_in(_, _)), │ - ╰ and 13 other candidates + ╰ and 15 other candidates help: consider using the `Default` trait ╭╴ LL - wtf: Some(Box(U { @@ -118,7 +118,7 @@ LL + let _ = Box::new_zeroed(); LL - let _ = Box {}; LL + let _ = Box::new_in(_, _); │ - ╰ and 14 other candidates + ╰ and 16 other candidates help: consider using the `Default` trait ╭╴ LL - let _ = Box {};