-
Notifications
You must be signed in to change notification settings - Fork 13.5k
loop_match
: suggest extracting to a const
item
#143585
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
base: master
Are you sure you want to change the base?
loop_match
: suggest extracting to a const
item
#143585
Conversation
Sorry, I won't be able to review this. |
38091b2
to
aafc04c
Compare
help: try wrapping the expression in a `const` block | ||
| | ||
LL | break 'blk const { const_fn() }; | ||
| +++++++ + |
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.
As additional context, #143310 shows that this suggestion doesn't work (but it should). We get
https://godbolt.org/z/zvs9ePzdj
error[E0391]: cycle detected when building MIR for `break_on_constant_evalution`
--> <source>:20:32
|
20 | break 'blk const{ const_fn() };
| ^^^^^^^^^^^^^^^^^^^
|
note: ...which requires evaluating type-level constant...
--> <source>:20:37
|
20 | break 'blk const{ const_fn() };
| ^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `break_on_constant_evalution::{constant#0}`...
--> <source>:20:37
|
20 | break 'blk const{ const_fn() };
| ^^^^^^^^^^^^^^
note: ...which requires caching mir of `break_on_constant_evalution::{constant#0}` for CTFE...
--> <source>:20:37
|
20 | break 'blk const{ const_fn() };
| ^^^^^^^^^^^^^^
note: ...which requires elaborating drops for `break_on_constant_evalution::{constant#0}`...
And I'm not sure why. We must be evaluating the constant in some sort of unexpected way, but I really don't know enough about const eval to troubleshoot it.
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.
const blocks are nested within their parent and borrowchecked together with them, so in order to drop elaborate the constant we need to borrowck the parent, and that depends on MIR building of the parent again (which is when you're evaluating the const). To avoid this you need to put the const into a separate item, not a const block. This means you lose access to generic params, but that's probably a good thing similar to how const blocks in patterns being affected by generic params is fishy
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.
Right, but what confuses me is why the example does work when I comment out the loop-match attributes, like here https://godbolt.org/z/66q98PeW9.
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.
Why is that surprising? If you don't use the attributes, then your code doesn't run, so it can't ICE.
It is fundamentally not possible to evaluate constants during MIR building. The constant could be generic, and MIR building happens pre-monomorphization, so the value of generics is not known yet. For the same reason, you cannot use constants that use generic in patterns.
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.
So this has to enforce the same restrictions as patterns: only named constants without any generics in their path. It shouldn't ICE, of course. But unfortunately const blocks do not work.
After all, the entire point if this construct is to hard-code where this jumps to; if that could depend on generics, then it couldn't be hard-coded into the MIR.
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.
Hmm, you mean that loop-match
evaluates the const { ... }
too early? It must evaluate it at compile-time at some point right, so whether the code runs doesn't seem relevant. Also this const { ... }
block doesn´t use generics in practice so I think that added to my confusion (but it's probably hard to figure that out at that point).
Anyway, that means we should suggest using a const
item, not a const
expression.
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.
Hmm, you mean that loop-match evaluates the const { ... } too early?
Yes. In general, it can only be evaluated during monomorphization.
It must evaluate it at compile-time at some point right,
Sure, but there's many different stages of compile-time and it makes a big difference when (i.e., in which stage) code runs. In particular, there's the key distinction of "are generics still present or have they been monomorphized away already".
So, this is very relevant. It seems you are fundamentally confused about how generic functions work in rustc; please let's take any further questions you may have here to Zulip.
this const { ... } block doesn´t use generics
Yeah, for this const block the ICE comes from the borrow checker as Oli explained.
But we also don't actually detect whether a const block needs some generic or not, we just give all the surrounding generics to const blocks. Surely it would be very confusing if const { ... }
worked in loop_match but only in non-generic functions.
I missed this problem with generics when I wrote my comment in #143310, sorry for that.
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.
I just hadn't considered generics given that the concrete example didn't have them. But it makes sense that they must be taken into account now. Thanks for the background!
loop_match
: suggest wrapping in a const
blockloop_match
: suggest extracting to a const
item
aafc04c
to
37706c5
Compare
Allright, the error now suggests to extract to a |
if the expression cannot be evaluated in a straightforward way
37706c5
to
069f5cb
Compare
tracking issue: #132306
fixes #143310