@@ -245,7 +245,7 @@ use core::hash::{Hash, Hasher};
245
245
use core:: intrinsics:: abort;
246
246
use core:: iter;
247
247
use 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} ;
249
249
use core:: ops:: { CoerceUnsized , Deref , DispatchFromDyn , Receiver } ;
250
250
use core:: pin:: Pin ;
251
251
use core:: ptr:: { self , NonNull } ;
@@ -1704,9 +1704,18 @@ impl<T> Weak<T> {
1704
1704
/// [`null`]: ../../std/ptr/fn.null.html
1705
1705
#[ stable( feature = "weak_into_raw" , since = "1.45.0" ) ]
1706
1706
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
+ }
1710
1719
}
1711
1720
1712
1721
/// 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 {
2117
2126
unsafe { data_offset_align ( align_of_val_raw ( ptr) ) }
2118
2127
}
2119
2128
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
-
2127
2129
#[ inline]
2128
2130
fn data_offset_align ( align : usize ) -> isize {
2129
2131
let layout = Layout :: new :: < RcBox < ( ) > > ( ) ;
0 commit comments