diff options
| author | bors <bors@rust-lang.org> | 2024-12-15 08:26:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-12-15 08:26:19 +0000 |
| commit | 87139bd9cfb999eff4025ff3d2ab5659c8082678 (patch) | |
| tree | 58ab98db8194b97261795bf2784a098579f7629f /library/alloc/src/rc.rs | |
| parent | 4790a435cbcb55c94ccdef51bf7a9b2e55824528 (diff) | |
| parent | 2d2225950fa193add623c430d2d2beb61a798e95 (diff) | |
| download | rust-87139bd9cfb999eff4025ff3d2ab5659c8082678.tar.gz rust-87139bd9cfb999eff4025ff3d2ab5659c8082678.zip | |
Auto merge of #133223 - zachs18:uniquerc-impls, r=Noratrieb
`UniqueRc` trait impls UniqueRc tracking Issue: #112566 Stable traits: (i.e. impls behind only the `unique_rc_arc` feature gate) * Support the same formatting as `Rc`: * `fmt::Debug` and `fmt::Display` delegate to the pointee. * `fmt::Pointer` prints the address of the pointee. * Add explicit `!Send` and `!Sync` impls, to mirror `Rc`. * Borrowing traits: `Borrow`, `BorrowMut`, `AsRef`, `AsMut` * `Rc` does not implement `BorrowMut` and `AsMut`, but `UniqueRc` can. * Unconditional `Unpin`, like other heap-allocated types. * Comparison traits `(Partial)Ord` and `(Partial)Eq` delegate to the pointees. * `PartialEq for UniqueRc` does not do `Rc`'s specialization shortcut for pointer equality when `T: Eq`, since by definition two `UniqueRc`s cannot share an allocation. * `Hash` delegates to the pointee. * `AsRawFd`, `AsFd`, `AsHandle`, `AsSocket` delegate to the pointee like `Rc`. * Sidenote: The bounds on `T` for the existing `Pointer<T>` impls for specifically `AsRawFd` and `AsSocket` do not allow `T: ?Sized`. For the added `UniqueRc` impls I allowed `T: ?Sized` for all four traits, but I did not change the existing (stable) impls. Unstable traits: * `DispatchFromDyn`, allows using `UniqueRc<Self>` as a method receiver under `feature(arbitrary_self_types)`. * Existing `PinCoerceUnsized for UniqueRc` is generalized to allow non-`Global` allocators, like `Rc`. * `DerefPure`, allows using `UniqueRc` in deref-patterns under `feature(deref_patterns)`, like `Rc`. For documentation, `Rc` only has documentation on the comparison traits' methods, so I copied/adapted the documentation for those, and left the rest without impl-specific docs. ~~Edit: Marked as draft while I figure out `UnwindSafe`.~~ Edit: Ignoring `UnwindSafe` for this PR
Diffstat (limited to 'library/alloc/src/rc.rs')
| -rw-r--r-- | library/alloc/src/rc.rs | 253 |
1 files changed, 249 insertions, 4 deletions
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 7aa1457b1df..bb27fe3c62d 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2232,12 +2232,20 @@ impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> { #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Rc<T, A> {} +//#[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for UniqueRc<T, A> {} + #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {} #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl<T: ?Sized, A: Allocator> DerefPure for Rc<T, A> {} +//#[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl<T: ?Sized, A: Allocator> DerefPure for UniqueRc<T, A> {} + #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl<T: ?Sized> LegacyReceiver for Rc<T> {} @@ -3684,7 +3692,6 @@ fn data_offset_align(align: usize) -> usize { /// previous example, `UniqueRc` allows for more flexibility in the construction of cyclic data, /// including fallible or async constructors. #[unstable(feature = "unique_rc_arc", issue = "112566")] -#[derive(Debug)] pub struct UniqueRc< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, @@ -3694,12 +3701,253 @@ pub struct UniqueRc< alloc: A, } +// Not necessary for correctness since `UniqueRc` contains `NonNull`, +// but having an explicit negative impl is nice for documentation purposes +// and results in nicer error messages. +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> !Send for UniqueRc<T, A> {} + +// Not necessary for correctness since `UniqueRc` contains `NonNull`, +// but having an explicit negative impl is nice for documentation purposes +// and results in nicer error messages. +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> !Sync for UniqueRc<T, A> {} + #[unstable(feature = "unique_rc_arc", issue = "112566")] impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<UniqueRc<U, A>> for UniqueRc<T, A> { } +//#[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<UniqueRc<U>> for UniqueRc<T> {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized + fmt::Display, A: Allocator> fmt::Display for UniqueRc<T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for UniqueRc<T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> fmt::Pointer for UniqueRc<T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&(&raw const **self), f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for UniqueRc<T, A> { + fn borrow(&self) -> &T { + &**self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for UniqueRc<T, A> { + fn borrow_mut(&mut self) -> &mut T { + &mut **self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> AsRef<T> for UniqueRc<T, A> { + fn as_ref(&self) -> &T { + &**self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> AsMut<T> for UniqueRc<T, A> { + fn as_mut(&mut self) -> &mut T { + &mut **self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized, A: Allocator> Unpin for UniqueRc<T, A> {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for UniqueRc<T, A> { + /// Equality for two `UniqueRc`s. + /// + /// Two `UniqueRc`s are equal if their inner values are equal. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five == UniqueRc::new(5)); + /// ``` + #[inline] + fn eq(&self, other: &Self) -> bool { + PartialEq::eq(&**self, &**other) + } + + /// Inequality for two `UniqueRc`s. + /// + /// Two `UniqueRc`s are not equal if their inner values are not equal. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five != UniqueRc::new(6)); + /// ``` + #[inline] + fn ne(&self, other: &Self) -> bool { + PartialEq::ne(&**self, &**other) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for UniqueRc<T, A> { + /// Partial comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `partial_cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// use std::cmp::Ordering; + /// + /// let five = UniqueRc::new(5); + /// + /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueRc::new(6))); + /// ``` + #[inline(always)] + fn partial_cmp(&self, other: &UniqueRc<T, A>) -> Option<Ordering> { + (**self).partial_cmp(&**other) + } + + /// Less-than comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `<` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five < UniqueRc::new(6)); + /// ``` + #[inline(always)] + fn lt(&self, other: &UniqueRc<T, A>) -> bool { + **self < **other + } + + /// 'Less than or equal to' comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `<=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five <= UniqueRc::new(5)); + /// ``` + #[inline(always)] + fn le(&self, other: &UniqueRc<T, A>) -> bool { + **self <= **other + } + + /// Greater-than comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `>` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five > UniqueRc::new(4)); + /// ``` + #[inline(always)] + fn gt(&self, other: &UniqueRc<T, A>) -> bool { + **self > **other + } + + /// 'Greater than or equal to' comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `>=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five >= UniqueRc::new(5)); + /// ``` + #[inline(always)] + fn ge(&self, other: &UniqueRc<T, A>) -> bool { + **self >= **other + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized + Ord, A: Allocator> Ord for UniqueRc<T, A> { + /// Comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// use std::cmp::Ordering; + /// + /// let five = UniqueRc::new(5); + /// + /// assert_eq!(Ordering::Less, five.cmp(&UniqueRc::new(6))); + /// ``` + #[inline] + fn cmp(&self, other: &UniqueRc<T, A>) -> Ordering { + (**self).cmp(&**other) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized + Eq, A: Allocator> Eq for UniqueRc<T, A> {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl<T: ?Sized + Hash, A: Allocator> Hash for UniqueRc<T, A> { + fn hash<H: Hasher>(&self, state: &mut H) { + (**self).hash(state); + } +} + // Depends on A = Global impl<T> UniqueRc<T> { /// Creates a new `UniqueRc`. @@ -3791,9 +4039,6 @@ impl<T: ?Sized, A: Allocator> Deref for UniqueRc<T, A> { } } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl<T: ?Sized> PinCoerceUnsized for UniqueRc<T> {} - #[unstable(feature = "unique_rc_arc", issue = "112566")] impl<T: ?Sized, A: Allocator> DerefMut for UniqueRc<T, A> { fn deref_mut(&mut self) -> &mut T { |
