@@ -16,7 +16,7 @@ use core::hash::{Hash, Hasher};
1616use  core:: intrinsics:: abort; 
1717use  core:: iter; 
1818use  core:: marker:: { PhantomData ,  Unpin ,  Unsize } ; 
19- use  core:: mem:: { self ,  align_of ,   align_of_val,  size_of_val} ; 
19+ use  core:: mem:: { self ,  align_of_val,  size_of_val} ; 
2020use  core:: ops:: { CoerceUnsized ,  Deref ,  DispatchFromDyn ,  Receiver } ; 
2121use  core:: pin:: Pin ; 
2222use  core:: ptr:: { self ,  NonNull } ; 
@@ -267,6 +267,7 @@ pub struct Weak<T: ?Sized> {
267267    // `Weak::new` sets this to `usize::MAX` so that it doesn’t need 
268268    // to allocate space on the heap.  That's not a value a real pointer 
269269    // will ever have because RcBox has alignment at least 2. 
270+     // This is only possible when `T: Sized`; unsized `T` never dangle. 
270271    ptr :  NonNull < ArcInner < T > > , 
271272} 
272273
@@ -590,17 +591,11 @@ impl<T: ?Sized> Arc<T> {
590591     #[ stable( feature = "weak_into_raw" ,  since = "1.45.0" ) ]  
591592    pub  fn  as_ptr ( this :  & Self )  -> * const  T  { 
592593        let  ptr:  * mut  ArcInner < T >  = NonNull :: as_ptr ( this. ptr ) ; 
593-         let  fake_ptr = ptr as  * mut  T ; 
594594
595-         // SAFETY: This cannot go through Deref::deref. 
596-         // Instead, we manually offset the pointer rather than manifesting a reference. 
597-         // This is so that the returned pointer retains the same provenance as our pointer. 
598-         // This is required so that e.g. `get_mut` can write through the pointer 
599-         // after the Arc is recovered through `from_raw`. 
600-         unsafe  { 
601-             let  offset = data_offset ( & ( * ptr) . data ) ; 
602-             set_data_ptr ( fake_ptr,  ( ptr as  * mut  u8 ) . offset ( offset) ) 
603-         } 
595+         // SAFETY: This cannot go through Deref::deref or RcBoxPtr::inner because 
596+         // this is required to retain raw/mut provenance such that e.g. `get_mut` can 
597+         // write through the pointer after the Rc is recovered through `from_raw`. 
598+         unsafe  {  & raw  const  ( * ptr) . data  } 
604599    } 
605600
606601    /// Constructs an `Arc<T>` from a raw pointer. 
@@ -1476,9 +1471,18 @@ impl<T> Weak<T> {
14761471     /// [`null`]: ../../std/ptr/fn.null.html 
14771472     #[ stable( feature = "weak_into_raw" ,  since = "1.45.0" ) ]  
14781473    pub  fn  as_ptr ( & self )  -> * const  T  { 
1479-         let  offset = data_offset_sized :: < T > ( ) ; 
1480-         let  ptr = self . ptr . cast :: < u8 > ( ) . as_ptr ( ) . wrapping_offset ( offset) ; 
1481-         ptr as  * const  T 
1474+         let  ptr:  * mut  ArcInner < T >  = NonNull :: as_ptr ( self . ptr ) ; 
1475+ 
1476+         // SAFETY: we must offset the pointer manually, and said pointer may be 
1477+         // a dangling weak (usize::MAX) if T is sized. data_offset is safe to call, 
1478+         // because we know that a pointer to unsized T was derived from a real 
1479+         // unsized T, as dangling weaks are only created for sized T. wrapping_offset 
1480+         // is used so that we can use the same code path for the non-dangling 
1481+         // unsized case and the potentially dangling sized case. 
1482+         unsafe  { 
1483+             let  offset = data_offset ( ptr as  * mut  T ) ; 
1484+             set_data_ptr ( ptr as  * mut  T ,  ( ptr as  * mut  u8 ) . wrapping_offset ( offset) ) 
1485+         } 
14821486    } 
14831487
14841488    /// Consumes the `Weak<T>` and turns it into a raw pointer. 
@@ -2270,7 +2274,16 @@ impl<T: ?Sized> AsRef<T> for Arc<T> {
22702274#[ stable( feature = "pin" ,  since = "1.33.0" ) ]  
22712275impl < T :  ?Sized >  Unpin  for  Arc < T >  { } 
22722276
2273- /// Computes the offset of the data field within `ArcInner`. 
2277+ /// Get the offset within an `ArcInner` for 
2278+ /// a payload of type described by a pointer. 
2279+ /// 
2280+ /// # Safety 
2281+ /// 
2282+ /// This has the same safety requirements as `align_of_val_raw`. In effect: 
2283+ /// 
2284+ /// - This function is safe for any argument if `T` is sized, and 
2285+ /// - if `T` is unsized, the pointer must have appropriate pointer metadata 
2286+ ///   aquired from the real instance that you are getting this offset for. 
22742287unsafe  fn  data_offset < T :  ?Sized > ( ptr :  * const  T )  -> isize  { 
22752288    // Align the unsized value to the end of the `ArcInner`. 
22762289    // Because it is `?Sized`, it will always be the last field in memory. 
@@ -2279,13 +2292,6 @@ unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
22792292    unsafe  {  data_offset_align ( align_of_val ( & * ptr) )  } 
22802293} 
22812294
2282- /// Computes the offset of the data field within `ArcInner`. 
2283- /// 
2284- /// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. 
2285- fn  data_offset_sized < T > ( )  -> isize  { 
2286-     data_offset_align ( align_of :: < T > ( ) ) 
2287- } 
2288- 
22892295#[ inline]  
22902296fn  data_offset_align ( align :  usize )  -> isize  { 
22912297    let  layout = Layout :: new :: < ArcInner < ( ) > > ( ) ; 
0 commit comments