Skip to content

ACP: cast_init method for pointers #627

@clarfonthey

Description

@clarfonthey

Proposal

Problem statement

MaybeUninit<T> is required for references in order to maintain soundness, but no such restrictions exist for pointers, and *const MaybeUninit<T> is mostly just an unnecessary layer of abstraction. The goal is to make it easier to convert *const MaybeUninit<T> to *const T, especially due to the fact that <[MaybeUninit<T>]>::as_ptr returns it.

Motivating examples or use cases

Right now, the MaybeUninit::slice_as_ptr and MaybeUninit::slice_as_mut_ptr methods exist to do a direct conversion from &[MaybeUninit<T>] to *const T and &mut [MaybeUninit<T>] to *mut T, but these methods are clunky and it's not clear how to fix this.

As stated, since pointers don't have the same initialization requirements as methods, it can be very desirable to use pointer-based write methods instead of those for slices, especially due to the lack of initialization requirements. However, these methods will require the "initialized" pointers, not the MaybeUninit<T> ones, and it's nice to be able to have an easy way to perform this cast without requiring additional type ascriptions (cast::<T>()).

Additionally, this way of doing MaybeUninit<T> -> T pointer conversion is more flexible than an inherent slice-based method such as <[MaybeUninit<T>]>::as_init_ptr, and would avoid the potential variability between calling such an as_init_ptr method and as_ptr().cast_init().

Solution sketch

Essentially, add the following methods:

impl<T> *const MaybeUninit<T> {
    pub const fn cast_init(self) -> *const T { self.cast() }
}
impl<T> *mut MaybeUninit<T> {
    pub const fn cast_init(self) -> *mut T { self.cast() }
}

Alternatives

There are currently three alternates:

  1. Keep the MaybeUninit::slice_as_ptr and MaybeUninit::slice_as_mut_ptr methods, don't add these. This option is undesirable because this method requires the explicit function call syntax as well as importing MaybeUninit in code that may not otherwise need to do so.
  2. Replace the explicit functions with real methods on [MaybeUninit<T>] slices. This is still not preferred due to the fact that cast_init can work on pointers obtained in other ways too.
  3. Remove all these methods and don't add a replacement. This isn't great because cast::<T>() will require type ascriptions, but cast::<T>() isn't necessarily any worse than cast_init(), just a little less clear.

Links and related work

What happens now?

This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.

Possible responses

The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):

  • We think this problem seems worth solving, and the standard library might be the right place to solve it.
  • We think that this probably doesn't belong in the standard library.

Second, if there's a concrete solution:

  • We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
  • We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions