Hi, I would like to ask your opinions on this alternative RFC #2582 (&raw
operator) proposal.
Summary
Allow accessing fields in raw pointers pointing to structs or unions. Such an operation would create a raw pointer.
Motivation
Rust doesn't provide a way to safely create a pointer to a field for uninitialized and packed types without going through reference indirection. This abstraction would also permit a safe way to implement offset_of
outside of the standard library.
Guide-level explanation
Using member access operator on raw pointer would create a raw pointer pointing a given field. This avoids reference indirection, avoiding the need to prove guarantees about alignment and dangling references.
struct Hello {
a: i32,
b: i64,
}
fn main() {
let hello = Hello { a: 1, b: 2 };
let ptr: *const Hello = &hello;
let b_ptr: *const i64 = ptr.b;
assert_eq!(unsafe { *b_ptr }, 2);
}
This can be used with packed structures.
use std::ptr;
#[repr(packed)]
struct Hello {
a: i32,
b: i64,
}
fn main() {
let hello = Hello { a: 1, b: 2 };
let ptr: *const Hello = &hello;
let b_ptr: *const i64 = ptr.b;
println!("{}", unsafe { ptr::read_unaligned(b_ptr) });
}
It's also possible to partially initialize uninitialized structures.
use std::mem::MaybeUninit;
#[derive(Debug)]
struct Hello {
a: i32,
b: i64,
}
fn main() {
let mut m: MaybeUninit<Hello> = MaybeUninit::uninit();
let mp = m.as_mut_ptr();
unsafe {
mp.a.write(1);
mp.b.write(2);
println!("{:?}", m.assume_init());
}
}
Reference-level explanation
https://doc.rust-lang.org/reference/expressions/field-expr.html
If a type of expression to the left is a raw pointer. this operation provides a raw pointer to the location of that field whose mutability depends on original pointer's mutability. This doesn't require unsafe
, even if the pointer points to an union.
Drawbacks
This introduces a special rule for member access when using raw pointers increasing the complexity of the language.
Rationale and alternatives
RFC #2582. I believe however this design is more powerful overall as well as it has a more intuitive syntax not introducing a new pseudo-keyword raw
.
Unresolved questions
Should this operator be possible to use for dangling/made-up pointers? Answering no here means unsafe
requirement, which is probably fine, as this feature is useful in unsafe code only.
Future possibilities
This pretty much conflicts with RFC #2582 by introducing another syntax to access packed fields. Likely only one of those RFCs should be stabilized.
Accessing enum fields. That said, I don't think that is particularly important when union
s can be used to simulate enum
s.