Description
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.