@@ -35,7 +35,10 @@ use std::{
3535 panic:: { RefUnwindSafe , UnwindSafe } ,
3636} ;
3737use {
38- alloc:: { rc:: Rc , sync:: Arc } ,
38+ alloc:: {
39+ rc:: { self , Rc } ,
40+ sync:: { self , Arc } ,
41+ } ,
3942 core:: {
4043 borrow:: Borrow ,
4144 cmp:: Ordering ,
@@ -55,59 +58,58 @@ use {
5558/// See https://internals.rust-lang.org/t/_/11463/11 for why these are important.
5659/// By using a trait here, we can more easily switch when these functions are available.
5760trait RawRc < T : ?Sized > {
61+ type Weak ;
62+
5863 //noinspection RsSelfConvention
5964 fn as_raw ( this : & Self ) -> * const T ;
65+
6066 /// # Safety
6167 ///
6268 /// This pointer must have come from [`RawRc::as_raw`] or `into_raw`.
6369 unsafe fn clone_raw ( this : * const T ) -> Self ;
70+
71+ unsafe fn downgrade_raw ( this : * const T ) -> Self :: Weak ;
6472}
6573
6674impl < T : ?Sized > RawRc < T > for Arc < T > {
67- #[ rustfmt:: skip]
75+ type Weak = sync:: Weak < T > ;
76+
6877 #[ inline( always) ]
6978 fn as_raw ( this : & Self ) -> * const T {
70- #[ cfg( not( has_Arc__as_raw) ) ] {
71- Arc :: into_raw ( unsafe { ptr:: read ( this) } )
72- }
73- #[ cfg( has_Arc__as_raw) ] {
74- Arc :: as_raw ( this)
75- }
79+ // Arc::as_ptr(this)
80+ Arc :: into_raw ( unsafe { ptr:: read ( this) } )
7681 }
7782
78- #[ rustfmt:: skip]
7983 #[ inline( always) ]
8084 unsafe fn clone_raw ( this : * const T ) -> Self {
81- #[ cfg( not( has_Arc__clone_raw) ) ] {
82- Arc :: clone ( & ManuallyDrop :: new ( Arc :: from_raw ( this) ) )
83- }
84- #[ cfg( has_Arc__clone_raw) ] {
85- Arc :: clone_raw ( this)
86- }
85+ Arc :: clone ( & ManuallyDrop :: new ( Arc :: from_raw ( this) ) )
86+ }
87+
88+ #[ inline( always) ]
89+ unsafe fn downgrade_raw ( this : * const T ) -> sync:: Weak < T > {
90+ let this = ManuallyDrop :: new ( Arc :: from_raw ( this) ) ;
91+ Arc :: downgrade ( & this)
8792 }
8893}
8994
9095impl < T : ?Sized > RawRc < T > for Rc < T > {
91- #[ rustfmt:: skip]
96+ type Weak = rc:: Weak < T > ;
97+
9298 #[ inline( always) ]
9399 fn as_raw ( this : & Self ) -> * const T {
94- #[ cfg( not( has_Rc__as_raw) ) ] {
95- Rc :: into_raw ( unsafe { ptr:: read ( this) } )
96- }
97- #[ cfg( has_Rc__as_raw) ] {
98- Rc :: as_raw ( this)
99- }
100+ // Rc::as_ptr(this)
101+ Rc :: into_raw ( unsafe { ptr:: read ( this) } )
100102 }
101103
102- #[ rustfmt:: skip]
103104 #[ inline( always) ]
104105 unsafe fn clone_raw ( this : * const T ) -> Self {
105- #[ cfg( not( has_Rc__clone_raw) ) ] {
106- Rc :: clone ( & ManuallyDrop :: new ( Rc :: from_raw ( this) ) )
107- }
108- #[ cfg( has_Rc__clone_raw) ] {
109- Rc :: clone_raw ( this)
110- }
106+ Rc :: clone ( & ManuallyDrop :: new ( Rc :: from_raw ( this) ) )
107+ }
108+
109+ #[ inline( always) ]
110+ unsafe fn downgrade_raw ( this : * const T ) -> rc:: Weak < T > {
111+ let this = ManuallyDrop :: new ( Rc :: from_raw ( this) ) ;
112+ Rc :: downgrade ( & this)
111113 }
112114}
113115
@@ -120,7 +122,7 @@ macro_rules! doc_comment {
120122}
121123
122124macro_rules! rc_borrow {
123- ( $( $( #[ $m: meta] ) * $vis: vis struct $RcBorrow: ident = & $Rc: ident; ) * ) => { $(
125+ ( $( $( #[ $m: meta] ) * $vis: vis struct $RcBorrow: ident = & $rc : ident :: $ Rc: ident; ) * ) => { $(
124126 $( #[ $m] ) *
125127 $vis struct $RcBorrow<' a, T : ?Sized > {
126128 raw: ptr:: NonNull <T >,
@@ -147,6 +149,11 @@ macro_rules! rc_borrow {
147149 unsafe { <$Rc<T > as RawRc <T >>:: clone_raw( this. raw. as_ptr( ) ) }
148150 }
149151
152+ /// Convert this borrowed pointer into a weak pointer.
153+ $vis fn weaken( this: Self ) -> $rc:: Weak <T > {
154+ unsafe { <$Rc<T > as RawRc <T >>:: downgrade_raw( this. raw. as_ptr( ) ) }
155+ }
156+
150157 /// Convert this borrowed pointer into a standard reference.
151158 ///
152159 /// This gives you a long-lived reference,
@@ -377,10 +384,10 @@ rc_borrow! {
377384 ///
378385 /// This type is guaranteed to have the same repr as `&T`.
379386 #[ repr( transparent) ]
380- pub struct ArcBorrow = & Arc ;
387+ pub struct ArcBorrow = & sync :: Arc ;
381388 /// Borrowed version of [`Rc`].
382389 ///
383390 /// This type is guaranteed to have the same repr as `&T`.
384391 #[ repr( transparent) ]
385- pub struct RcBorrow = & Rc ;
392+ pub struct RcBorrow = & rc :: Rc ;
386393}
0 commit comments