-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking issue for comparing raw pointers in constants #53020
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…,RalfJung,nagisa A way forward for pointer equality in const eval r? @varkor on the first commit and @RalfJung on the second commit cc rust-lang#53020
…,RalfJung,nagisa A way forward for pointer equality in const eval r? @varkor on the first commit and @RalfJung on the second commit cc rust-lang#53020
…,RalfJung,nagisa A way forward for pointer equality in const eval r? @varkor on the first commit and @RalfJung on the second commit cc rust-lang#53020
…,RalfJung,nagisa A way forward for pointer equality in const eval r? @varkor on the first commit and @RalfJung on the second commit cc rust-lang#53020
I came here to say yes. In general there's an ongoing issue with several APIs in const eval, where under const evaluation to assume there's no reason you might need to handle the case where the function fails to produce a meaningful result. Some examples of this are |
FWIW, the
|
Sort of, but this could have been done in the appropriate cases as As it is, it not only means that you cannot rely on the alignment occurring for non-performance cases, but you also can't rely on it happening for performance cases either. It's pretty much set up only for loops that are exactly "handle head", "handle body", "handle tail", which is the rough shape, but you often want more flexibility than is allowed by that assumption. This ends up being very frustrating when using the API, and I think its a pattern we shouldn't repeat. |
That is explicitly and exclusively the case this API was designed for. So IMO it would have been a mistake to make the API worse for that case, and expand its scope. Rather, we should have other APIs for the other usecases. (And we can still add them, if someone has good ideas for useful APIs! I don't feel like Anyway, that's water under the bridge. |
FWIW, the things I'm referring to are things like being able to rely on there being less than An example from the stdlib of this is https://github.com/rust-lang/rust/blob/master/library/core/src/str/count.rs#L60-L69, which still exists at runtime, and causes worse codegen. |
I agree on this point, although it makes it explicit that the |
I tried to use this just now in some code wanting to assert that some struct definition was correct at compile time. (It failed, but I writing it that way was probably expecting too much of const eval, and I was able to rewrite it without this). Anyway, initially my It occurs to me though, that I only noticed this because my code had While it might seem unlikely for someone to write code that does Use of an option would force handling the "don't know at compile time" case in some way (ideally unwrap) and avoid a case where the API is similar enough to a non-const API that it becomes easy to do make a mistake when translating from one to the other. |
We probably want to use a simpler type for the intrinsic (to make that easier to implement), but I am generally on-board with changing the type of the public functions here. |
The `<*const T>::guaranteed_*` methods now return an option for the unknown case cc rust-lang#53020 (comment) I chose `0` for "not equal" and `1` for "equal" and left `2` for the unknown case so backends can just forward to raw pointer equality and it works ✨ r? `@fee1-dead` or `@lcnr` cc `@rust-lang/wg-const-eval`
The `<*const T>::guaranteed_*` methods now return an option for the unknown case cc rust-lang/rust#53020 (comment) I chose `0` for "not equal" and `1` for "equal" and left `2` for the unknown case so backends can just forward to raw pointer equality and it works ✨ r? `@fee1-dead` or `@lcnr` cc `@rust-lang/wg-const-eval`
The `<*const T>::guaranteed_*` methods now return an option for the unknown case cc rust-lang/rust#53020 (comment) I chose `0` for "not equal" and `1` for "equal" and left `2` for the unknown case so backends can just forward to raw pointer equality and it works ✨ r? `@fee1-dead` or `@lcnr` cc `@rust-lang/wg-const-eval`
=== stdout === === stderr === error: pointers cannot be reliably compared during const eval --> /home/runner/work/glacier/glacier/ices/105047.rs:6:12 | 6 | if let RCZ = &raw const *&0 {} | ^^^ | = note: see issue #53020 <rust-lang/rust#53020> for more information note: erroneous constant used --> /home/runner/work/glacier/glacier/ices/105047.rs:6:30 | 6 | if let RCZ = &raw const *&0 {} | ^^ error: aborting due to previous error ==============
The `<*const T>::guaranteed_*` methods now return an option for the unknown case cc rust-lang/rust#53020 (comment) I chose `0` for "not equal" and `1` for "equal" and left `2` for the unknown case so backends can just forward to raw pointer equality and it works ✨ r? `@fee1-dead` or `@lcnr` cc `@rust-lang/wg-const-eval`
The `<*const T>::guaranteed_*` methods now return an option for the unknown case cc rust-lang/rust#53020 (comment) I chose `0` for "not equal" and `1` for "equal" and left `2` for the unknown case so backends can just forward to raw pointer equality and it works ✨ r? `@fee1-dead` or `@lcnr` cc `@rust-lang/wg-const-eval`
Comparing raw pointers in constants is forbidden (hard error) in const contexts.
The
const_compare_raw_pointers
feature gate enables theguaranteed_eq
andguaranteed_ne
methods on raw pointers. The root problem with pointer comparisons at compile time is that in many cases we can't know for sure whether two pointers are equal or inequal. While it's fairly obvious that a pointer to astatic
and a local variable won't be equal, we can't ever tell whether two local variables are equal (their memory may alias at runtime) or whether any pointer is equal to a specific integer. In order to make it obvious that there is a discrepancy between runtime and compile-time, theguaranteed_*
methods only returntrue
when we can be sure that two things are (in)equal. At runtime these methods just return the result of the actual pointer comparison.This permits
const fn
to do performance optimization tricks like the one done in slice comparison (if length is equal and pointer is equal, don't compare the slice contents, just return that it's equal).Since we aren't sure yet what the semantics of functions that return different values at runtime and at compile-time are, we'll keep this function unstable until we've had that discussion.
Unresolved questions
guaranteed_eq
return anOption<bool>
to allow the caller to know whether they got unclear results? What would the use-case for this be?The text was updated successfully, but these errors were encountered: