-
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
Add a HIR pass to check consts for if
, loop
, etc.
#66170
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
cc @rust-lang/compiler I was hoping we would implement const-checking for arbitrary CFGs and never have to deal with a HIR check on constants again, but I guess I was wrong. |
This comment has been minimized.
This comment has been minimized.
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.
The checker code looks good aside from some nits and some thoughts for the future (cleanup tasks mostly unrelated to the PR but which I noticed along the way).
@@ -329,6 +329,11 @@ rustc_queries! { | |||
desc { |tcx| "checking for unstable API usage in {}", key.describe_as_module(tcx) } | |||
} | |||
|
|||
/// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`). | |||
query check_mod_const_bodies(key: DefId) -> () { |
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.
Aside: I noticed that the categorization in this module wrt. Other
, TypeChecking
, and friends is rather messy and there doesn't seem to be a lot of logic to it? -- Maybe another C-cleanup issue...? (cc @Zoxc & @nikomatsakis)
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.
Oh, this categorization was added as a very coarse grouping for profiling purposes IIRC, we can certainly clean things up here. cc @wesleywiser
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.
Cleanups wrt categorization are definitely appreciated. I did the initial pass ~1yr ago and I don't think they've changed substantially since that time. Feel free to assign me to any such cleanup PRs.
I wouldn't expend any energy on making #62272 work; it's not very useful in any case and was never intended to be allowed on stable other than as a side-effect of how the compiler is structured. The check as written in this PR is good. :) |
Okay, I fixed most of @Centril's suggestions, blessed the back-compat breakages, and added an explanation to them. Let me know if you're okay with the new error messages. This should pass CI now. I'd like people to weigh in on where to put this in the compilation pipeline; I think it should go alongside the MIR const-checker if possible. |
On my end, the code & diagnostics look good, so r=me on that aspect when you feel comfortable. |
This comment has been minimized.
This comment has been minimized.
ddc87f8
to
f539d6e
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
eede3d6
to
1fdd6bd
Compare
@@ -13,7 +11,6 @@ fn set_editor(_: Value) {} | |||
|
|||
fn main() { | |||
let settings_data = from_string(settings_dir); | |||
//~^ ERROR cannot move out of static item `settings_dir` [E0507] |
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.
It's unfortunate that this error no longer occurs. I believe it's simply because the compiler stops working before the move checker runs?
|
||
fn main() { | ||
[FOO; { let x; loop { x = 5; break; } x }]; | ||
[FOO; { let x; loop { x = 5; break; } x }]; //~ ERROR `loop` is not allowed in a `const` |
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.
How do we feel about the term const
for an array initializer? Is there a preexisting convention here? It's pretty easy to change.
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.
Maybe @estebank has thoughts?
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 would prefer us to be correct mentioning the array length is a const context, but this should be ok for now, we have plenty of other places where we are inconsistent about calling this out.
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.
Oh, also, I think const generic arguments are also anon_const
, so this isn't that easy. Probably the right way is to add an AnonConstKind
to AnonConst
in hir/mod.rs
. With that in mind, I'm inclined to fix this later :).
I've rebased to clean up the history a bit and (hopefully) blessed the remaining tests. I've left some comments where the new error messages aren't a clear improvement. This is still waiting for @rust-lang/compiler to weigh in on whether breaking #62272 is okay. It might need an FCP/crater run? Also, I would still like for someone to review the relative order of the |
1fdd6bd
to
469040b
Compare
This comment has been minimized.
This comment has been minimized.
469040b
to
05c4808
Compare
This comment has been minimized.
This comment has been minimized.
Control-flow expressions are not allowed inside a const context. | ||
|
||
At the moment, `if` and `match`, as well as the looping constructs `for`, | ||
`while`, and `loop`, are forbidden inside a `const`, `static`, or `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.
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'll do this in a follow-up PR since the bulk of this one is ready.
This part is unfortunately out of my expertise to mentor; I'll defer to folks on T-Compiler. |
This PR BREAKS CODE THAT WAS ACCEPTED ON STABLE. It's arguably a bug that this was accepted in the first place, but here we are. See rust-lang#62272 for more info.
The MIR const-checker errors for if/match/loop are now delay span bugs, so nothing will be emitted unless the HIR checker misses something.
16c674f
to
7552bd6
Compare
📌 Commit 7552bd6 has been approved by |
Add a HIR pass to check consts for `if`, `loop`, etc. Resolves #66125. This PR adds a HIR pass to check for high-level control flow constructs that are forbidden in a const-context. The MIR const-checker is unable to provide good spans for these since they are lowered to control flow primitives (e.g., `Goto` and `SwitchInt`), and these often don't map back to the underlying statement as a whole. This PR is intended only to improve diagnostics once `if` and `match` become commonplace in constants (behind a feature flag). The MIR const-checker will continue to operate unchanged, and will catch anything this check might miss. In this implementation, the HIR const-checking pass is run much earlier than the MIR one, so it will supersede any errors from the latter. I will need some mentoring if we wish to change this, since I'm not familiar with the diagnostics system. Moving this pass into the same phase as the MIR const-checker could also help keep backwards compatibility for items like `const _: () = loop { break; };`, which are currently (erroneously?) accepted by the MIR const-checker (see #62272). r? @Centril cc @eddyb (since they filed #62272)
☀️ Test successful - checks-azure |
…msg, r=estebank Link to tracking issue in HIR const-check error code description This is a follow up to rust-lang#66170 that addresses [this comment](rust-lang#66170 (comment)). As an aside, the only other error code whose description uses the phrase "tracking issue" is `E0202`. We may want to come up with standards around this, especially since error codes are now centralized and easier to keep track of (thanks @GuillaumeGomez). r? @estebank (since they +1'ed the comment)
…msg, r=estebank Link to tracking issue in HIR const-check error code description This is a follow up to rust-lang#66170 that addresses [this comment](rust-lang#66170 (comment)). As an aside, the only other error code whose description uses the phrase "tracking issue" is `E0202`. We may want to come up with standards around this, especially since error codes are now centralized and easier to keep track of (thanks @GuillaumeGomez). r? @estebank (since they +1'ed the comment)
…msg, r=estebank Link to tracking issue in HIR const-check error code description This is a follow up to rust-lang#66170 that addresses [this comment](rust-lang#66170 (comment)). As an aside, the only other error code whose description uses the phrase "tracking issue" is `E0202`. We may want to come up with standards around this, especially since error codes are now centralized and easier to keep track of (thanks @GuillaumeGomez). r? @estebank (since they +1'ed the comment)
…msg, r=estebank Link to tracking issue in HIR const-check error code description This is a follow up to rust-lang#66170 that addresses [this comment](rust-lang#66170 (comment)). As an aside, the only other error code whose description uses the phrase "tracking issue" is `E0202`. We may want to come up with standards around this, especially since error codes are now centralized and easier to keep track of (thanks @GuillaumeGomez). r? @estebank (since they +1'ed the comment)
Resolves #66125.
This PR adds a HIR pass to check for high-level control flow constructs that are forbidden in a const-context. The MIR const-checker is unable to provide good spans for these since they are lowered to control flow primitives (e.g.,
Goto
andSwitchInt
), and these often don't map back to the underlying statement as a whole. This PR is intended only to improve diagnostics onceif
andmatch
become commonplace in constants (behind a feature flag). The MIR const-checker will continue to operate unchanged, and will catch anything this check might miss.In this implementation, the HIR const-checking pass is run much earlier than the MIR one, so it will supersede any errors from the latter. I will need some mentoring if we wish to change this, since I'm not familiar with the diagnostics system. Moving this pass into the same phase as the MIR const-checker could also help keep backwards compatibility for items like
const _: () = loop { break; };
, which are currently (erroneously?) accepted by the MIR const-checker (see #62272).r? @Centril
cc @eddyb (since they filed #62272)