diff options
| author | Ralf Jung <post@ralfj.de> | 2024-05-12 15:44:24 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-05-12 15:44:24 +0200 |
| commit | 1e7fba9e06965b6db8a173cb497068401eea3bae (patch) | |
| tree | f3ada808f56974250673700372722ba24596027f /library/alloc | |
| parent | 7d565dfa0fa40991df9e3567f991284b4912ab0b (diff) | |
| parent | f8433a82b4a4120e34de236a68d0cfeaea6e60c3 (diff) | |
Merge from rustc
Diffstat (limited to 'library/alloc')
| -rw-r--r-- | library/alloc/src/fmt.rs | 6 | ||||
| -rw-r--r-- | library/alloc/src/rc.rs | 49 | ||||
| -rw-r--r-- | library/alloc/src/sync.rs | 16 |
3 files changed, 37 insertions, 34 deletions
diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index b9918752540..ae44cab8131 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -403,7 +403,7 @@ //! is, a formatting implementation must and may only return an error if the //! passed-in [`Formatter`] returns an error. This is because, contrary to what //! the function signature might suggest, string formatting is an infallible -//! operation. This function only returns a result because writing to the +//! operation. This function only returns a [`Result`] because writing to the //! underlying stream might fail and it must provide a way to propagate the fact //! that an error has occurred back up the stack. //! @@ -630,7 +630,9 @@ pub fn format(args: Arguments<'_>) -> string::String { fn format_inner(args: Arguments<'_>) -> string::String { let capacity = args.estimated_capacity(); let mut output = string::String::with_capacity(capacity); - output.write_fmt(args).expect("a formatting trait implementation returned an error"); + output + .write_fmt(args) + .expect("a formatting trait implementation returned an error when the underlying stream did not"); output } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index c245b42c3e8..45b20535675 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -366,6 +366,12 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { } #[inline] + fn into_inner_with_allocator(this: Self) -> (NonNull<RcBox<T>>, A) { + let this = mem::ManuallyDrop::new(this); + (this.ptr, unsafe { ptr::read(&this.alloc) }) + } + + #[inline] unsafe fn from_inner_in(ptr: NonNull<RcBox<T>>, alloc: A) -> Self { Self { ptr, phantom: PhantomData, alloc } } @@ -1145,12 +1151,9 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] #[inline] - pub unsafe fn assume_init(self) -> Rc<T, A> - where - A: Clone, - { - let md_self = mem::ManuallyDrop::new(self); - unsafe { Rc::from_inner_in(md_self.ptr.cast(), md_self.alloc.clone()) } + pub unsafe fn assume_init(self) -> Rc<T, A> { + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + unsafe { Rc::from_inner_in(ptr.cast(), alloc) } } } @@ -1189,12 +1192,9 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] #[inline] - pub unsafe fn assume_init(self) -> Rc<[T], A> - where - A: Clone, - { - let md_self = mem::ManuallyDrop::new(self); - unsafe { Rc::from_ptr_in(md_self.ptr.as_ptr() as _, md_self.alloc.clone()) } + pub unsafe fn assume_init(self) -> Rc<[T], A> { + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + unsafe { Rc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -1809,7 +1809,9 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> { // reference to the allocation. unsafe { &mut this.ptr.as_mut().value } } +} +impl<T: Clone, A: Allocator> Rc<T, A> { /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the /// clone. /// @@ -1845,7 +1847,7 @@ impl<T: Clone, A: Allocator + Clone> Rc<T, A> { } } -impl<A: Allocator + Clone> Rc<dyn Any, A> { +impl<A: Allocator> Rc<dyn Any, A> { /// Attempt to downcast the `Rc<dyn Any>` to a concrete type. /// /// # Examples @@ -1869,10 +1871,8 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> { pub fn downcast<T: Any>(self) -> Result<Rc<T, A>, Self> { if (*self).is::<T>() { unsafe { - let ptr = self.ptr.cast::<RcBox<T>>(); - let alloc = self.alloc.clone(); - forget(self); - Ok(Rc::from_inner_in(ptr, alloc)) + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + Ok(Rc::from_inner_in(ptr.cast(), alloc)) } } else { Err(self) @@ -1909,10 +1909,8 @@ impl<A: Allocator + Clone> Rc<dyn Any, A> { #[unstable(feature = "downcast_unchecked", issue = "90850")] pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T, A> { unsafe { - let ptr = self.ptr.cast::<RcBox<T>>(); - let alloc = self.alloc.clone(); - mem::forget(self); - Rc::from_inner_in(ptr, alloc) + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + Rc::from_inner_in(ptr.cast(), alloc) } } } @@ -2661,12 +2659,13 @@ impl From<Rc<str>> for Rc<[u8]> { } #[stable(feature = "boxed_slice_try_from", since = "1.43.0")] -impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]> { - type Error = Rc<[T]>; +impl<T, A: Allocator, const N: usize> TryFrom<Rc<[T], A>> for Rc<[T; N], A> { + type Error = Rc<[T], A>; - fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> { + fn try_from(boxed_slice: Rc<[T], A>) -> Result<Self, Self::Error> { if boxed_slice.len() == N { - Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) }) + let (ptr, alloc) = Rc::into_inner_with_allocator(boxed_slice); + Ok(unsafe { Rc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 297a273d274..a35c99849b3 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -280,8 +280,8 @@ impl<T: ?Sized> Arc<T> { impl<T: ?Sized, A: Allocator> Arc<T, A> { #[inline] - fn internal_into_inner_with_allocator(self) -> (NonNull<ArcInner<T>>, A) { - let this = mem::ManuallyDrop::new(self); + fn into_inner_with_allocator(this: Self) -> (NonNull<ArcInner<T>>, A) { + let this = mem::ManuallyDrop::new(this); (this.ptr, unsafe { ptr::read(&this.alloc) }) } @@ -1290,7 +1290,7 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub unsafe fn assume_init(self) -> Arc<T, A> { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); unsafe { Arc::from_inner_in(ptr.cast(), alloc) } } } @@ -1332,7 +1332,7 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub unsafe fn assume_init(self) -> Arc<[T], A> { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -2227,7 +2227,9 @@ impl<T: Clone, A: Allocator + Clone> Arc<T, A> { // either unique to begin with, or became one upon cloning the contents. unsafe { Self::get_mut_unchecked(this) } } +} +impl<T: Clone, A: Allocator> Arc<T, A> { /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the /// clone. /// @@ -2499,7 +2501,7 @@ impl<A: Allocator> Arc<dyn Any + Send + Sync, A> { { if (*self).is::<T>() { unsafe { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); Ok(Arc::from_inner_in(ptr.cast(), alloc)) } } else { @@ -2540,7 +2542,7 @@ impl<A: Allocator> Arc<dyn Any + Send + Sync, A> { T: Any + Send + Sync, { unsafe { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); Arc::from_inner_in(ptr.cast(), alloc) } } @@ -3506,7 +3508,7 @@ impl<T, A: Allocator, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> { fn try_from(boxed_slice: Arc<[T], A>) -> Result<Self, Self::Error> { if boxed_slice.len() == N { - let (ptr, alloc) = boxed_slice.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice); Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) |
