@@ -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,68 @@ 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 > {
75+ type Weak = sync:: Weak < T > ;
76+
6777 #[ rustfmt:: skip]
6878 #[ inline( always) ]
6979 fn as_raw ( this : & Self ) -> * const T {
70- #[ cfg( not( has_Arc__as_raw ) ) ] {
80+ #[ cfg( not( has_Arc__as_ptr ) ) ] {
7181 Arc :: into_raw ( unsafe { ptr:: read ( this) } )
7282 }
7383 #[ cfg( has_Arc__as_raw) ] {
74- Arc :: as_raw ( this)
84+ Arc :: as_ptr ( this)
7585 }
7686 }
7787
78- #[ rustfmt:: skip]
7988 #[ inline( always) ]
8089 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- }
90+ Arc :: clone ( & ManuallyDrop :: new ( Arc :: from_raw ( this) ) )
91+ }
92+
93+ #[ inline( always) ]
94+ unsafe fn downgrade_raw ( this : * const T ) -> sync:: Weak < T > {
95+ let this = ManuallyDrop :: new ( Arc :: from_raw ( this) ) ;
96+ Arc :: downgrade ( & this)
8797 }
8898}
8999
90100impl < T : ?Sized > RawRc < T > for Rc < T > {
101+ type Weak = rc:: Weak < T > ;
102+
91103 #[ rustfmt:: skip]
92104 #[ inline( always) ]
93105 fn as_raw ( this : & Self ) -> * const T {
94- #[ cfg( not( has_Rc__as_raw ) ) ] {
106+ #[ cfg( not( has_Rc__as_ptr ) ) ] {
95107 Rc :: into_raw ( unsafe { ptr:: read ( this) } )
96108 }
97- #[ cfg( has_Rc__as_raw ) ] {
98- Rc :: as_raw ( this)
109+ #[ cfg( has_Rc__as_ptr ) ] {
110+ Rc :: as_ptr ( this)
99111 }
100112 }
101113
102- #[ rustfmt:: skip]
103114 #[ inline( always) ]
104115 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- }
116+ Rc :: clone ( & ManuallyDrop :: new ( Rc :: from_raw ( this) ) )
117+ }
118+
119+ #[ inline( always) ]
120+ unsafe fn downgrade_raw ( this : * const T ) -> rc:: Weak < T > {
121+ let this = ManuallyDrop :: new ( Rc :: from_raw ( this) ) ;
122+ Rc :: downgrade ( & this)
111123 }
112124}
113125
@@ -120,7 +132,7 @@ macro_rules! doc_comment {
120132}
121133
122134macro_rules! rc_borrow {
123- ( $( $( #[ $m: meta] ) * $vis: vis struct $RcBorrow: ident = & $Rc: ident; ) * ) => { $(
135+ ( $( $( #[ $m: meta] ) * $vis: vis struct $RcBorrow: ident = & $Rc: ident ( $rc : ident ) ; ) * ) => { $(
124136 $( #[ $m] ) *
125137 $vis struct $RcBorrow<' a, T : ?Sized > {
126138 raw: ptr:: NonNull <T >,
@@ -147,6 +159,11 @@ macro_rules! rc_borrow {
147159 unsafe { <$Rc<T > as RawRc <T >>:: clone_raw( this. raw. as_ptr( ) ) }
148160 }
149161
162+ /// Convert this borrowed pointer into a weak pointer.
163+ $vis fn weaken( this: Self ) -> $rc:: Weak <T > {
164+ unsafe { <$Rc<T > as RawRc <T >>:: downgrade_raw( this. raw. as_ptr( ) ) }
165+ }
166+
150167 /// Convert this borrowed pointer into a standard reference.
151168 ///
152169 /// This gives you a long-lived reference,
@@ -377,10 +394,10 @@ rc_borrow! {
377394 ///
378395 /// This type is guaranteed to have the same repr as `&T`.
379396 #[ repr( transparent) ]
380- pub struct ArcBorrow = & Arc ;
397+ pub struct ArcBorrow = & Arc ( sync ) ;
381398 /// Borrowed version of [`Rc`].
382399 ///
383400 /// This type is guaranteed to have the same repr as `&T`.
384401 #[ repr( transparent) ]
385- pub struct RcBorrow = & Rc ;
402+ pub struct RcBorrow = & Rc ( rc ) ;
386403}
0 commit comments