Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 5e7406c

Browse files
committed
Adjust sync::Weak::from_raw to support unsized T
1 parent 0c61ce2 commit 5e7406c

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

library/alloc/src/sync.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,17 +1629,18 @@ impl<T> Weak<T> {
16291629
/// [`forget`]: std::mem::forget
16301630
#[stable(feature = "weak_into_raw", since = "1.45.0")]
16311631
pub unsafe fn from_raw(ptr: *const T) -> Self {
1632-
if ptr.is_null() {
1633-
Self::new()
1634-
} else {
1635-
// See Arc::from_raw for details
1636-
unsafe {
1637-
let offset = data_offset(ptr);
1638-
let fake_ptr = ptr as *mut ArcInner<T>;
1639-
let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
1640-
Weak { ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw") }
1641-
}
1642-
}
1632+
// SAFETY: data_offset is safe to call, because this pointer originates from a Weak.
1633+
// See Weak::as_ptr for context on how the input pointer is derived.
1634+
let offset = unsafe { data_offset(ptr) };
1635+
1636+
// Reverse the offset to find the original ArcInner.
1637+
// SAFETY: we use wrapping_offset here because the pointer may be dangling (iff T: Sized)
1638+
let ptr = unsafe {
1639+
set_data_ptr(ptr as *mut ArcInner<T>, (ptr as *mut u8).wrapping_offset(-offset))
1640+
};
1641+
1642+
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
1643+
unsafe { Weak { ptr: NonNull::new_unchecked(ptr) } }
16431644
}
16441645
}
16451646

0 commit comments

Comments
 (0)