-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NonNull
should document that From<&T>
and friends preserve provenance
#116181
Comments
@rustbot claim |
In which sense do they do that? Functions that take references always generate a fresh aliasing tag for their arguments, so in that sense they decisively do not preserve provenance in Miri today. |
Cc @rust-lang/opsem |
I'm confused by this. The examples in the let a = [0; 5];
let ptr1: *const i32 = &a[1];
let ptr2: *const i32 = &a[3];
unsafe {
assert_eq!(ptr2.offset_from(ptr1), 2);
assert_eq!(ptr1.offset_from(ptr2), -2);
assert_eq!(ptr1.offset(2), ptr2);
assert_eq!(ptr2.offset(-2), ptr1);
}
My understanding is that the point of provenance is to be able to restrict operations like |
Ah, you seem to confuse "has the same provenance" with "derived from a pointer to the same object". We have not finalized what exactly the provenance of a pointer in Rust will be, but it will likely involve two components:
The first component stays the same on every operation you do with that pointer. It is literally impossible to change. It gets set when the pointer is created (i.e., when the memory is allocated and the initial pointer is returned -- or when an int2ptr cast happens) So it doesn't make a lot of sense to document this for each and every operation, IMO. |
Okay, I think I understand. I re-read the provenance docs in the
The provenance docs in the Does that match your understanding? |
Hm, no not quite. Zero-sized accesses do not require the pointer to have provenance, that's why they are allowed on But other than that, what you say is correct, but does not completely characterize provenance. (IOW, the conditions you list are necessary but not sufficient for a memory access to be allowed.) We deliberately are leaving the full characterization of provenance open. Provenance might restrict a pointer further, for example:
Also, I don't know what you mean by "all pointer operations". I am assuming you are referring to loads and stores here. There are other pointer operations, such as deref ( |
@rustbot release-assignment |
Okay, based on your comment, I'm updating from:
...to: Given
* I suppose you could also just argue that some operations can "remove" provenance from other points, so this is unnecessary to explicitly state. Is this both necessary and sufficient (ignoring non-provenance-related rules, of course)? Or am I still missing aspects? Based on this discussion, maybe a more appropriate promise would be that |
That sounds like a really complicated way to say: But it does sound equivalent to that, yes.
There's nothing different about NonNull vs regular raw pointers. Whether it is actually valid for lifetime The most sensible thing to say about |
Sounds good! Put up a PR: #130571 |
The implementations of
From<&T>
andFrom<&mut T>
forNonNull<T>
preserve pointer provenance. This should be documented as a guarantee so callers can rely on it.The text was updated successfully, but these errors were encountered: