[Pre-RFC] `field_projection`

You would also want to support field projections for raw pointers *const T/*mut T. More importantly, we should be able to field-project *(const/mut) MaybeUninit<T> to *(const/mut) MaybeUninit<Field>, and similarly for UnsafeCell, because in unsafe code you would often deal with pointers, and would want to avoid giving at any moment any pointer validity/aliasing guarantees.

This isn't currently possible to do in end-user code without transmutes and dealing with offsets of fields. There is currently an RFC for offset_of! macro, which would give you field offsets, including #[repr(Rust)] types. Personally I'm not happy with that addition. It would be nice if there was some way to get the benefits of field offsets without directly exposing them to the users.


Some way to implement field projections is highly desirable, but I wouldn't want it to be a compiler built-in. There are way too many possible types to implement this feature in an ad-hoc way, it's not just a matter of a couple new lang items. This functionality is also highly desirable for user smart pointers.

Adding new methods to those types is relatively easy, but that would be highly unsafe, since there is no way to verify the offsets of fields (or pointers to fields) provided to the methods.

Derive macros would also be a neat solution, but that would mean that projections would work only if the author of the inner type has bothered to provide all required derives. Again, it seems infeasible to add 20 derive macros to each struct, and a catch-all derive macro would not provide the level of control generally expected of libcore derive macros. There is also an issue that some of the types live in core, while some require alloc or std. That would incur the same fragmentation for the derive macros. Finally, the macro-based approach isn't composable: you have derived Option<&T> and &MaybeUninit<T>, but have you derived Option<&MaybeUninit<T>>? This sounds like a frustrating and unexpected limitation.

I would expect so. You can map *mut Union to *mut Variant via offset_of!, why wouldn't it be possible for smart pointers?


Crazy thought: what if we had first-class place expressions in the language?

To avoid derailing this thread with pie-in-the-sky proposals, I have opened a separate topic.

5 Likes