What is the situation on pointer provenance? There were a few threads a few weeks ago, and this is clearly something miri takes seriously: It will complain on e.g. converting a reference to the first field of a #[repr(C)]
struct to a reference of the full struct.
Miri example of repr(C) struct
#[repr(C)]
#[derive(Debug)]
struct Full {
a: A,
b: B,
}
#[repr(C)]
#[derive(Debug)]
struct A {
field: u32
}
#[repr(C)]
#[derive(Debug)]
struct B {
field: u32
}
fn convert(r: &A) -> &Full {
unsafe { &*(r as *const A as *const Full) }
}
fn main() {
let full = Full {
a: A { field: 10 },
b: B { field: 20 },
};
let a = &full.a;
println!("{:?}", convert(a));
}
Pick miri under tools in playground to see it fail. Are there any authoritative documents on this? I came across this, which says
The exact form of provenance in Rust is unclear. [...] In the following, we give some examples of what provenance could look like.
Considering miri takes it so seriously, it seems quite important to understand. Here's my current understanding:
- References always have exactly the provenance corresponding to the size of the referent.
- Raw pointers can have a larger provenance, e.g.
slice::as_mut_ptr
has provenance of the entire slice, not just the first element. - Converting a reference to a raw pointer gives the raw pointer the provenance of the reference.
- Raw pointers obtained from the allocator have provenance of the allocation.
So provenance is lost on conversion to reference. This is supposedly quite important for the soundness of IterMut
, which is implemented as a start and end raw pointer both with provenance of the entire slice, but the returned mutable references do not alias due to their provenance being disjoint.
Of course this raises a question: It seems like the raw pointers in IterMut
alias with the returned mutable reference? Is this ok merely because they are no longer used to access those parts of the slice? That appears to be a special interaction between aliasing and raw pointers.
But all of this is what I've gathered from random forum posts, and I'd like something more reliable. Can someone clarify what's going on? The nomicon doesn't appear to have anything to say about this.