@@ -20,7 +20,7 @@ use core::iter;
2020use core:: marker:: { PhantomData , Unsize } ;
2121use core:: mem:: { self , ManuallyDrop , align_of_val_raw} ;
2222use core:: num:: NonZeroUsize ;
23- use core:: ops:: { CoerceUnsized , Deref , DerefPure , DispatchFromDyn , LegacyReceiver } ;
23+ use core:: ops:: { CoerceUnsized , Deref , DerefMut , DerefPure , DispatchFromDyn , LegacyReceiver } ;
2424use core:: panic:: { RefUnwindSafe , UnwindSafe } ;
2525use core:: pin:: { Pin , PinCoerceUnsized } ;
2626use core:: ptr:: { self , NonNull } ;
@@ -4066,3 +4066,183 @@ impl<T: core::error::Error + ?Sized> core::error::Error for Arc<T> {
40664066 core:: error:: Error :: provide ( & * * self , req) ;
40674067 }
40684068}
4069+
4070+ /// A uniquely owned [`Arc`].
4071+ ///
4072+ /// This represents an `Arc` that is known to be uniquely owned -- that is, have exactly one strong
4073+ /// reference. Multiple weak pointers can be created, but attempts to upgrade those to strong
4074+ /// references will fail unless the `UniqueArc` they point to has been converted into a regular `Arc`.
4075+ ///
4076+ /// Because they are uniquely owned, the contents of a `UniqueArc` can be freely mutated. A common
4077+ /// use case is to have an object be mutable during its initialization phase but then have it become
4078+ /// immutable and converted to a normal `Arc`.
4079+ ///
4080+ /// This can be used as a flexible way to create cyclic data structures, as in the example below.
4081+ ///
4082+ /// ```
4083+ /// #![feature(unique_rc_arc)]
4084+ /// use std::sync::{Arc, Weak, UniqueArc};
4085+ ///
4086+ /// struct Gadget {
4087+ /// #[allow(dead_code)]
4088+ /// me: Weak<Gadget>,
4089+ /// }
4090+ ///
4091+ /// fn create_gadget() -> Option<Arc<Gadget>> {
4092+ /// let mut rc = UniqueArc::new(Gadget {
4093+ /// me: Weak::new(),
4094+ /// });
4095+ /// rc.me = UniqueArc::downgrade(&rc);
4096+ /// Some(UniqueArc::into_arc(rc))
4097+ /// }
4098+ ///
4099+ /// create_gadget().unwrap();
4100+ /// ```
4101+ ///
4102+ /// An advantage of using `UniqueArc` over [`Arc::new_cyclic`] to build cyclic data structures is that
4103+ /// [`Arc::new_cyclic`]'s `data_fn` parameter cannot be async or return a [`Result`]. As shown in the
4104+ /// previous example, `UniqueArc` allows for more flexibility in the construction of cyclic data,
4105+ /// including fallible or async constructors.
4106+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4107+ #[ derive( Debug ) ]
4108+ pub struct UniqueArc <
4109+ T : ?Sized ,
4110+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ] A : Allocator = Global ,
4111+ > {
4112+ ptr : NonNull < ArcInner < T > > ,
4113+ phantom : PhantomData < ArcInner < T > > ,
4114+ alloc : A ,
4115+ }
4116+
4117+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4118+ impl < T : ?Sized + Unsize < U > , U : ?Sized , A : Allocator > CoerceUnsized < UniqueArc < U , A > >
4119+ for UniqueArc < T , A >
4120+ {
4121+ }
4122+
4123+ // Depends on A = Global
4124+ impl < T > UniqueArc < T > {
4125+ /// Creates a new `UniqueArc`.
4126+ ///
4127+ /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading
4128+ /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`].
4129+ /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will
4130+ /// point to the new [`Arc`].
4131+ #[ cfg( not( no_global_oom_handling) ) ]
4132+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4133+ pub fn new ( value : T ) -> Self {
4134+ Self :: new_in ( value, Global )
4135+ }
4136+ }
4137+
4138+ impl < T , A : Allocator > UniqueArc < T , A > {
4139+ /// Creates a new `UniqueArc` in the provided allocator.
4140+ ///
4141+ /// Weak references to this `UniqueArc` can be created with [`UniqueArc::downgrade`]. Upgrading
4142+ /// these weak references will fail before the `UniqueArc` has been converted into an [`Arc`].
4143+ /// After converting the `UniqueArc` into an [`Arc`], any weak references created beforehand will
4144+ /// point to the new [`Arc`].
4145+ #[ cfg( not( no_global_oom_handling) ) ]
4146+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4147+ pub fn new_in ( data : T , alloc : A ) -> Self {
4148+ let ( ptr, alloc) = Box :: into_unique ( Box :: new_in (
4149+ ArcInner {
4150+ strong : atomic:: AtomicUsize :: new ( 0 ) ,
4151+ // keep one weak reference so if all the weak pointers that are created are dropped
4152+ // the UniqueArc still stays valid.
4153+ weak : atomic:: AtomicUsize :: new ( 1 ) ,
4154+ data,
4155+ } ,
4156+ alloc,
4157+ ) ) ;
4158+ Self { ptr : ptr. into ( ) , phantom : PhantomData , alloc }
4159+ }
4160+ }
4161+
4162+ impl < T : ?Sized , A : Allocator > UniqueArc < T , A > {
4163+ /// Converts the `UniqueArc` into a regular [`Arc`].
4164+ ///
4165+ /// This consumes the `UniqueArc` and returns a regular [`Arc`] that contains the `value` that
4166+ /// is passed to `into_arc`.
4167+ ///
4168+ /// Any weak references created before this method is called can now be upgraded to strong
4169+ /// references.
4170+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4171+ pub fn into_arc ( this : Self ) -> Arc < T , A > {
4172+ let this = ManuallyDrop :: new ( this) ;
4173+
4174+ // Move the allocator out.
4175+ // SAFETY: `this.alloc` will not be accessed again, nor dropped because it is in
4176+ // a `ManuallyDrop`.
4177+ let alloc: A = unsafe { ptr:: read ( & this. alloc ) } ;
4178+
4179+ // SAFETY: This pointer was allocated at creation time so we know it is valid.
4180+ unsafe {
4181+ // Convert our weak reference into a strong reference
4182+ ( * this. ptr . as_ptr ( ) ) . strong . store ( 1 , Release ) ;
4183+ Arc :: from_inner_in ( this. ptr , alloc)
4184+ }
4185+ }
4186+ }
4187+
4188+ impl < T : ?Sized , A : Allocator + Clone > UniqueArc < T , A > {
4189+ /// Creates a new weak reference to the `UniqueArc`.
4190+ ///
4191+ /// Attempting to upgrade this weak reference will fail before the `UniqueArc` has been converted
4192+ /// to a [`Arc`] using [`UniqueArc::into_arc`].
4193+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4194+ pub fn downgrade ( this : & Self ) -> Weak < T , A > {
4195+ // Using a relaxed ordering is alright here, as knowledge of the
4196+ // original reference prevents other threads from erroneously deleting
4197+ // the object or converting the object to a normal `Arc<T, A>`.
4198+ //
4199+ // Note that we don't need to test if the weak counter is locked because there
4200+ // are no such operations like `Arc::get_mut` or `Arc::make_mut` that will lock
4201+ // the weak counter.
4202+ //
4203+ // SAFETY: This pointer was allocated at creation time so we know it is valid.
4204+ let old_size = unsafe { ( * this. ptr . as_ptr ( ) ) . weak . fetch_add ( 1 , Relaxed ) } ;
4205+
4206+ // See comments in Arc::clone() for why we do this (for mem::forget).
4207+ if old_size > MAX_REFCOUNT {
4208+ abort ( ) ;
4209+ }
4210+
4211+ Weak { ptr : this. ptr , alloc : this. alloc . clone ( ) }
4212+ }
4213+ }
4214+
4215+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4216+ impl < T : ?Sized , A : Allocator > Deref for UniqueArc < T , A > {
4217+ type Target = T ;
4218+
4219+ fn deref ( & self ) -> & T {
4220+ // SAFETY: This pointer was allocated at creation time so we know it is valid.
4221+ unsafe { & self . ptr . as_ref ( ) . data }
4222+ }
4223+ }
4224+
4225+ // #[unstable(feature = "unique_rc_arc", issue = "112566")]
4226+ #[ unstable( feature = "pin_coerce_unsized_trait" , issue = "123430" ) ]
4227+ unsafe impl < T : ?Sized > PinCoerceUnsized for UniqueArc < T > { }
4228+
4229+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4230+ impl < T : ?Sized , A : Allocator > DerefMut for UniqueArc < T , A > {
4231+ fn deref_mut ( & mut self ) -> & mut T {
4232+ // SAFETY: This pointer was allocated at creation time so we know it is valid. We know we
4233+ // have unique ownership and therefore it's safe to make a mutable reference because
4234+ // `UniqueArc` owns the only strong reference to itself.
4235+ unsafe { & mut ( * self . ptr . as_ptr ( ) ) . data }
4236+ }
4237+ }
4238+
4239+ #[ unstable( feature = "unique_rc_arc" , issue = "112566" ) ]
4240+ unsafe impl < #[ may_dangle] T : ?Sized , A : Allocator > Drop for UniqueArc < T , A > {
4241+ fn drop ( & mut self ) {
4242+ // See `Arc::drop_slow` which drops an `Arc` with a strong count of 0.
4243+ // SAFETY: This pointer was allocated at creation time so we know it is valid.
4244+ let _weak = Weak { ptr : self . ptr , alloc : & self . alloc } ;
4245+
4246+ unsafe { ptr:: drop_in_place ( & mut ( * self . ptr . as_ptr ( ) ) . data ) } ;
4247+ }
4248+ }
0 commit comments