@@ -295,6 +295,13 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
295295impl < T : ?Sized + Unsize < U > , U : ?Sized > DispatchFromDyn < Rc < U > > for Rc < T > { }
296296
297297impl < T : ?Sized > Rc < T > {
298+ #[ inline( always) ]
299+ fn inner ( & self ) -> & RcBox < T > {
300+ // This unsafety is ok because while this Rc is alive we're guaranteed
301+ // that the inner pointer is valid.
302+ unsafe { self . ptr . as_ref ( ) }
303+ }
304+
298305 fn from_inner ( ptr : NonNull < RcBox < T > > ) -> Self {
299306 Self { ptr, phantom : PhantomData }
300307 }
@@ -469,7 +476,7 @@ impl<T> Rc<T> {
469476 // the strong count, and then remove the implicit "strong weak"
470477 // pointer while also handling drop logic by just crafting a
471478 // fake Weak.
472- this. dec_strong ( ) ;
479+ this. inner ( ) . dec_strong ( ) ;
473480 let _weak = Weak { ptr : this. ptr } ;
474481 forget ( this) ;
475482 Ok ( val)
@@ -735,7 +742,7 @@ impl<T: ?Sized> Rc<T> {
735742 /// ```
736743 #[ stable( feature = "rc_weak" , since = "1.4.0" ) ]
737744 pub fn downgrade ( this : & Self ) -> Weak < T > {
738- this. inc_weak ( ) ;
745+ this. inner ( ) . inc_weak ( ) ;
739746 // Make sure we do not create a dangling Weak
740747 debug_assert ! ( !is_dangling( this. ptr) ) ;
741748 Weak { ptr : this. ptr }
@@ -756,7 +763,7 @@ impl<T: ?Sized> Rc<T> {
756763 #[ inline]
757764 #[ stable( feature = "rc_counts" , since = "1.15.0" ) ]
758765 pub fn weak_count ( this : & Self ) -> usize {
759- this. weak ( ) - 1
766+ this. inner ( ) . weak ( ) - 1
760767 }
761768
762769 /// Gets the number of strong (`Rc`) pointers to this allocation.
@@ -774,7 +781,7 @@ impl<T: ?Sized> Rc<T> {
774781 #[ inline]
775782 #[ stable( feature = "rc_counts" , since = "1.15.0" ) ]
776783 pub fn strong_count ( this : & Self ) -> usize {
777- this. strong ( )
784+ this. inner ( ) . strong ( )
778785 }
779786
780787 /// Returns `true` if there are no other `Rc` or [`Weak`] pointers to
@@ -844,7 +851,9 @@ impl<T: ?Sized> Rc<T> {
844851 #[ inline]
845852 #[ unstable( feature = "get_mut_unchecked" , issue = "63292" ) ]
846853 pub unsafe fn get_mut_unchecked ( this : & mut Self ) -> & mut T {
847- unsafe { & mut this. ptr . as_mut ( ) . value }
854+ // We are careful to *not* create a reference covering the "count" fields, as
855+ // this would conflict with accesses to the reference counts (e.g. by `Weak`).
856+ unsafe { & mut ( * this. ptr . as_ptr ( ) ) . value }
848857 }
849858
850859 #[ inline]
@@ -931,10 +940,10 @@ impl<T: Clone> Rc<T> {
931940 unsafe {
932941 let mut swap = Rc :: new ( ptr:: read ( & this. ptr . as_ref ( ) . value ) ) ;
933942 mem:: swap ( this, & mut swap) ;
934- swap. dec_strong ( ) ;
943+ swap. inner ( ) . dec_strong ( ) ;
935944 // Remove implicit strong-weak ref (no need to craft a fake
936945 // Weak here -- we know other Weaks can clean up for us)
937- swap. dec_weak ( ) ;
946+ swap. inner ( ) . dec_weak ( ) ;
938947 forget ( swap) ;
939948 }
940949 }
@@ -1192,16 +1201,16 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc<T> {
11921201 /// ```
11931202 fn drop ( & mut self ) {
11941203 unsafe {
1195- self . dec_strong ( ) ;
1196- if self . strong ( ) == 0 {
1204+ self . inner ( ) . dec_strong ( ) ;
1205+ if self . inner ( ) . strong ( ) == 0 {
11971206 // destroy the contained object
1198- ptr:: drop_in_place ( self . ptr . as_mut ( ) ) ;
1207+ ptr:: drop_in_place ( Self :: get_mut_unchecked ( self ) ) ;
11991208
12001209 // remove the implicit "strong weak" pointer now that we've
12011210 // destroyed the contents.
1202- self . dec_weak ( ) ;
1211+ self . inner ( ) . dec_weak ( ) ;
12031212
1204- if self . weak ( ) == 0 {
1213+ if self . inner ( ) . weak ( ) == 0 {
12051214 Global . dealloc ( self . ptr . cast ( ) , Layout :: for_value ( self . ptr . as_ref ( ) ) ) ;
12061215 }
12071216 }
@@ -1227,7 +1236,7 @@ impl<T: ?Sized> Clone for Rc<T> {
12271236 /// ```
12281237 #[ inline]
12291238 fn clone ( & self ) -> Rc < T > {
1230- self . inc_strong ( ) ;
1239+ self . inner ( ) . inc_strong ( ) ;
12311240 Self :: from_inner ( self . ptr )
12321241 }
12331242}
@@ -1851,6 +1860,13 @@ pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool {
18511860 address == usize:: MAX
18521861}
18531862
1863+ /// Helper type to allow accessing the reference counts without
1864+ /// making any assertions about the data field.
1865+ struct WeakInner < ' a > {
1866+ weak : & ' a Cell < usize > ,
1867+ strong : & ' a Cell < usize > ,
1868+ }
1869+
18541870impl < T : ?Sized > Weak < T > {
18551871 /// Attempts to upgrade the `Weak` pointer to an [`Rc`], delaying
18561872 /// dropping of the inner value if successful.
@@ -1910,11 +1926,21 @@ impl<T: ?Sized> Weak<T> {
19101926 . unwrap_or ( 0 )
19111927 }
19121928
1913- /// Returns `None` when the pointer is dangling and there is no allocated `RcBox`
1929+ /// Returns `None` when the pointer is dangling and there is no allocated `RcBox`,
19141930 /// (i.e., when this `Weak` was created by `Weak::new`).
19151931 #[ inline]
1916- fn inner ( & self ) -> Option < & RcBox < T > > {
1917- if is_dangling ( self . ptr ) { None } else { Some ( unsafe { self . ptr . as_ref ( ) } ) }
1932+ fn inner ( & self ) -> Option < WeakInner < ' _ > > {
1933+ if is_dangling ( self . ptr ) {
1934+ None
1935+ } else {
1936+ // We are careful to *not* create a reference covering the "data" field, as
1937+ // the field may be mutated concurrently (for example, if the last `Rc`
1938+ // is dropped, the data field will be dropped in-place).
1939+ Some ( unsafe {
1940+ let ptr = self . ptr . as_ptr ( ) ;
1941+ WeakInner { strong : & ( * ptr) . strong , weak : & ( * ptr) . weak }
1942+ } )
1943+ }
19181944 }
19191945
19201946 /// Returns `true` if the two `Weak`s point to the same allocation (similar to
@@ -1992,14 +2018,14 @@ impl<T: ?Sized> Drop for Weak<T> {
19922018 /// assert!(other_weak_foo.upgrade().is_none());
19932019 /// ```
19942020 fn drop ( & mut self ) {
1995- if let Some ( inner) = self . inner ( ) {
1996- inner . dec_weak ( ) ;
1997- // the weak count starts at 1, and will only go to zero if all
1998- // the strong pointers have disappeared.
1999- if inner . weak ( ) == 0 {
2000- unsafe {
2001- Global . dealloc ( self . ptr . cast ( ) , Layout :: for_value ( self . ptr . as_ref ( ) ) ) ;
2002- }
2021+ let inner = if let Some ( inner) = self . inner ( ) { inner } else { return } ;
2022+
2023+ inner . dec_weak ( ) ;
2024+ // the weak count starts at 1, and will only go to zero if all
2025+ // the strong pointers have disappeared.
2026+ if inner . weak ( ) == 0 {
2027+ unsafe {
2028+ Global . dealloc ( self . ptr . cast ( ) , Layout :: for_value ( self . ptr . as_ref ( ) ) ) ;
20032029 }
20042030 }
20052031 }
@@ -2065,12 +2091,13 @@ impl<T> Default for Weak<T> {
20652091// clone these much in Rust thanks to ownership and move-semantics.
20662092
20672093#[ doc( hidden) ]
2068- trait RcBoxPtr < T : ?Sized > {
2069- fn inner ( & self ) -> & RcBox < T > ;
2094+ trait RcInnerPtr {
2095+ fn weak_ref ( & self ) -> & Cell < usize > ;
2096+ fn strong_ref ( & self ) -> & Cell < usize > ;
20702097
20712098 #[ inline]
20722099 fn strong ( & self ) -> usize {
2073- self . inner ( ) . strong . get ( )
2100+ self . strong_ref ( ) . get ( )
20742101 }
20752102
20762103 #[ inline]
@@ -2084,17 +2111,17 @@ trait RcBoxPtr<T: ?Sized> {
20842111 if strong == 0 || strong == usize:: MAX {
20852112 abort ( ) ;
20862113 }
2087- self . inner ( ) . strong . set ( strong + 1 ) ;
2114+ self . strong_ref ( ) . set ( strong + 1 ) ;
20882115 }
20892116
20902117 #[ inline]
20912118 fn dec_strong ( & self ) {
2092- self . inner ( ) . strong . set ( self . strong ( ) - 1 ) ;
2119+ self . strong_ref ( ) . set ( self . strong ( ) - 1 ) ;
20932120 }
20942121
20952122 #[ inline]
20962123 fn weak ( & self ) -> usize {
2097- self . inner ( ) . weak . get ( )
2124+ self . weak_ref ( ) . get ( )
20982125 }
20992126
21002127 #[ inline]
@@ -2108,26 +2135,36 @@ trait RcBoxPtr<T: ?Sized> {
21082135 if weak == 0 || weak == usize:: MAX {
21092136 abort ( ) ;
21102137 }
2111- self . inner ( ) . weak . set ( weak + 1 ) ;
2138+ self . weak_ref ( ) . set ( weak + 1 ) ;
21122139 }
21132140
21142141 #[ inline]
21152142 fn dec_weak ( & self ) {
2116- self . inner ( ) . weak . set ( self . weak ( ) - 1 ) ;
2143+ self . weak_ref ( ) . set ( self . weak ( ) - 1 ) ;
21172144 }
21182145}
21192146
2120- impl < T : ?Sized > RcBoxPtr < T > for Rc < T > {
2147+ impl < T : ?Sized > RcInnerPtr for RcBox < T > {
21212148 #[ inline( always) ]
2122- fn inner ( & self ) -> & RcBox < T > {
2123- unsafe { self . ptr . as_ref ( ) }
2149+ fn weak_ref ( & self ) -> & Cell < usize > {
2150+ & self . weak
2151+ }
2152+
2153+ #[ inline( always) ]
2154+ fn strong_ref ( & self ) -> & Cell < usize > {
2155+ & self . strong
21242156 }
21252157}
21262158
2127- impl < T : ? Sized > RcBoxPtr < T > for RcBox < T > {
2159+ impl < ' a > RcInnerPtr for WeakInner < ' a > {
21282160 #[ inline( always) ]
2129- fn inner ( & self ) -> & RcBox < T > {
2130- self
2161+ fn weak_ref ( & self ) -> & Cell < usize > {
2162+ self . weak
2163+ }
2164+
2165+ #[ inline( always) ]
2166+ fn strong_ref ( & self ) -> & Cell < usize > {
2167+ self . strong
21312168 }
21322169}
21332170
0 commit comments