Skip to content

There should be a way to unwrap MaybeUninits without moving them #61011

Open
@Manishearth

Description

@Manishearth

MaybeUninit has an API where you construct a MaybeUninit<T>, can operate on it via raw pointer methods, and then can call assume_init() to move the inner value out. It also has methods that let you assume that it is initialized and obtain safe Rust references.

This is great for temporary initialization on the stack, but this doesn't work so well for the heap. What if you need to gradually initialize Vec<T> or Arc<T> heap values? This ends up leaving a carcass of a MaybeUninit in the type forever, basically infecting the type with an unsafe abstraction from the time of its initialization.

One solution here is to make sure MaybeUninit and ManuallyDrop have a repr of T (basically, repr(transparent), except we haven't defined that for unions) so that you can always transmute &MaybeUninit<T> to &T, or Arc<MaybeUninit<T>> into Arc<T>.

The fact that MaybeUninit has methods specifically for doing this kind of thing with slices seems to point to the need for this ability to be generalized.

Either way we should have clear documentation for using MaybeUninit with values not on your stack (on the heap, or passed in as a reference). Ideally we allow you to transmute it in such cases (and have examples doing this), but if we can't, we should still document that you shouldn't use it that way. (I think that this choice would preclude a lot of legitimate and necessary use cases, especially in FFI)

cc @eddyb @RalfJung

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions