diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 0205c40829930..8c70b0a913a98 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -575,6 +575,11 @@ impl Rc { let fake_ptr = ptr as *mut T; mem::forget(this); + // 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 Rc is recovered through `from_raw`. unsafe { let offset = data_offset(&(*ptr).value); set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index de56cb300d38c..5c1fa17a626d1 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -555,6 +555,11 @@ impl Arc { let fake_ptr = ptr as *mut T; mem::forget(this); + // 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))