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
This commit is contained in:
commit
87139bd9cf
6 changed files with 282 additions and 4 deletions
|
@ -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 {
|
||||
|
|
|
@ -373,6 +373,7 @@
|
|||
#![feature(thin_box)]
|
||||
#![feature(try_reserve_kind)]
|
||||
#![feature(try_with_capacity)]
|
||||
#![feature(unique_rc_arc)]
|
||||
#![feature(vec_into_raw_parts)]
|
||||
// tidy-alphabetical-end
|
||||
//
|
||||
|
|
|
@ -428,6 +428,14 @@ impl<T: AsFd + ?Sized> AsFd for crate::rc::Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T: AsFd + ?Sized> AsFd for crate::rc::UniqueRc<T> {
|
||||
#[inline]
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
(**self).as_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asfd_ptrs", since = "1.64.0")]
|
||||
impl<T: AsFd + ?Sized> AsFd for Box<T> {
|
||||
#[inline]
|
||||
|
|
|
@ -266,6 +266,14 @@ impl<T: AsRawFd> AsRawFd for crate::rc::Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T: AsRawFd + ?Sized> AsRawFd for crate::rc::UniqueRc<T> {
|
||||
#[inline]
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
(**self).as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "asrawfd_ptrs", since = "1.63.0")]
|
||||
impl<T: AsRawFd> AsRawFd for Box<T> {
|
||||
#[inline]
|
||||
|
|
|
@ -485,6 +485,14 @@ impl<T: AsHandle + ?Sized> AsHandle for crate::rc::Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T: AsHandle + ?Sized> AsHandle for crate::rc::UniqueRc<T> {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
(**self).as_handle()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
|
||||
impl<T: AsHandle + ?Sized> AsHandle for Box<T> {
|
||||
#[inline]
|
||||
|
|
|
@ -279,6 +279,14 @@ impl<T: AsSocket> AsSocket for crate::rc::Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique_rc_arc", issue = "112566")]
|
||||
impl<T: AsSocket + ?Sized> AsSocket for crate::rc::UniqueRc<T> {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
(**self).as_socket()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
|
||||
impl<T: AsSocket> AsSocket for Box<T> {
|
||||
#[inline]
|
||||
|
|
Loading…
Add table
Reference in a new issue