@@ -867,12 +867,10 @@ impl<T: ?Sized> Arc<T> {
867867    unsafe  fn  drop_slow ( & mut  self )  { 
868868        // Destroy the data at this time, even though we may not free the box 
869869        // allocation itself (there may still be weak pointers lying around). 
870-         ptr:: drop_in_place ( & mut   self . ptr . as_mut ( ) . data ) ; 
870+         ptr:: drop_in_place ( Self :: get_mut_unchecked ( self ) ) ; 
871871
872-         if  self . inner ( ) . weak . fetch_sub ( 1 ,  Release )  == 1  { 
873-             acquire ! ( self . inner( ) . weak) ; 
874-             Global . dealloc ( self . ptr . cast ( ) ,  Layout :: for_value ( self . ptr . as_ref ( ) ) ) 
875-         } 
872+         // Drop the weak ref collectively held by all strong references 
873+         drop ( Weak  {  ptr :  self . ptr  } ) ; 
876874    } 
877875
878876    #[ inline]  
@@ -1204,7 +1202,7 @@ impl<T: Clone> Arc<T> {
12041202
12051203        // As with `get_mut()`, the unsafety is ok because our reference was 
12061204        // either unique to begin with, or became one upon cloning the contents. 
1207-         unsafe  {  & mut  this . ptr . as_mut ( ) . data  } 
1205+         unsafe  {  Self :: get_mut_unchecked ( this )  } 
12081206    } 
12091207} 
12101208
@@ -1280,7 +1278,9 @@ impl<T: ?Sized> Arc<T> {
12801278#[ inline]  
12811279    #[ unstable( feature = "get_mut_unchecked" ,  issue = "63292" ) ]  
12821280    pub  unsafe  fn  get_mut_unchecked ( this :  & mut  Self )  -> & mut  T  { 
1283-         & mut  this. ptr . as_mut ( ) . data 
1281+         // We are careful to *not* create a reference covering the "count" fields, as 
1282+         // this would alias with concurrent access to the reference counts (e.g. by `Weak`). 
1283+         & mut  ( * this. ptr . as_ptr ( ) ) . data 
12841284    } 
12851285
12861286    /// Determine whether this is the unique reference (including weak refs) to 
@@ -1571,6 +1571,13 @@ impl<T> Weak<T> {
15711571    } 
15721572} 
15731573
1574+ /// Helper type to allow accessing the reference counts without 
1575+ /// making any assertions about the data field. 
1576+ struct  WeakInner < ' a >  { 
1577+     weak :  & ' a  atomic:: AtomicUsize , 
1578+     strong :  & ' a  atomic:: AtomicUsize , 
1579+ } 
1580+ 
15741581impl < T :  ?Sized >  Weak < T >  { 
15751582    /// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying 
15761583/// dropping of the inner value if successful. 
@@ -1678,8 +1685,18 @@ impl<T: ?Sized> Weak<T> {
16781685    /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`, 
16791686/// (i.e., when this `Weak` was created by `Weak::new`). 
16801687#[ inline]  
1681-     fn  inner ( & self )  -> Option < & ArcInner < T > >  { 
1682-         if  is_dangling ( self . ptr )  {  None  }  else  {  Some ( unsafe  {  self . ptr . as_ref ( )  } )  } 
1688+     fn  inner ( & self )  -> Option < WeakInner < ' _ > >  { 
1689+         if  is_dangling ( self . ptr )  { 
1690+             None 
1691+         }  else  { 
1692+             // We are careful to *not* create a reference covering the "data" field, as 
1693+             // the field may be mutated concurrently (for example, if the last `Arc` 
1694+             // is dropped, the data field will be dropped in-place). 
1695+             Some ( unsafe  { 
1696+                 let  ptr = self . ptr . as_ptr ( ) ; 
1697+                 WeakInner  {  strong :  & ( * ptr) . strong ,  weak :  & ( * ptr) . weak  } 
1698+             } ) 
1699+         } 
16831700    } 
16841701
16851702    /// Returns `true` if the two `Weak`s point to the same allocation (similar to 
0 commit comments