FFI mutating raw pointer where immutable reference in scope, is this UB?

I think this is not a problem right now as it is not possible to send pointer to another thread unless you explicitly making a newtype that is Send.

This example have problem because it attempts to use the *mut extern pointer IN Rust (the expression &mut *pointer deferences the pointer).

What the original intention is treat *mut extern a completely opaque type: the only way you can use it is to sent it to FFI.

My thoughts

In theory, there is no way Rust can know whether the use of FFI functions will UB: there could be a bug in the FFI module, who knows?

So what the compiler can do for safe code and programmers should do for unsafe code, is to ensure the following condition (legal = not UB):

If the current program status is legal, before calling any FFI functions (including exit of the program), the program status should be legal at any point

This principle means we can only conclude the following in my example:

assuming the status before main is legal,

  • Before ffi_write_u8 it is still legal
  • If after ffi_write_u8 it is still legal (means all Rust visible variables including pointer remains the same, and pointer is still point to legal memory), it is still legal before ffi_read_u8 because the ref_pointer is still refer to pointer, a legal pointer.
  • If after ffi_read_u8 it is still legal (means integer is valid), the remaining program is legal

So in general, our safety conclusion can only base on the assumption that the FFI code is not UB.

In terms of mutability though, I think now we have three category of mutability:

  1. Exterior mutability, specified by the use of mut keyword
  2. Interior mutability, specified by using UnsafeCell directly or indirectly
  3. Foreign mutablity, specified by a never dereferenced raw pointer, and may sent to FFI functions

Problems left behind

  1. What language facility shall we have to specify a raw pointer should never be dereferenced?
    • This is harder than it looks
    let ref_pointer: &mut ! = &mut *(pointer as *mut !);
  • The above code is legal, but the whole point is to avoid such things for specific raw pointer types.
  1. Should this type also have mut and const variants? C pointers have const void * and void * variants so the difference do exists in FFI. But I am not sure what can the Rust compiler take advantage of them.

Finally I think the *mut extern grammar is great, but I just don't want to enable &*pointer or coerce to another type - we do not want Rust to touch the thing it points to. If the user do want things like that, they can always use *mut [u8;10] instead.