@@ -35,7 +35,10 @@ use std::{
35
35
panic:: { RefUnwindSafe , UnwindSafe } ,
36
36
} ;
37
37
use {
38
- alloc:: { rc:: Rc , sync:: Arc } ,
38
+ alloc:: {
39
+ rc:: { self , Rc } ,
40
+ sync:: { self , Arc } ,
41
+ } ,
39
42
core:: {
40
43
borrow:: Borrow ,
41
44
cmp:: Ordering ,
@@ -55,59 +58,58 @@ use {
55
58
/// See https://internals.rust-lang.org/t/_/11463/11 for why these are important.
56
59
/// By using a trait here, we can more easily switch when these functions are available.
57
60
trait RawRc < T : ?Sized > {
61
+ type Weak ;
62
+
58
63
//noinspection RsSelfConvention
59
64
fn as_raw ( this : & Self ) -> * const T ;
65
+
60
66
/// # Safety
61
67
///
62
68
/// This pointer must have come from [`RawRc::as_raw`] or `into_raw`.
63
69
unsafe fn clone_raw ( this : * const T ) -> Self ;
70
+
71
+ unsafe fn downgrade_raw ( this : * const T ) -> Self :: Weak ;
64
72
}
65
73
66
74
impl < T : ?Sized > RawRc < T > for Arc < T > {
67
- #[ rustfmt:: skip]
75
+ type Weak = sync:: Weak < T > ;
76
+
68
77
#[ inline( always) ]
69
78
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) } )
76
81
}
77
82
78
- #[ rustfmt:: skip]
79
83
#[ inline( always) ]
80
84
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)
87
92
}
88
93
}
89
94
90
95
impl < T : ?Sized > RawRc < T > for Rc < T > {
91
- #[ rustfmt:: skip]
96
+ type Weak = rc:: Weak < T > ;
97
+
92
98
#[ inline( always) ]
93
99
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) } )
100
102
}
101
103
102
- #[ rustfmt:: skip]
103
104
#[ inline( always) ]
104
105
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)
111
113
}
112
114
}
113
115
@@ -120,7 +122,7 @@ macro_rules! doc_comment {
120
122
}
121
123
122
124
macro_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; ) * ) => { $(
124
126
$( #[ $m] ) *
125
127
$vis struct $RcBorrow<' a, T : ?Sized > {
126
128
raw: ptr:: NonNull <T >,
@@ -147,6 +149,11 @@ macro_rules! rc_borrow {
147
149
unsafe { <$Rc<T > as RawRc <T >>:: clone_raw( this. raw. as_ptr( ) ) }
148
150
}
149
151
152
+ /// Convert this borrowed pointer into a weak pointer.
153
+ $vis fn to_weak( this: Self ) -> $rc:: Weak <T > {
154
+ unsafe { <$Rc<T > as RawRc <T >>:: downgrade_raw( this. raw. as_ptr( ) ) }
155
+ }
156
+
150
157
/// Convert this borrowed pointer into a standard reference.
151
158
///
152
159
/// This gives you a long-lived reference,
@@ -377,10 +384,10 @@ rc_borrow! {
377
384
///
378
385
/// This type is guaranteed to have the same repr as `&T`.
379
386
#[ repr( transparent) ]
380
- pub struct ArcBorrow = & Arc ;
387
+ pub struct ArcBorrow = & sync :: Arc ;
381
388
/// Borrowed version of [`Rc`].
382
389
///
383
390
/// This type is guaranteed to have the same repr as `&T`.
384
391
#[ repr( transparent) ]
385
- pub struct RcBorrow = & Rc ;
392
+ pub struct RcBorrow = & rc :: Rc ;
386
393
}
0 commit comments