-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
offset_from: do not require pointers to be inbounds #112712
Conversation
r? @b-naber (rustbot has picked a reviewer for you, use r? to override) |
The Miri subtree was changed cc @rust-lang/miri Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri |
The job Click to see the possible cause of the failure (guessed by this bot)
|
How does this affect |
It is affected the same way, so the docs did not need to change.
|
@RalfJung it's not quite clear to me how I'm expected to be able to use this feature correctly in a const context. If I offset a pointer to outside its allocation, is it ever possible for me to know that such an operation won't overflow the address space? That does happen to be the case right now because all const allocations are at the beginning of the address space, but I don't think that's stable. Unrelated: Does having the "same allocations" restriction as a safety requirement make sense? It seems like we could 1. drop this requirement outside of const contexts, and 2. promise to throw an error and halt compilation if this requirement is violated in a const context. That seems like a much more user friendly version of things than UB |
Yeah I realized what I really want is a wrapping_offset_from that still requires "based on same alloc" but makes no overflow restrictions.
Regarding the second point, as of now we that would be an option though we don't have precedent for such an operation. However, the "based on same alloc" is actually useful for optimizations; it means this operation does not "escape" the provenance (in an alias analysis sense, not an ptr2int semantics sense).
|
I realize I didn't say it before, but I should clarify: Even with my two above points (which I do think should be considered) this PR doesn't make things worse and I'm in support regardless.
I see the point in theory, but I can't actually think of an example where it's useful. Might be worth taking to a separate Zulip thread though? |
@@ -644,6 +642,12 @@ impl<T: ?Sized> *const T { | |||
/// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on | |||
/// such large allocations either.) | |||
/// | |||
/// The requirement for pointers to be derived from the same allocated object is primarily | |||
/// equired for `const`-compatibility: at compile-time, pointers into *different* allocated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// equired for `const`-compatibility: at compile-time, pointers into *different* allocated | |
/// required for `const`-compatibility: at compile-time, pointers into *different* allocated |
😄
I tend to disagree. If we add
To maintain that symmetry we should drop the |
This PR is superseded by #112837. |
In
offset_from
, we currently require both pointers to be in-bounds of the same allocation.There's not really any good motivation for this requirement: all codegen backends implement this intrinsic by casting to integers and doing the subtraction there, and const-eval (the original motivation for having this function in the first place) is fine as long as both pointers are derived from the same allocation, but doesn't care if they are in-bounds.
This restriction also causes problems, as noted in #92512. We allow CTFE to move pointers out-of-bounds with
wrapping_offset
, but it is currently impossible to determine how far they have been moved, asoffset_from
is the only "pointer subtraction" operation available inconst
and it has this restriction on things being in-bounds.Hence I propose we remove this restriction. @rust-lang/opsem what do you think? (For FCP we'll probably want to add T-lang since this is stable.)
The one interesting question this open is how to interpret the requirement about not wrapping the edge of the address space in CTFE, where we don't know where that edge is. Currently we basically pretend that the edge is at the beginning of the allocation, so a pointer to 4 bytes before that beginning is considered to "wrap" when used with a pointer to 4 bytes after that beginning.
The Miri implementation also needs some work for wildcard pointers (as returned by int2ptr casts). But I figured I'd see if we even want this change before implementing all that.