You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a tracking issue for the RFC "3027" (rust-lang/rfcs#3027).
The RFC does not have a feature gate.
About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
In #80243 we learned that there is at least some code (e.g. rodrimati1992/abi_stable_crates#46) that relies in non-trivial ways on const fn calls being promoted in a const/static initializer. We need to figure out how to move forward with such code. I see these options:
Live with the fact that promoteds in const/static initializers can fail even if they are not required for said initializer. This means no breaking change here, but it will require care in MIR optimizations, MIR printing, maybe more.
Make sure that all potentally-failing promoteds in const/static initializers are required to compute the value of the const. This will require some break change. There are different alternatives here:
Never promote anything that might fail -- this breaks some real code (no idea how much, it's only 2 crates in crater), but leads to a rather clean situation.
Only promote things that fail if they are in parts of the CFG that will definitely be evaluated -- that will however be rather surprising behavior, so maybe we want to do this only for old editions. In particular, a proper post-dominance analysis might be too expensive, so we might just check if the entire CFG is linear, or we only promote on the "linear head" of the CFG; in either case, adding a conditional somewhere in the code will stop promotion of things further down that code, which is rather odd.
Never promote anything that might fail -- this breaks some real code (no idea how much, it's only 2 crates in crater), but leads to a rather clean situation.
Can that code be made to compile with inline const blocks?
Live with the fact that promoteds in const/static initializers can fail even if they are not required for said initializer. This means no breaking change here, but it will require care in MIR optimizations, MIR printing, maybe more.
#85112 ensures that at least a normal build handles this correctly. @oli-obk any idea how to check other MIR consumers such as MIR printing for this?
MIR printing should just print the path to unevaluated constants and not eval them at all. The only other thing would be optimizations, but these aren't run for constants' bodies
If we end up deciding we are okay with promoting const fn calls in const/static bodies, we might then also accept other things like general array indexing or division -- we could accept basically everything that qualifies syntactically, i.e., anything that does not depend on surrounding variables. I am not sure what is the better choice -- this makes the rules even more inconsistent, but the rules already are wildly inconsistent to the extend that people do get confused by it (e.g., #85181).
What items from RFC 3027 remain to be implemented?
We talked about this in today's @rust-lang/lang meeting, and we know that const { ... } still needs further implementation, but we weren't sure if that was a blocker for this or if all the work specified by the RFC was complete.
Basically we still promote arbitrary function calls inside const/static initializers. We need to decide whether we want to
Live with this technical debt
Try to slowly phase it out in favor of const blocks (once those are stable)
This is a MIR building thing so it could potentially be done at an edition boundary. However, as long as any edition promotes arbitrary fn calls, MIR optimizations need to be careful and not overeagerly evaluate constants they find to determine their value. So the technical debt does not become any better by making this an edition thing. I am not sure whether doing this only for the sake of "rules of the latest edition are easier to explain" is worth it.
Activity
RalfJung commentedon Jan 2, 2021
In #80243 we learned that there is at least some code (e.g. rodrimati1992/abi_stable_crates#46) that relies in non-trivial ways on
const fncalls being promoted in aconst/staticinitializer. We need to figure out how to move forward with such code. I see these options:Aaron1011 commentedon Jan 2, 2021
Can that code be made to compile with inline
constblocks?RalfJung commentedon Jan 2, 2021
@Aaron1011 yes it can, but only once inline const blocks can use generics of the surrounding context.
[-]Tracking Issue for infallibe promotion[/-][+]Tracking Issue for infallible promotion[/+]RalfJung commentedon May 9, 2021
I think this is probably the best option:
#85112 ensures that at least a normal build handles this correctly. @oli-obk any idea how to check other MIR consumers such as MIR printing for this?
oli-obk commentedon May 9, 2021
MIR printing should just print the path to unevaluated constants and not eval them at all. The only other thing would be optimizations, but these aren't run for constants' bodies
RalfJung commentedon May 12, 2021
As in, it already does that, or it should be changed to do that?
oli-obk commentedon May 12, 2021
I believe it does that. At least I specifically remember seeing paths being printed for things that could have been evaluated.
RalfJung commentedon May 15, 2021
If we end up deciding we are okay with promoting
const fncalls inconst/staticbodies, we might then also accept other things like general array indexing or division -- we could accept basically everything that qualifies syntactically, i.e., anything that does not depend on surrounding variables. I am not sure what is the better choice -- this makes the rules even more inconsistent, but the rules already are wildly inconsistent to the extend that people do get confused by it (e.g., #85181).joshtriplett commentedon Jul 20, 2022
What items from RFC 3027 remain to be implemented?
We talked about this in today's @rust-lang/lang meeting, and we know that
const { ... }still needs further implementation, but we weren't sure if that was a blocker for this or if all the work specified by the RFC was complete.RalfJung commentedon Jul 20, 2022
@joshtriplett the main open question is what is listed as unresolved question in the issue:
Basically we still promote arbitrary function calls inside const/static initializers. We need to decide whether we want to
constblocks (once those are stable)This is a MIR building thing so it could potentially be done at an edition boundary. However, as long as any edition promotes arbitrary fn calls, MIR optimizations need to be careful and not overeagerly evaluate constants they find to determine their value. So the technical debt does not become any better by making this an edition thing. I am not sure whether doing this only for the sake of "rules of the latest edition are easier to explain" is worth it.
16 remaining items
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#122819 - RalfJung:fn-call-promotion-experimen…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
RalfJung commentedon Mar 21, 2024
Regarding the chance to entirely get rid of promotion of function calls -- currently, that breaks the build of cargo, due to this constant in
time:The
default()calls here are function calls which are being promoted.This could easily be fixed by using associated consts instead of functions. But who knows what we'd run into next...
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
Auto merge of rust-lang#121557 - RalfJung:const-fn-call-promotion, r=…
RalfJung commentedon Apr 24, 2024
#121557 landed. So we have finally achieved
Elysiumthe property that all potentially failing consts are captured by required_consts. :)I think we can consider the RFC to be fully implemented now. 🎉
I have opened #124328 to track cleaning up the "hacks" we had to add to get here.