rust-lang / unsafe-code-guidelines

Forum for discussion about what unsafe code can and can't do
https://rust-lang.github.io/unsafe-code-guidelines
Apache License 2.0
670 stars 58 forks source link

Can shared references and raw pointers concurrently access a memory region? #463

Open joshlf opened 1 year ago

joshlf commented 1 year ago

The ptr module docs say:

The result of casting a reference to a pointer is valid for as long as the underlying object is live and no reference (just raw pointers) is used to access the same memory. That is, reference and pointer accesses cannot be interleaved.

This seems to imply that accessing a *const T while a &T is live is illegal, which is surprisingly restrictive. The following code seems intuitively fine, and is accepted by Miri, but seems to violate this rule:

fn main() {
    let x = 0usize;
    let x_ref = &x;
    let x_copy = unsafe { core::ptr::read(&x as *const usize) };
    println!("{x}, {x_ref}, {x_copy}");
}

Am I misinterpreting this text? Is this intended to be unsound and Miri just needs to be taught to catch it? Should the text be relaxed?

RalfJung commented 1 year ago

Yeah that text is super restrictive. Note that the entire set of rules here starts out saying

The precise rules for validity are not determined yet. The guarantees that are provided at this point are very minimal:

We have a huge grey area of code accepted by Stacked Borrows but not guaranteed to be accepted by the eventual final memory model.

The code in your example is definitely intended to be allowed.