@@ -245,7 +245,7 @@ use core::hash::{Hash, Hasher};
245245use core:: intrinsics:: abort;
246246use core:: iter;
247247use core:: marker:: { self , PhantomData , Unpin , Unsize } ;
248- use core:: mem:: { self , align_of , align_of_val_raw, forget, size_of_val} ;
248+ use core:: mem:: { self , align_of_val_raw, forget, size_of_val} ;
249249use core:: ops:: { CoerceUnsized , Deref , DispatchFromDyn , Receiver } ;
250250use core:: pin:: Pin ;
251251use core:: ptr:: { self , NonNull } ;
@@ -1704,9 +1704,18 @@ impl<T> Weak<T> {
17041704 /// [`null`]: ../../std/ptr/fn.null.html
17051705 #[ stable( feature = "weak_into_raw" , since = "1.45.0" ) ]
17061706 pub fn as_ptr ( & self ) -> * const T {
1707- let offset = data_offset_sized :: < T > ( ) ;
1708- let ptr = self . ptr . cast :: < u8 > ( ) . as_ptr ( ) . wrapping_offset ( offset) ;
1709- ptr as * const T
1707+ let ptr: * mut RcBox < T > = NonNull :: as_ptr ( self . ptr ) ;
1708+ let fake_ptr = ptr as * mut T ;
1709+
1710+ // SAFETY: we must offset the pointer manually, and said pointer may be
1711+ // a dangling weak (usize::MAX). data_offset is safe to call, because we
1712+ // know a pointer to unsized T must be derived from a real unsized T,
1713+ // because dangling weaks are only created for sized T. wrapping_offset
1714+ // is used so that we can use the same code path for dangling weak refs.
1715+ unsafe {
1716+ let offset = data_offset ( & raw const ( * ptr) . value ) ;
1717+ set_data_ptr ( fake_ptr, ( ptr as * mut u8 ) . wrapping_offset ( offset) )
1718+ }
17101719 }
17111720
17121721 /// Consumes the `Weak<T>` and turns it into a raw pointer.
@@ -2117,13 +2126,6 @@ unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
21172126 unsafe { data_offset_align ( align_of_val_raw ( ptr) ) }
21182127}
21192128
2120- /// Computes the offset of the data field within `RcBox`.
2121- ///
2122- /// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`.
2123- fn data_offset_sized < T > ( ) -> isize {
2124- data_offset_align ( align_of :: < T > ( ) )
2125- }
2126-
21272129#[ inline]
21282130fn data_offset_align ( align : usize ) -> isize {
21292131 let layout = Layout :: new :: < RcBox < ( ) > > ( ) ;
0 commit comments