Rollup merge of #154081 - safer-rust:main, r=Mark-Simulacrum

format safety doc of Rc/Arc::from_raw/from_raw_in

The following APIs previously had safety notes, but they were not placed under a dedicated Safety section. This PR adds a Safety section for each API and moves the original safety descriptions there:
- [`Rc::from_raw`](https://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.from_raw)
- [`Rc::from_raw_in`](https://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.from_raw_in)
- [`Arc::from_raw`](https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#method.from_raw)
- [`Arc::from_raw_in`](https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#method.from_raw_in)

Additionally, we updated the parameter requirements to clarify that the raw pointer may be returned not only from `into_raw`, but also from `into_raw_with_allocator`.
This commit is contained in:
Stuart Cook
2026-03-28 15:01:37 +11:00
committed by GitHub
2 changed files with 61 additions and 49 deletions
+31 -25
View File
@@ -1430,29 +1430,32 @@ impl<T: ?Sized> Rc<T> {
/// Constructs an `Rc<T>` from a raw pointer.
///
/// The raw pointer must have been previously returned by a call to
/// [`Rc<U>::into_raw`][into_raw] with the following requirements:
/// [`Rc<U>::into_raw`][into_raw] or [`Rc<U>::into_raw_with_allocator`][into_raw_with_allocator].
///
/// # Safety
///
/// * Creating a `Rc<T>` from a pointer other than one returned from
/// [`Rc<U>::into_raw`][into_raw] or [`Rc<U>::into_raw_with_allocator`][into_raw_with_allocator]
/// is undefined behavior.
/// * If `U` is sized, it must have the same size and alignment as `T`. This
/// is trivially true if `U` is `T`.
/// * If `U` is unsized, its data pointer must have the same size and
/// alignment as `T`. This is trivially true if `Rc<U>` was constructed
/// through `Rc<T>` and then converted to `Rc<U>` through an [unsized
/// coercion].
///
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
///
/// The raw pointer must point to a block of memory allocated by the global allocator
///
/// The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
/// * Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
/// * The raw pointer must point to a block of memory allocated by the global allocator
/// * The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
///
/// This function is unsafe because improper use may lead to memory unsafety,
/// even if the returned `Rc<T>` is never accessed.
///
/// [into_raw]: Rc::into_raw
/// [into_raw_with_allocator]: Rc::into_raw_with_allocator
/// [transmute]: core::mem::transmute
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
///
@@ -1662,29 +1665,32 @@ pub fn as_ptr(this: &Self) -> *const T {
/// Constructs an `Rc<T, A>` from a raw pointer in the provided allocator.
///
/// The raw pointer must have been previously returned by a call to [`Rc<U,
/// A>::into_raw`][into_raw] with the following requirements:
/// A>::into_raw`][into_raw] or [`Rc<U, A>::into_raw_with_allocator`][into_raw_with_allocator].
///
/// # Safety
///
/// * Creating a `Rc<T, A>` from a pointer other than one returned from
/// [`Rc<U, A>::into_raw`][into_raw] or [`Rc<U, A>::into_raw_with_allocator`][into_raw_with_allocator]
/// is undefined behavior.
/// * If `U` is sized, it must have the same size and alignment as `T`. This
/// is trivially true if `U` is `T`.
/// * If `U` is unsized, its data pointer must have the same size and
/// alignment as `T`. This is trivially true if `Rc<U>` was constructed
/// through `Rc<T>` and then converted to `Rc<U>` through an [unsized
/// alignment as `T`. This is trivially true if `Rc<U, A>` was constructed
/// through `Rc<T, A>` and then converted to `Rc<U, A>` through an [unsized
/// coercion].
///
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
///
/// The raw pointer must point to a block of memory allocated by `alloc`
///
/// The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
/// * Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
/// * The raw pointer must point to a block of memory allocated by `alloc`
/// * The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
///
/// This function is unsafe because improper use may lead to memory unsafety,
/// even if the returned `Rc<T>` is never accessed.
/// even if the returned `Rc<T, A>` is never accessed.
///
/// [into_raw]: Rc::into_raw
/// [into_raw_with_allocator]: Rc::into_raw_with_allocator
/// [transmute]: core::mem::transmute
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
///
+30 -24
View File
@@ -1581,29 +1581,32 @@ impl<T: ?Sized> Arc<T> {
/// Constructs an `Arc<T>` from a raw pointer.
///
/// The raw pointer must have been previously returned by a call to
/// [`Arc<U>::into_raw`][into_raw] with the following requirements:
/// [`Arc<U>::into_raw`][into_raw] or [`Arc<U>::into_raw_with_allocator`][into_raw_with_allocator].
///
/// # Safety
///
/// * Creating a `Arc<T>` from a pointer other than one returned from
/// [`Arc<U>::into_raw`][into_raw] or [`Arc<U>::into_raw_with_allocator`][into_raw_with_allocator]
/// is undefined behavior.
/// * If `U` is sized, it must have the same size and alignment as `T`. This
/// is trivially true if `U` is `T`.
/// * If `U` is unsized, its data pointer must have the same size and
/// alignment as `T`. This is trivially true if `Arc<U>` was constructed
/// through `Arc<T>` and then converted to `Arc<U>` through an [unsized
/// coercion].
///
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
///
/// The raw pointer must point to a block of memory allocated by the global allocator.
///
/// The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
/// * Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
/// * The raw pointer must point to a block of memory allocated by the global allocator.
/// * The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
///
/// This function is unsafe because improper use may lead to memory unsafety,
/// even if the returned `Arc<T>` is never accessed.
///
/// [into_raw]: Arc::into_raw
/// [into_raw_with_allocator]: Arc::into_raw_with_allocator
/// [transmute]: core::mem::transmute
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
///
@@ -1819,29 +1822,32 @@ pub fn as_ptr(this: &Self) -> *const T {
/// Constructs an `Arc<T, A>` from a raw pointer.
///
/// The raw pointer must have been previously returned by a call to [`Arc<U,
/// A>::into_raw`][into_raw] with the following requirements:
/// A>::into_raw`][into_raw] or [`Arc<U, A>::into_raw_with_allocator`][into_raw_with_allocator].
///
/// # Safety
///
/// * Creating a `Arc<T, A>` from a pointer other than one returned from
/// [`Arc<U, A>::into_raw`][into_raw] or [`Arc<U, A>::into_raw_with_allocator`][into_raw_with_allocator]
/// is undefined behavior.
/// * If `U` is sized, it must have the same size and alignment as `T`. This
/// is trivially true if `U` is `T`.
/// * If `U` is unsized, its data pointer must have the same size and
/// alignment as `T`. This is trivially true if `Arc<U>` was constructed
/// through `Arc<T>` and then converted to `Arc<U>` through an [unsized
/// alignment as `T`. This is trivially true if `Arc<U, A>` was constructed
/// through `Arc<T, A>` and then converted to `Arc<U, A>` through an [unsized
/// coercion].
///
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
///
/// The raw pointer must point to a block of memory allocated by `alloc`
///
/// The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
/// * Note that if `U` or `U`'s data pointer is not `T` but has the same size
/// and alignment, this is basically like transmuting references of
/// different types. See [`mem::transmute`][transmute] for more information
/// on what restrictions apply in this case.
/// * The raw pointer must point to a block of memory allocated by `alloc`
/// * The user of `from_raw` has to make sure a specific value of `T` is only
/// dropped once.
///
/// This function is unsafe because improper use may lead to memory unsafety,
/// even if the returned `Arc<T>` is never accessed.
///
/// [into_raw]: Arc::into_raw
/// [into_raw_with_allocator]: Arc::into_raw_with_allocator
/// [transmute]: core::mem::transmute
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
///