/// ```
///
/// [`null`]: ../../std/ptr/fn.null.html
- #[stable(feature = "weak_into_raw", since = "1.45.0")]
+ #[stable(feature = "rc_as_ptr", since = "1.45.0")]
pub fn as_ptr(&self) -> *const T {
- let offset = data_offset_sized::<T>();
- let ptr = self.ptr.cast::<u8>().as_ptr().wrapping_offset(offset);
- ptr as *const T
+ let ptr: *mut RcBox<T> = NonNull::as_ptr(self.ptr);
+
+ // SAFETY: we must offset the pointer manually, and said pointer may be
+ // a dangling weak (usize::MAX) if T is sized. data_offset is safe to call,
+ // because we know that a pointer to unsized T was derived from a real
+ // unsized T, as dangling weaks are only created for sized T. wrapping_offset
+ // is used so that we can use the same code path for the non-dangling
+ // unsized case and the potentially dangling sized case.
+ unsafe {
+ let offset = data_offset(ptr as *mut T);
+ set_data_ptr(ptr as *mut T, (ptr as *mut u8).wrapping_offset(offset))
+ }
}
/// Consumes the `Weak<T>` and turns it into a raw pointer.
/// assert_eq!(x_ptr, Arc::as_ptr(&y));
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// ```
- #[stable(feature = "weak_into_raw", since = "1.45.0")]
+ #[stable(feature = "rc_as_ptr", since = "1.45.0")]
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
- let fake_ptr = ptr as *mut T;
- // SAFETY: This cannot go through Deref::deref.
- // Instead, we manually offset the pointer rather than manifesting a reference.
- // This is so that the returned pointer retains the same provenance as our pointer.
- // This is required so that e.g. `get_mut` can write through the pointer
- // after the Arc is recovered through `from_raw`.
- unsafe {
- let offset = data_offset(&(*ptr).data);
- set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset))
- }
+ // SAFETY: This cannot go through Deref::deref or RcBoxPtr::inner because
+ // this is required to retain raw/mut provenance such that e.g. `get_mut` can
+ // write through the pointer after the Rc is recovered through `from_raw`.
+ unsafe { &raw const (*ptr).data }
}
/// Constructs an `Arc<T>` from a raw pointer.