Need for -> operator for Unsafe Code Guidelines

There are subtly different requirements at work here. The code that spawned the issue was due to unergonomic access to pointer math for fields. Your code actually needs to read from the field inner to get the second pointer. And that should be a strong distinction, I think. Another reason why I dislike the current code patterns because it very much conflates the two issues.

&(*ptr).inner as *const _ // 'Just' pointer math

&(*(*ptr).inner).field) as *const _ // Reads from inner

With respect to code, the problem I see new syntax being most useful in solving would be

struct FooMe { inner: BarMe }
struct BarMe { field: u8 }

unsafe fn init_field(ptr: *const FooMe) -> *const u8 {
    ptr~inner~field // Bikeshedding but that's free as binary operator?
}

// Also helps and makes explicit your version:
unsafe fn init_through_field(ptr: *const Foo) -> *const u8 {
    (*ptr~inner)~field
}

And in the context of MaybeUnint I'm dreaming of a safe solution to grabbing a pointer to initialize fields.

fn init_field(uninit: &mut MaybeUninit<Foo>) {
    uninit.as_init()~inner~field.write(0);
}
1 Like

Note that there’s intent to make &(*ptr).inner as *const _ be something like &raw const (*ptr).inner (or maybe even ptr.inner), as it’s potentially very tricky to make &(*ptr).inner as *const _ guarantee that it doesn’t actually deref ptr and, as you’ve noted, it visually looks as if it does. When the conversion to pointer is later than an immediate cast (such as when done by a conversion), it’s even trickier a question.

See the raw reference operator RFC for more details.

It is rather unfortunate that it is very hard to tell, from such a raw pointer expression, whether memory is actually being accessed or not.

&raw does not help with that:

&const raw (*ptr).inner // 'Just' pointer math
&const raw (*(*ptr).inner).field) // Reads from inner

C-style -> would not help much either:

&const raw ptr->inner // 'Just' pointer math
&const raw ptr->inner->field // Reads from inner

For this, we'd really need a dedicated "offset" operator.

6 Likes

A minimalistic, maybe stupid, idea for syntax that could provide pointer offset but still leverage . for structural fields without ambiguity:

&.ptr.inner.field

Justification: A pointer result without involving & in the expression may be confusing given precendence set by the current language. However, if the inner expression can stand alone as with other place borrow expressions then the confusing part is that no access to the place happens. Thus combine both aspects and also hint to . operating on the pointer type.

How is this hard to tell? Isn't this, like: given ptr: *const *const Pointee distinguishing &raw *ptr from &raw **ptr ?

Given the arrow notation, doesn't the leftmost &[] raw "cancel" the rightmost ->, a la C ?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.