Computing raw pointers to fields

There have been discussions on raw pointers to fields in the past (e.g., "[Idea] Pointer to Field" and it's RFC). This thread is an attempt to collect some of the various discussions and ideas around getting a pointer to an object's field.

Right now, &raw const <place>/&raw mut <place> are being worked on (with a high probability of being stabilized someday, I think). It's a step forward, but it doesn't fully cover raw pointers to fields. Consider, for example:

struct Struct {
    field: f32,
}

let mut uninit_struct = core::mem::MaybeUninit::<Struct>::uninit();
let struct_ptr = uninit.as_mut_ptr();

There are a few ways to get a pointer to the field:

  1. Current syntax: unsafe { &mut (*struct_ptr).field as *mut _ }.
  2. Using the new &raw syntax: unsafe { &raw mut (*struct_ptr).field }.
  3. Using @Yato's RFC: struct_ptr.wrapping_project(Struct.field).

Questions:

  1. What's the validity status of unsafe { &raw mut (*struct_ptr).field }? I believe the validity of dereferencing an uninitialized pointer to obtain a pointer to a field is still undecided. cc @RalfJung
  2. Are there other proposals or alternatives?

I'm trying to collect and understand the various ways to obtain a pointer to struct_ptr's field (including stable, unstable, and proposed-but-not-accepted).

This seems to be the current state of affairs. My RFC will likely be closed/postponed after &raw mut hits nightly, and I transfer my WIP crate to use it. I think it would be best to try out generic fields as a crate before folding it into std because there is quite a lot of design space (esp. around pin). The Pointer to Field idea was more like an extension to Deref than anything else, making all pointer-like types have a very similar api.

In this case you could use unsafe { struct_ptr.project_unchecked(Struct.field) }

There is also this RFC which is sort-of orthogonal, but related

I am pretty sure that this is meant to be valid based on @RalfJung's comment here

... But &raw const (*base_ptr).field is allowed, ...

I think the deref is fine. This is in accordance with the reference.

But to be really sure, we should ask the lang team to FCP that given x: *const !, doing &raw const *x is okay. And more interestingly, so is x: *const (i32, !) in &raw const (*x).0. To get us started in that direction I opened a UCG issue.

1 Like