-
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
Are (non-free) generic constants guaranteed to be evaluated? #112090
Comments
It's unambiguously guaranteed that at a bare minimum, the code will panic before executing the #107503 et. al. is related but distinct, about defining when a monomorphization is "used." If this spelling is permitted to panic at runtime, it would be (will be) possible to place the constant instantiation in a my well established positionI've made my position clear w.r.t. monomorphization instantiation const evaluation errors; all constant evaluation required to fulfill statically instantiated monomorphizations should semantically be evaluated, and skipping nonpure evaluation should be considered incorrect. I would also accept changing it such that The current status that associated You can argue that |
To my knowledge, we guarantee that every constant mentioned syntactically within a function that executes at runtime, has been previously executed at compiletime. (This is certainly current compiler behavior, and we explicitly have code to make this happen, it's not just an accident of the current implementation.) I don't know if and where we document that guarantee, though. |
That's good to hear! A few questions:
@CAD97 if I'm reading your comment correctly, you're of the same opinion as @RalfJung? I quoted their comment because it contains language I wanted to respond to directly, but really I think I'm responding to both of your comments, which seem to agree with each other. |
Here's one way to think about it: imagine the const body was inlined, and ask whether that line of code is reachable by any possible runtime arguments. If it is, then the const body must be evaluated, and a const body that must be evaluated must be evaluated at compile time. I think we would like to strengthen this guarantee to something more syntactic, i.e. if there is a reference to a For your example, we get the following:
|
Okay, in that case I'm pretty sure I understand the current state of affairs.
Is this guaranteed by the reference? |
From https://doc.rust-lang.org/reference/const_eval.html#constant-expressions:
|
I specifically meant that even constants inside an
Yes. We actually evaluate consts for all functions that are monomorphized, but we don't have clear guarantees on what does or does not get monomorphized, as indicated by the issue you linked. However if a function actually executes at runtime then surely it has been monomorphized. (Crucially, the "that" above refers to the function containing the use of the
Hm, I guess either the @digama0 you are stating weaker rules than I am.
This is not correct. Put differently: |
Yes, I gave two versions of the rules that I called the "weak guarantee" and the "strong guarantee". My understanding is that the rule you are giving is what I called the strong guarantee, and the #107503 behavior lies somewhere in between.
Ah, thanks. I saw that there was some inconsistency in whether const code was getting evaluated but I wasn't sure what the exact description was, I didn't realize that out-lining via a |
Out-lining via Also I am still confused by this:
Your paragraph describes current behavior exactly and is not in contradiction with #107503. #107503 affects functions called from dead code, but not consts called from dead code in a live function. |
I suppose the unstated part of that sentence is that functions are also monomorphized when they are referenced in a function that is itself monomorphized, because we would like this "monomorphized by" relation to be transitive. So if a ODR-used function calls a function which has a const block, then the const block is monomorphized and hence evaluated. |
That part is the one which doesn't apply currently, due to #107503. I don't know what "ODR-used" is/means. |
might be referring to the "static const" section of https://en.wikipedia.org/wiki/One_Definition_Rule ? |
ODR-used is a technical definition from the C++ spec which basically means "transitively required by monomorphizations leading to some exported function or |
Past discussion of this topic: #67191. However, I couldn't find an FCP establishing an explicit T-lang guarantee for certain consts to be evaluated. |
Okay, sounds like it'd be worth documenting that guarantee somewhere. As a stopgap, is the following guaranteed to execute?
In the context of
|
If |
I'm confused; doesn't your reply here imply that |
If by "guaranteed" you mean t-lang FCP'd, then I don't think we have any guarantees here. ;) But this is just a procedural matter, I have no doubt that we will have (at least) the guarantee I mentioned. We just need someone to push this through the process. |
How about adding a test to the test suite? I bet lots of people are relying on this already, so it should be tested and guaranteed. |
I'm pretty sure we have such tests... |
Turns out we have a test in Miri but I couldn't find one in rustc. So here's one: #116444 |
Reference PR that should resolve this: rust-lang/reference#1497. |
New issue for the t-lang decision: #124971. |
Reposted from rust-lang/unsafe-code-guidelines#409 at the suggestion of @digama0
Thanks to this suggestion by @gootorov, we're considering doing something like the following in zerocopy:
The nightly reference guarantees that "free constants are always evaluated at compile time." However, that's not quite what we have here - we evaluate the constant
REF_TRANSMUTABLE_INTO
but assign it to a runtime variable (let _: () = ...
). If we replacedlet _
withconst _
, that would be a free constant, but it would never compile (even when we wanted it to) because a constant in a function body isn't allowed to reference types which are generic in that context.What I want to know is: Is this constant guaranteed to be evaluated so long as
transmute_ref_into
is used?The text was updated successfully, but these errors were encountered: