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