Skip to content

Add "as raw pointer" methods to Box #355

Closed
@RalfJung

Description

@RalfJung

Proposal

Problem statement

When working with raw pointers, it can be necessary to obtain raw pointers to the contents of a container in a way that multiple such pointers can alias with each other arbitrarily. For Vec, we have Vec::as_mut_ptr for that purpose, and that aliasing model interaction is even documented nowadays. However, for Box, we have no such method. One has to instead write addr_of_mut!(*bx), which works because Box is a primitive and this does not go through DerefMut. (DerefMut would be creating a reference and thus defeat the aliasing point of this.)

Motivating examples or use cases

Here's an example of code that's wrong:

use std::ptr;

fn test(mut x: Box<[u8]>) { unsafe {
    //let mut x: Vec<u8> = x.into(); // adding this line makes it well-defined
    let ptr1 = x[0..10].as_ptr();
    let ptr2 = x.as_mut_ptr().add(5); // this was meant not to invalidate `ptr1`...
    ptr::copy(ptr1, ptr2, 10);
} }

fn main() {
    test(Box::new([0; 128]));
}

This came about in rustc itself due to a refactor that replaced Vec by Box.

Solution sketch

I'm not sure how to avoid the refactoring issue, since Box can't really have self methods, so as_mut_ptr on a Box<[T]> will always call the slice method and thus create an intermediate reference. But we could at least provide methods that do the right thing and are more discoverable than the addr_of_mut! trick:

impl<T> Box<T> {
  fn as_ptr(this: &Box<T>) -> *const T { addr_of!(**this) }
  fn as_mut_ptr(this: &mut Box<T>) -> *mut T { addr_of_mut!(**this) }
}

This would also complement the existing into_raw.

Alternatives

We could do nothing and instead just document the addr_of_mut! pattern somewhere in the Box type docs.

Links and related work

Vec has as_ptr/as_mut_ptr with aliasing model guarantees.

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

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)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