Skip to content
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

Enable loop and while in constants behind a feature flag #67216

Merged
merged 19 commits into from
Dec 15, 2019

Conversation

ecstatic-morse
Copy link
Contributor

@ecstatic-morse ecstatic-morse commented Dec 11, 2019

This PR is an initial implementation of #52000. It adds a const_loop feature gate, which allows while and loop expressions through both HIR and MIR const-checkers if enabled. for expressions remain forbidden by the HIR const-checker, since they desugar to a call to IntoIterator::into_iter, which will be rejected anyways.

while loops also require #![feature(const_if_match)], since they have a conditional built into them. The diagnostics from the HIR const checker will suggest this to the user.

r? @oli-obk
cc @rust-lang/wg-const-eval

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 11, 2019
@ecstatic-morse
Copy link
Contributor Author

ecstatic-morse commented Dec 11, 2019

cc #66946. This needn't be blocked on my changes to the infinite loop detector or vice versa, but having loop will make invoking the detector a lot easier. It's possible we want to add a #![rustc_const_eval_iteration_limit] attribute before this PR lands that could, e.g., be set to -1 to disable the loop detector entirely (see #67217).

src/librustc_passes/check_const.rs Show resolved Hide resolved
src/librustc_feature/active.rs Outdated Show resolved Hide resolved
src/librustc_passes/check_const.rs Outdated Show resolved Hide resolved
src/librustc_passes/check_const.rs Show resolved Hide resolved
src/test/ui/consts/control-flow/loop.rs Outdated Show resolved Hide resolved
@Centril Centril self-assigned this Dec 11, 2019
@Centril
Copy link
Contributor

Centril commented Dec 11, 2019

cc #66946. This needn't be blocked on my changes to the infinite loop detector or vice versa, but having loop will make invoking the detector a lot easier. It's possible we want to add a #![rustc_const_eval_iteration_limit] attribute before this PR lands that could, e.g., be set to -1 to disable the loop detector entirely (see #67217).

These seem independent to me and I would prefer landing this PR before beta branches so that we can get this into the new bootstrap compiler.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@oli-obk
Copy link
Contributor

oli-obk commented Dec 11, 2019

All lgtm, I'd just like @Centril to sign off on the fact that both control flow and loops can be used on stable const fn (only in libstd) without any additional annotation

@rust-highfive

This comment has been minimized.

@bors

This comment has been minimized.

ecstatic-morse and others added 9 commits December 13, 2019 10:39
Conditionals and loops now have unstable features, and `feature_err` has
its own error code. I think that `feature_err` should take an error code
as a parameter, but don't have the energy to make this change throughout
the codebase. Also, the error code system may be torn out entirely.
Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
@oli-obk
Copy link
Contributor

oli-obk commented Dec 13, 2019

@bors r+

@bors
Copy link
Contributor

bors commented Dec 13, 2019

📌 Commit faa52d1 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 13, 2019
Centril added a commit to Centril/rust that referenced this pull request Dec 14, 2019
Enable `loop` and `while` in constants behind a feature flag

This PR is an initial implementation of rust-lang#52000. It adds a `const_loop` feature gate, which allows `while` and `loop` expressions through both HIR and MIR const-checkers if enabled. `for` expressions remain forbidden by the HIR const-checker, since they desugar to a call to `IntoIterator::into_iter`, which will be rejected anyways.

`while` loops also require [`#![feature(const_if_match)]`](rust-lang#66507), since they have a conditional built into them. The diagnostics from the HIR const checker will suggest this to the user.

r? @oli-obk
cc @rust-lang/wg-const-eval
bors added a commit that referenced this pull request Dec 14, 2019
Rollup of 5 pull requests

Successful merges:

 - #67151 (doc comments: Less attribute mimicking)
 - #67216 (Enable `loop` and `while` in constants behind a feature flag)
 - #67255 (Remove i686-unknown-dragonfly target)
 - #67267 (Fix signature of `__wasilibc_find_relpath`)
 - #67282 (Fix example code of OpenOptions::open)

Failed merges:

r? @ghost
@bors
Copy link
Contributor

bors commented Dec 15, 2019

⌛ Testing commit faa52d1 with merge fc6b5d6...

bors added a commit that referenced this pull request Dec 15, 2019
Enable `loop` and `while` in constants behind a feature flag

This PR is an initial implementation of #52000. It adds a `const_loop` feature gate, which allows `while` and `loop` expressions through both HIR and MIR const-checkers if enabled. `for` expressions remain forbidden by the HIR const-checker, since they desugar to a call to `IntoIterator::into_iter`, which will be rejected anyways.

`while` loops also require [`#![feature(const_if_match)]`](#66507), since they have a conditional built into them. The diagnostics from the HIR const checker will suggest this to the user.

r? @oli-obk
cc @rust-lang/wg-const-eval
@bors
Copy link
Contributor

bors commented Dec 15, 2019

☀️ Test successful - checks-azure
Approved by: oli-obk
Pushing fc6b5d6 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Dec 15, 2019
@bors bors merged commit faa52d1 into rust-lang:master Dec 15, 2019
@@ -390,8 +390,12 @@ fn check_terminator(
cleanup: _,
} => check_operand(tcx, cond, span, def_id, body),

| TerminatorKind::FalseUnwind { .. }
if feature_allowed(tcx, def_id, sym::const_loop)
=> Ok(()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems very fragile. FalseUnwind is supposed to be ignored (unless you care about unwind paths).

What this code should be doing is a CFG cyclicity check.

Copy link
Contributor Author

@ecstatic-morse ecstatic-morse Jan 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one in check_consts that will run even if #![feature(const_fn)] is specified. I hope we can lose that feature gate in favor of fine-grained ones in the future, as well as merge check_consts and qualify_min_const_fn.

Copy link
Member

@eddyb eddyb Jan 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do both run? That makes me happier, I guess, but then the FalseUnwind check here is not needed at all, is it?

Copy link
Contributor Author

@ecstatic-morse ecstatic-morse Jan 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check_consts validation is always run. qualify_min_const_fn is run when #![feature(const_fn)] is not specified. My opinion is that this pass should be removed along with #![feature(const_fn)] and any check that isn't already in check_consts given its own feature gate along with an entry in check_consts/ops.rs. I don't wanna spend political capital to spearhead this, however.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qualify_min_const_fn was added as a hack back when the normal const-checking pass was such a mess that nobody was confident in its ability to rule out all bad code. It was always meant to be temporary.

So, assuming const-check these days is well-structured enough that everyone is confident in its ability to do what it is supposed to do, I don't think you'll need to spend any political capital to get rid of it. Quite the contrary, at least I personally would be delighted to see it go. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we could wait with removing qualify_min_const_fn. Not necessarily because the new const checker is messy, but because I don't understand the new code (which is based on data-flow) nearly as well as the old code. And as the lang team point-person for the const things, I would like to understand the thing that checks for stability wrt. const. So I'd appreciate if we don't do it right now and allow me some time to study the new stuff. (Also, is there an urgency to this?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no urgency, there are some preliminary things that can be done like eliminating the const_fn feature gate

Copy link
Member

@eddyb eddyb Jan 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just make the handling of FalseUnwind consistent, for now.
It's not, and should not be mistaken for, a loop.

As the name says, it's a "false" (or "phantom") unwind edge. It's for situations where analyses which care about unwinding / cleanup blocks need to be conservative and assume unwinding can happen "out of the blue".

Everything else in const-checking ignores unwind edges (e.g. from calls) and associated cleanup blocks, because we completely bypass unwinding at compile-time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #62274 for precedent.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also looks like FalseEdges is also mishandled?

@ecstatic-morse ecstatic-morse deleted the const-loop branch October 6, 2020 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants