Skip to content

Commit 87139bd

Browse files
committed
Auto merge of rust-lang#133223 - zachs18:uniquerc-impls, r=Noratrieb
`UniqueRc` trait impls UniqueRc tracking Issue: rust-lang#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
2 parents 4790a43 + 2d22259 commit 87139bd

File tree

6 files changed

+282
-4
lines changed

6 files changed

+282
-4
lines changed

library/alloc/src/rc.rs

+249-4
Original file line numberDiff line numberDiff line change
@@ -2232,12 +2232,20 @@ impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {
22322232
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
22332233
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Rc<T, A> {}
22342234

2235+
//#[unstable(feature = "unique_rc_arc", issue = "112566")]
2236+
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
2237+
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for UniqueRc<T, A> {}
2238+
22352239
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
22362240
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {}
22372241

22382242
#[unstable(feature = "deref_pure_trait", issue = "87121")]
22392243
unsafe impl<T: ?Sized, A: Allocator> DerefPure for Rc<T, A> {}
22402244

2245+
//#[unstable(feature = "unique_rc_arc", issue = "112566")]
2246+
#[unstable(feature = "deref_pure_trait", issue = "87121")]
2247+
unsafe impl<T: ?Sized, A: Allocator> DerefPure for UniqueRc<T, A> {}
2248+
22412249
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
22422250
impl<T: ?Sized> LegacyReceiver for Rc<T> {}
22432251

@@ -3684,7 +3692,6 @@ fn data_offset_align(align: usize) -> usize {
36843692
/// previous example, `UniqueRc` allows for more flexibility in the construction of cyclic data,
36853693
/// including fallible or async constructors.
36863694
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3687-
#[derive(Debug)]
36883695
pub struct UniqueRc<
36893696
T: ?Sized,
36903697
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
@@ -3694,12 +3701,253 @@ pub struct UniqueRc<
36943701
alloc: A,
36953702
}
36963703

3704+
// Not necessary for correctness since `UniqueRc` contains `NonNull`,
3705+
// but having an explicit negative impl is nice for documentation purposes
3706+
// and results in nicer error messages.
3707+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3708+
impl<T: ?Sized, A: Allocator> !Send for UniqueRc<T, A> {}
3709+
3710+
// Not necessary for correctness since `UniqueRc` contains `NonNull`,
3711+
// but having an explicit negative impl is nice for documentation purposes
3712+
// and results in nicer error messages.
3713+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3714+
impl<T: ?Sized, A: Allocator> !Sync for UniqueRc<T, A> {}
3715+
36973716
#[unstable(feature = "unique_rc_arc", issue = "112566")]
36983717
impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<UniqueRc<U, A>>
36993718
for UniqueRc<T, A>
37003719
{
37013720
}
37023721

3722+
//#[unstable(feature = "unique_rc_arc", issue = "112566")]
3723+
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
3724+
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<UniqueRc<U>> for UniqueRc<T> {}
3725+
3726+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3727+
impl<T: ?Sized + fmt::Display, A: Allocator> fmt::Display for UniqueRc<T, A> {
3728+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3729+
fmt::Display::fmt(&**self, f)
3730+
}
3731+
}
3732+
3733+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3734+
impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for UniqueRc<T, A> {
3735+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3736+
fmt::Debug::fmt(&**self, f)
3737+
}
3738+
}
3739+
3740+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3741+
impl<T: ?Sized, A: Allocator> fmt::Pointer for UniqueRc<T, A> {
3742+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3743+
fmt::Pointer::fmt(&(&raw const **self), f)
3744+
}
3745+
}
3746+
3747+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3748+
impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for UniqueRc<T, A> {
3749+
fn borrow(&self) -> &T {
3750+
&**self
3751+
}
3752+
}
3753+
3754+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3755+
impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for UniqueRc<T, A> {
3756+
fn borrow_mut(&mut self) -> &mut T {
3757+
&mut **self
3758+
}
3759+
}
3760+
3761+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3762+
impl<T: ?Sized, A: Allocator> AsRef<T> for UniqueRc<T, A> {
3763+
fn as_ref(&self) -> &T {
3764+
&**self
3765+
}
3766+
}
3767+
3768+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3769+
impl<T: ?Sized, A: Allocator> AsMut<T> for UniqueRc<T, A> {
3770+
fn as_mut(&mut self) -> &mut T {
3771+
&mut **self
3772+
}
3773+
}
3774+
3775+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3776+
impl<T: ?Sized, A: Allocator> Unpin for UniqueRc<T, A> {}
3777+
3778+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3779+
impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for UniqueRc<T, A> {
3780+
/// Equality for two `UniqueRc`s.
3781+
///
3782+
/// Two `UniqueRc`s are equal if their inner values are equal.
3783+
///
3784+
/// # Examples
3785+
///
3786+
/// ```
3787+
/// #![feature(unique_rc_arc)]
3788+
/// use std::rc::UniqueRc;
3789+
///
3790+
/// let five = UniqueRc::new(5);
3791+
///
3792+
/// assert!(five == UniqueRc::new(5));
3793+
/// ```
3794+
#[inline]
3795+
fn eq(&self, other: &Self) -> bool {
3796+
PartialEq::eq(&**self, &**other)
3797+
}
3798+
3799+
/// Inequality for two `UniqueRc`s.
3800+
///
3801+
/// Two `UniqueRc`s are not equal if their inner values are not equal.
3802+
///
3803+
/// # Examples
3804+
///
3805+
/// ```
3806+
/// #![feature(unique_rc_arc)]
3807+
/// use std::rc::UniqueRc;
3808+
///
3809+
/// let five = UniqueRc::new(5);
3810+
///
3811+
/// assert!(five != UniqueRc::new(6));
3812+
/// ```
3813+
#[inline]
3814+
fn ne(&self, other: &Self) -> bool {
3815+
PartialEq::ne(&**self, &**other)
3816+
}
3817+
}
3818+
3819+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3820+
impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for UniqueRc<T, A> {
3821+
/// Partial comparison for two `UniqueRc`s.
3822+
///
3823+
/// The two are compared by calling `partial_cmp()` on their inner values.
3824+
///
3825+
/// # Examples
3826+
///
3827+
/// ```
3828+
/// #![feature(unique_rc_arc)]
3829+
/// use std::rc::UniqueRc;
3830+
/// use std::cmp::Ordering;
3831+
///
3832+
/// let five = UniqueRc::new(5);
3833+
///
3834+
/// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueRc::new(6)));
3835+
/// ```
3836+
#[inline(always)]
3837+
fn partial_cmp(&self, other: &UniqueRc<T, A>) -> Option<Ordering> {
3838+
(**self).partial_cmp(&**other)
3839+
}
3840+
3841+
/// Less-than comparison for two `UniqueRc`s.
3842+
///
3843+
/// The two are compared by calling `<` on their inner values.
3844+
///
3845+
/// # Examples
3846+
///
3847+
/// ```
3848+
/// #![feature(unique_rc_arc)]
3849+
/// use std::rc::UniqueRc;
3850+
///
3851+
/// let five = UniqueRc::new(5);
3852+
///
3853+
/// assert!(five < UniqueRc::new(6));
3854+
/// ```
3855+
#[inline(always)]
3856+
fn lt(&self, other: &UniqueRc<T, A>) -> bool {
3857+
**self < **other
3858+
}
3859+
3860+
/// 'Less than or equal to' comparison for two `UniqueRc`s.
3861+
///
3862+
/// The two are compared by calling `<=` on their inner values.
3863+
///
3864+
/// # Examples
3865+
///
3866+
/// ```
3867+
/// #![feature(unique_rc_arc)]
3868+
/// use std::rc::UniqueRc;
3869+
///
3870+
/// let five = UniqueRc::new(5);
3871+
///
3872+
/// assert!(five <= UniqueRc::new(5));
3873+
/// ```
3874+
#[inline(always)]
3875+
fn le(&self, other: &UniqueRc<T, A>) -> bool {
3876+
**self <= **other
3877+
}
3878+
3879+
/// Greater-than comparison for two `UniqueRc`s.
3880+
///
3881+
/// The two are compared by calling `>` on their inner values.
3882+
///
3883+
/// # Examples
3884+
///
3885+
/// ```
3886+
/// #![feature(unique_rc_arc)]
3887+
/// use std::rc::UniqueRc;
3888+
///
3889+
/// let five = UniqueRc::new(5);
3890+
///
3891+
/// assert!(five > UniqueRc::new(4));
3892+
/// ```
3893+
#[inline(always)]
3894+
fn gt(&self, other: &UniqueRc<T, A>) -> bool {
3895+
**self > **other
3896+
}
3897+
3898+
/// 'Greater than or equal to' comparison for two `UniqueRc`s.
3899+
///
3900+
/// The two are compared by calling `>=` on their inner values.
3901+
///
3902+
/// # Examples
3903+
///
3904+
/// ```
3905+
/// #![feature(unique_rc_arc)]
3906+
/// use std::rc::UniqueRc;
3907+
///
3908+
/// let five = UniqueRc::new(5);
3909+
///
3910+
/// assert!(five >= UniqueRc::new(5));
3911+
/// ```
3912+
#[inline(always)]
3913+
fn ge(&self, other: &UniqueRc<T, A>) -> bool {
3914+
**self >= **other
3915+
}
3916+
}
3917+
3918+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3919+
impl<T: ?Sized + Ord, A: Allocator> Ord for UniqueRc<T, A> {
3920+
/// Comparison for two `UniqueRc`s.
3921+
///
3922+
/// The two are compared by calling `cmp()` on their inner values.
3923+
///
3924+
/// # Examples
3925+
///
3926+
/// ```
3927+
/// #![feature(unique_rc_arc)]
3928+
/// use std::rc::UniqueRc;
3929+
/// use std::cmp::Ordering;
3930+
///
3931+
/// let five = UniqueRc::new(5);
3932+
///
3933+
/// assert_eq!(Ordering::Less, five.cmp(&UniqueRc::new(6)));
3934+
/// ```
3935+
#[inline]
3936+
fn cmp(&self, other: &UniqueRc<T, A>) -> Ordering {
3937+
(**self).cmp(&**other)
3938+
}
3939+
}
3940+
3941+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3942+
impl<T: ?Sized + Eq, A: Allocator> Eq for UniqueRc<T, A> {}
3943+
3944+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
3945+
impl<T: ?Sized + Hash, A: Allocator> Hash for UniqueRc<T, A> {
3946+
fn hash<H: Hasher>(&self, state: &mut H) {
3947+
(**self).hash(state);
3948+
}
3949+
}
3950+
37033951
// Depends on A = Global
37043952
impl<T> UniqueRc<T> {
37053953
/// Creates a new `UniqueRc`.
@@ -3791,9 +4039,6 @@ impl<T: ?Sized, A: Allocator> Deref for UniqueRc<T, A> {
37914039
}
37924040
}
37934041

3794-
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
3795-
unsafe impl<T: ?Sized> PinCoerceUnsized for UniqueRc<T> {}
3796-
37974042
#[unstable(feature = "unique_rc_arc", issue = "112566")]
37984043
impl<T: ?Sized, A: Allocator> DerefMut for UniqueRc<T, A> {
37994044
fn deref_mut(&mut self) -> &mut T {

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@
373373
#![feature(thin_box)]
374374
#![feature(try_reserve_kind)]
375375
#![feature(try_with_capacity)]
376+
#![feature(unique_rc_arc)]
376377
#![feature(vec_into_raw_parts)]
377378
// tidy-alphabetical-end
378379
//

library/std/src/os/fd/owned.rs

+8
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,14 @@ impl<T: AsFd + ?Sized> AsFd for crate::rc::Rc<T> {
428428
}
429429
}
430430

431+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
432+
impl<T: AsFd + ?Sized> AsFd for crate::rc::UniqueRc<T> {
433+
#[inline]
434+
fn as_fd(&self) -> BorrowedFd<'_> {
435+
(**self).as_fd()
436+
}
437+
}
438+
431439
#[stable(feature = "asfd_ptrs", since = "1.64.0")]
432440
impl<T: AsFd + ?Sized> AsFd for Box<T> {
433441
#[inline]

library/std/src/os/fd/raw.rs

+8
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,14 @@ impl<T: AsRawFd> AsRawFd for crate::rc::Rc<T> {
266266
}
267267
}
268268

269+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
270+
impl<T: AsRawFd + ?Sized> AsRawFd for crate::rc::UniqueRc<T> {
271+
#[inline]
272+
fn as_raw_fd(&self) -> RawFd {
273+
(**self).as_raw_fd()
274+
}
275+
}
276+
269277
#[stable(feature = "asrawfd_ptrs", since = "1.63.0")]
270278
impl<T: AsRawFd> AsRawFd for Box<T> {
271279
#[inline]

library/std/src/os/windows/io/handle.rs

+8
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,14 @@ impl<T: AsHandle + ?Sized> AsHandle for crate::rc::Rc<T> {
485485
}
486486
}
487487

488+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
489+
impl<T: AsHandle + ?Sized> AsHandle for crate::rc::UniqueRc<T> {
490+
#[inline]
491+
fn as_handle(&self) -> BorrowedHandle<'_> {
492+
(**self).as_handle()
493+
}
494+
}
495+
488496
#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
489497
impl<T: AsHandle + ?Sized> AsHandle for Box<T> {
490498
#[inline]

library/std/src/os/windows/io/socket.rs

+8
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ impl<T: AsSocket> AsSocket for crate::rc::Rc<T> {
279279
}
280280
}
281281

282+
#[unstable(feature = "unique_rc_arc", issue = "112566")]
283+
impl<T: AsSocket + ?Sized> AsSocket for crate::rc::UniqueRc<T> {
284+
#[inline]
285+
fn as_socket(&self) -> BorrowedSocket<'_> {
286+
(**self).as_socket()
287+
}
288+
}
289+
282290
#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
283291
impl<T: AsSocket> AsSocket for Box<T> {
284292
#[inline]

0 commit comments

Comments
 (0)