Skip to content

Confusing wording of Vec::from_raw_parts pointer allocation requirement #98780

Closed

Description

The Alternatives section of the documentation for core::mem::transmute has this to say about a better way to turn a Vec<&X> into a Vec<Option<&X>>:

// This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the
// data layout. Instead of literally calling `transmute`, we perform a pointer cast, but
// in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`),
// this has all the same caveats. Besides the information provided above, also consult the
// [`from_raw_parts`] documentation.
let v_from_raw = unsafe {
    // Ensure the original vector is not dropped.
    let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
    Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
                        v_clone.len(),
                        v_clone.capacity())
};

The documentation for Vec<T>::from_raw_parts has this to say about where you can get the pointer from:

ptr needs to have been previously allocated via String/Vec<T> (at least, it’s highly likely to be incorrect if it wasn’t).

A strict reading, if I understand correctly, says that these two statements are contradictory. The transmute documentation says that it is safe to create a Vec<&i32> and then use from_raw_parts to create a Vec<Option<&i32>> out of its pointer. But the Vec documentation says that, when creating a Vec<T>, ptr must have previously been allocated via precisely and only Vec<T>, not Vec<U> for some other type U—not even if U happens to be transmutable from T, not even if T and U are ABI-compatible, not only if T is a repr(transparent) wrapper around U, but only T itself.

I suspect it was meant to say it must have previously been allocated by Vec, not Vec<T>; after all, if it could only have been allocated by Vec<T> in the first place, the next bullet point would be redundant (because obviously T has the same alignment as T).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-docsArea: documentation for any part of the project, including the compiler, standard library, and toolsC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions