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 if and match in constants behind a feature flag #66507

Merged
merged 14 commits into from
Nov 23, 2019

Conversation

ecstatic-morse
Copy link
Contributor

@ecstatic-morse ecstatic-morse commented Nov 18, 2019

This PR is an initial implementation of #49146. It introduces a const_if_match feature flag and does the following if it is enabled:

  • Allows Downcast projections, SwitchInt terminators and FakeReads for matched places through the MIR const-checker.
  • Allows if and match expressions through the HIR const-checker.
  • Stops converting && to & and || to | in const and static items.

As a result, the following operations are now allowed in a const context behind the feature flag:

  • if and match
  • short circuiting logic operators (&& and ||)
  • the assert and debug_assert macros (if the const_panic feature flag is also enabled)

However, the following operations remain forbidden:

This PR is possible now that we use dataflow for const qualification (see #64470 and #66385).

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

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 18, 2019
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
2019-11-18T05:47:26.6871374Z ##[command]git remote add origin https://github.com/rust-lang/rust
2019-11-18T05:47:27.6538045Z ##[command]git config gc.auto 0
2019-11-18T05:47:27.6543728Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2019-11-18T05:47:27.6548617Z ##[command]git config --get-all http.proxy
2019-11-18T05:47:27.6553947Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/66507/merge:refs/remotes/pull/66507/merge
---
2019-11-18T06:43:45.2183360Z .................................................................................................... 1600/9264
2019-11-18T06:43:51.0550431Z .................................................................................................... 1700/9264
2019-11-18T06:44:02.7897276Z .....................i.............................................................................. 1800/9264
2019-11-18T06:44:09.5391576Z .................................................................................................... 1900/9264
2019-11-18T06:44:24.0259743Z ......iiiii......................................................................................... 2000/9264
2019-11-18T06:44:33.1164149Z .................................................................................................... 2200/9264
2019-11-18T06:44:35.6999536Z .................................................................................................... 2300/9264
2019-11-18T06:44:41.4417312Z .................................................................................................... 2400/9264
2019-11-18T06:45:02.1587562Z .................................................................................................... 2500/9264
---
2019-11-18T06:47:40.8641421Z ......i...............i............................................................................. 4800/9264
2019-11-18T06:47:50.5436251Z .................................................................................................... 4900/9264
2019-11-18T06:47:55.7457985Z .................................................................................................... 5000/9264
2019-11-18T06:48:05.1570413Z .................................................................................................... 5100/9264
2019-11-18T06:48:10.6135206Z ..........ii.ii...........i......................................................................... 5200/9264
2019-11-18T06:48:20.0019737Z .................................................................................................... 5400/9264
2019-11-18T06:48:30.3299288Z ............................................................................................i....... 5500/9264
2019-11-18T06:48:38.2566171Z .................................................................................................... 5600/9264
2019-11-18T06:48:43.2933844Z .................................................................................................... 5700/9264
2019-11-18T06:48:43.2933844Z .................................................................................................... 5700/9264
2019-11-18T06:48:53.0268149Z ..............................................................................ii...i..ii...........i 5800/9264
2019-11-18T06:49:15.0265544Z .................................................................................................... 6000/9264
2019-11-18T06:49:22.8468137Z .................................................................................................... 6100/9264
2019-11-18T06:49:28.6764077Z .................................................................................................i.. 6200/9264
2019-11-18T06:49:41.6467919Z ii.................................................................................................. 6300/9264
---
2019-11-18T06:55:06.7888974Z  finished in 5.541
2019-11-18T06:55:06.8065976Z Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-18T06:55:06.9790109Z 
2019-11-18T06:55:06.9790915Z running 156 tests
2019-11-18T06:55:09.8159756Z iiii....iii......iii..iiii...i.............................i..i..................i....i...........ii 100/156
2019-11-18T06:55:11.6503670Z .i.i..iiii..............i.........iii.i.........ii......
2019-11-18T06:55:11.6506302Z 
2019-11-18T06:55:11.6507210Z  finished in 4.843
2019-11-18T06:55:11.6684502Z Check compiletest suite=codegen-units mode=codegen-units (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-18T06:55:11.8243847Z 
---
2019-11-18T06:55:13.7298317Z  finished in 2.061
2019-11-18T06:55:13.7469987Z Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-18T06:55:13.9014254Z 
2019-11-18T06:55:13.9014497Z running 9 tests
2019-11-18T06:55:13.9015222Z iiiiiiiii
2019-11-18T06:55:13.9015578Z 
2019-11-18T06:55:13.9015622Z  finished in 0.153
2019-11-18T06:55:13.9208308Z Check compiletest suite=incremental mode=incremental (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2019-11-18T06:55:14.0943048Z 
2019-11-18T06:55:14.0943048Z 
2019-11-18T06:55:14.0943276Z running 109 tests
2019-11-18T06:55:31.2939135Z .................................................................................................... 100/109
2019-11-18T06:55:32.5675452Z .......F.
2019-11-18T06:55:32.5677175Z failures:
2019-11-18T06:55:32.5678194Z 
2019-11-18T06:55:32.5679767Z ---- [incremental] incremental/warnings-reemitted.rs stdout ----
2019-11-18T06:55:32.5681153Z thread '[incremental] incremental/warnings-reemitted.rs' panicked at 'Error annotations must look like `//[X]~` in incremental tests', src/libcore/option.rs:1185:5
2019-11-18T06:55:32.5682614Z 
2019-11-18T06:55:32.5682887Z 
2019-11-18T06:55:32.5683674Z failures:
2019-11-18T06:55:32.5685025Z     [incremental] incremental/warnings-reemitted.rs
2019-11-18T06:55:32.5685025Z     [incremental] incremental/warnings-reemitted.rs
2019-11-18T06:55:32.5685995Z 
2019-11-18T06:55:32.5687433Z test result: FAILED. 108 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
2019-11-18T06:55:32.5688546Z 
2019-11-18T06:55:32.5693876Z thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:537:22
2019-11-18T06:55:32.5697807Z 
2019-11-18T06:55:32.5698890Z 
2019-11-18T06:55:32.5701323Z command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/incremental" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/incremental" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "incremental" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
2019-11-18T06:55:32.5701620Z 
2019-11-18T06:55:32.5701649Z 
2019-11-18T06:55:32.5710414Z failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
2019-11-18T06:55:32.5710505Z Build completed unsuccessfully in 1:01:56
2019-11-18T06:55:32.5710505Z Build completed unsuccessfully in 1:01:56
2019-11-18T06:55:32.5765259Z == clock drift check ==
2019-11-18T06:55:32.5786155Z   local time: Mon Nov 18 06:55:32 UTC 2019
2019-11-18T06:55:33.1003373Z   network time: Mon, 18 Nov 2019 06:55:33 GMT
2019-11-18T06:55:33.1004237Z == end clock drift check ==
2019-11-18T06:55:38.1292835Z 
2019-11-18T06:55:38.1386704Z ##[error]Bash exited with code '1'.
2019-11-18T06:55:38.1423978Z ##[section]Starting: Checkout
2019-11-18T06:55:38.1425643Z ==============================================================================
2019-11-18T06:55:38.1425715Z Task         : Get sources
2019-11-18T06:55:38.1425800Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@Centril Centril self-assigned this Nov 18, 2019
src/librustc_mir/transform/qualify_min_const_fn.rs Outdated Show resolved Hide resolved
src/librustc_passes/check_const.rs Outdated Show resolved Hide resolved
src/librustc_passes/check_const.rs Outdated Show resolved Hide resolved
src/librustc_passes/check_const.rs Outdated Show resolved Hide resolved
src/test/ui/consts/miri_unleashed/enum_discriminants.rs Outdated Show resolved Hide resolved
src/test/ui/consts/single_variant_match_ice.stderr Outdated Show resolved Hide resolved
src/test/ui/issues/issue-46843.stderr Outdated Show resolved Hide resolved
src/test/ui/issues/issue-50577.stderr Show resolved Hide resolved
src/tools/compiletest/src/errors.rs Show resolved Hide resolved
@Centril Centril added F-const_if_match A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. labels Nov 18, 2019
@Centril
Copy link
Contributor

Centril commented Nov 18, 2019

Added the feature gate label. @ecstatic-morse Could you please mark relevant past PRs that lead up to this one with that label as well? (It's very helpful for tracking implementation history for stabilization report purposes.)

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

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

I love how simple this is to do after all the refactorings and cleanups you did. Except for a diagnostic nit and some questions this looks ready to go to me

src/test/ui/consts/control-flow/interior-mutability.rs Outdated Show resolved Hide resolved
src/librustc_passes/check_const.rs Outdated Show resolved Hide resolved
src/test/ui/consts/control-flow/drop.rs Outdated Show resolved Hide resolved
@jyn514
Copy link
Member

jyn514 commented Nov 18, 2019

@ecstatic-morse this is really exciting! I still want to contribute tests but my laptop is currently broken so I'll be helping only sporadically.

Where would I start? I see you added tests in src/test/ui/consts/control-flow/basics.rs so I can follow that format, but what sort of things need to be tested? I would mostly be using this for enum matching (things like https://github.com/bytecodealliance/target-lexicon/blob/master/src/targets.rs#L126) but I imagine that isn't the hard part of this feature.

@ecstatic-morse ecstatic-morse force-pushed the const-if-match branch 2 times, most recently from 05a67b6 to 5e7a552 Compare November 18, 2019 23:12
@ecstatic-morse
Copy link
Contributor Author

I've rebased with @Centril's changes to the HIR const-checker applied. I now use emit_feature_err instead of custom logic. I also moved the compiletest changes into their own PR (#66524). I squashed all the test changes into one commit since the error messages are in flux and rebasing after each bless became a pain.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 20, 2019

Does this PR still count as WIP? Seems ready to me

@ecstatic-morse ecstatic-morse changed the title [WIP] Enable if and match in constants behind a feature flag Enable if and match in constants behind a feature flag Nov 20, 2019
@ecstatic-morse
Copy link
Contributor Author

@oli-obk Yeah, I think this is ready to go. I'd like to have a few more tests for interior mutability/Drop, but it's quite hard to come up with novel ones. Hopefully nightly users are more creative 😄.

@ecstatic-morse
Copy link
Contributor Author

Oh, this will have to be merged after #66524. They shouldn't conflict though.

@Centril
Copy link
Contributor

Centril commented Nov 20, 2019

@ecstatic-morse would be good to address #66507 (comment) first tho.

@bors
Copy link
Contributor

bors commented Nov 20, 2019

☔ The latest upstream changes (presumably #66578) made this pull request unmergeable. Please resolve the merge conflicts.

The `//[X]~` syntax filters errors for tests that are run across
multiple cfgs with  `// revisions:`. This commit extends that syntax to
accept `//[X,Y]~`, which will match multiple cfgs to the same error
annotation. This is functionally the same as writing two comments,
`//[X]~` and `//[Y]~`, but can fit on a single line.
This test does not actually emit any warnings, since
`#![allow(warnings)]` was specified. `compiletest` was erroneously
ignoring `//~` tests and looking only for `//[X]~` ones. As a result of
the changes in the previous commit, we now look for `//~` comments in
incremental tests and expect them to appear in *all* revisions.
These are generated when matching on enum variants to extract the value
within. We should have no problem evaluating these, but care should be
taken that we aren't accidentally allowing some other operation.
@@ -529,6 +529,9 @@ declare_features! (
/// Allows using the `#[register_attr]` attribute.
(active, register_tool, "1.41.0", Some(66079), None),

/// Allows the use of `if` and `match` in constants.
(active, const_if_match, "1.41.0", Some(49146), None),
Copy link
Contributor

Choose a reason for hiding this comment

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

Btw: a useful trick for the future, if you want to avoid rebasing due to this, is to move this before never_type_fallback.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
2019-11-21T23:24:47.3008807Z ##[command]git remote add origin https://github.com/rust-lang/rust
2019-11-21T23:24:48.0725402Z ##[command]git config gc.auto 0
2019-11-21T23:24:48.0729585Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2019-11-21T23:24:48.0734229Z ##[command]git config --get-all http.proxy
2019-11-21T23:24:48.0739881Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/66507/merge:refs/remotes/pull/66507/merge
---
2019-11-22T00:25:30.1450355Z .................................................................................................... 1600/9278
2019-11-22T00:25:35.0259555Z .................................................................................................... 1700/9278
2019-11-22T00:25:48.1920285Z ...........................i........................................................................ 1800/9278
2019-11-22T00:25:54.9704915Z .................................................................................................... 1900/9278
2019-11-22T00:26:09.4140055Z ............iiiii................................................................................... 2000/9278
2019-11-22T00:26:19.0124743Z .................................................................................................... 2200/9278
2019-11-22T00:26:21.5187022Z .................................................................................................... 2300/9278
2019-11-22T00:26:26.6422144Z .................................................................................................... 2400/9278
2019-11-22T00:26:48.2036519Z .................................................................................................... 2500/9278
---
2019-11-22T00:29:28.8651495Z ............i...............i....................................................................... 4800/9278
2019-11-22T00:29:39.6432697Z .................................................................................................... 4900/9278
2019-11-22T00:29:45.1443444Z .................................................................................................... 5000/9278
2019-11-22T00:29:54.7092063Z .................................................................................................... 5100/9278
2019-11-22T00:30:00.8071050Z .................ii.ii...........i.................................................................. 5200/9278
2019-11-22T00:30:10.0652922Z .................................................................................................... 5400/9278
2019-11-22T00:30:20.9805431Z ...............F...................................................................................i 5500/9278
2019-11-22T00:30:28.9067102Z .................................................................................................... 5600/9278
2019-11-22T00:30:34.7351969Z .................................................................................................... 5700/9278
2019-11-22T00:30:34.7351969Z .................................................................................................... 5700/9278
2019-11-22T00:30:45.2815902Z .....................................................................................ii...i..ii..... 5800/9278
2019-11-22T00:31:08.1491749Z .................................................................................................... 6000/9278
2019-11-22T00:31:16.2418734Z .................................................................................................... 6100/9278
2019-11-22T00:31:24.7287135Z .................................................................................................... 6200/9278
2019-11-22T00:31:24.7287135Z .................................................................................................... 6200/9278
2019-11-22T00:31:40.4345569Z ........i..ii....................................................................................... 6300/9278
2019-11-22T00:31:59.7907216Z ............................................................................i....................... 6500/9278
2019-11-22T00:32:02.2219295Z .................................................................................................... 6600/9278
2019-11-22T00:32:04.5895657Z .................................................................i.................................. 6700/9278
2019-11-22T00:32:07.6714622Z .................................................................................................... 6800/9278
---
2019-11-22T00:36:56.7331437Z diff of stderr:
2019-11-22T00:36:56.7331474Z 
2019-11-22T00:36:56.7331522Z 29    |             ^^^^^
2019-11-22T00:36:56.7331567Z 30 
2019-11-22T00:36:56.7331671Z 31 error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7332906Z +   --> $DIR/loop-break-value.rs:36:12
2019-11-22T00:36:56.7332988Z 33    |
2019-11-22T00:36:56.7333035Z 34 LL |         if break () {
2019-11-22T00:36:56.7333035Z 34 LL |         if break () {
2019-11-22T00:36:56.7333093Z 35    |            ^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7333199Z 40    |            ^^^^^
2019-11-22T00:36:56.7333243Z 41 
2019-11-22T00:36:56.7333243Z 41 
2019-11-22T00:36:56.7333293Z 42 error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7333825Z +   --> $DIR/loop-break-value.rs:41:9
2019-11-22T00:36:56.7333874Z 44    |
2019-11-22T00:36:56.7333936Z 45 LL |         break None;
2019-11-22T00:36:56.7333936Z 45 LL |         break None;
2019-11-22T00:36:56.7333993Z 46    |         ^^^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7334073Z 51    |         ^^^^^
2019-11-22T00:36:56.7334134Z 52 
2019-11-22T00:36:56.7334134Z 52 
2019-11-22T00:36:56.7334182Z 53 error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7334728Z +   --> $DIR/loop-break-value.rs:47:13
2019-11-22T00:36:56.7334777Z 55    |
2019-11-22T00:36:56.7334777Z 55    |
2019-11-22T00:36:56.7335034Z 56 LL |             break 'while_let_loop "nope";
2019-11-22T00:36:56.7335113Z 57    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7335182Z 
2019-11-22T00:36:56.7335231Z The actual stderr differed from the expected stderr.
2019-11-22T00:36:56.7335594Z Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/loops/loop-break-value/loop-break-value.stderr
2019-11-22T00:36:56.7335594Z Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/loops/loop-break-value/loop-break-value.stderr
2019-11-22T00:36:56.7335884Z To update references, rerun the tests and pass the `--bless` flag
2019-11-22T00:36:56.7336188Z To only update this specific test, also pass `--test-args loops/loop-break-value.rs`
2019-11-22T00:36:56.7336294Z error: 1 errors occurred comparing output.
2019-11-22T00:36:56.7336344Z status: exit code: 1
2019-11-22T00:36:56.7336344Z status: exit code: 1
2019-11-22T00:36:56.7337570Z command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/loops/loop-break-value.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/loops/loop-break-value" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/loops/loop-break-value/auxiliary" "-A" "unused"
2019-11-22T00:36:56.7337982Z ------------------------------------------
2019-11-22T00:36:56.7338023Z 
2019-11-22T00:36:56.7338275Z ------------------------------------------
2019-11-22T00:36:56.7338324Z stderr:
2019-11-22T00:36:56.7338324Z stderr:
2019-11-22T00:36:56.7338587Z ------------------------------------------
2019-11-22T00:36:56.7338640Z warning: denote infinite loops with `loop { ... }`
2019-11-22T00:36:56.7338998Z    |
2019-11-22T00:36:56.7338998Z    |
2019-11-22T00:36:56.7339283Z LL |     'while_loop: while true { //~ WARN denote infinite loops with
2019-11-22T00:36:56.7339340Z    |     ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop`
2019-11-22T00:36:56.7339403Z    |
2019-11-22T00:36:56.7339452Z    = note: `#[warn(while_true)]` on by default
2019-11-22T00:36:56.7339485Z 
2019-11-22T00:36:56.7339534Z error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7339875Z    |
2019-11-22T00:36:56.7339875Z    |
2019-11-22T00:36:56.7339927Z LL |         break (); //~ ERROR `break` with value from a `while` loop
2019-11-22T00:36:56.7340001Z    |         ^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7340053Z    |
2019-11-22T00:36:56.7340109Z help: instead, use `break` on its own without a value inside this `while` loop
2019-11-22T00:36:56.7340175Z    |
2019-11-22T00:36:56.7340245Z LL |         break; //~ ERROR `break` with value from a `while` loop
2019-11-22T00:36:56.7340341Z 
2019-11-22T00:36:56.7340341Z 
2019-11-22T00:36:56.7340390Z error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7340728Z    |
2019-11-22T00:36:56.7340989Z LL |             break 'while_loop 123;
2019-11-22T00:36:56.7340989Z LL |             break 'while_loop 123;
2019-11-22T00:36:56.7341048Z    |             ^^^^^^^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7341099Z    |
2019-11-22T00:36:56.7341167Z help: instead, use `break` on its own without a value inside this `while` loop
2019-11-22T00:36:56.7341262Z LL |             break;
2019-11-22T00:36:56.7341325Z    |             ^^^^^
2019-11-22T00:36:56.7341355Z 
2019-11-22T00:36:56.7341355Z 
2019-11-22T00:36:56.7341404Z error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7341760Z    |
2019-11-22T00:36:56.7341760Z    |
2019-11-22T00:36:56.7341813Z LL |         if break () { //~ ERROR `break` with value from a `while` loop
2019-11-22T00:36:56.7342155Z    |            ^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7342231Z    |
2019-11-22T00:36:56.7342284Z help: instead, use `break` on its own without a value inside this `while` loop
2019-11-22T00:36:56.7342332Z    |
2019-11-22T00:36:56.7342399Z LL |         if break { //~ ERROR `break` with value from a `while` loop
2019-11-22T00:36:56.7342479Z 
2019-11-22T00:36:56.7342479Z 
2019-11-22T00:36:56.7342528Z error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7342929Z    |
2019-11-22T00:36:56.7342975Z LL |         break None;
2019-11-22T00:36:56.7342975Z LL |         break None;
2019-11-22T00:36:56.7343044Z    |         ^^^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7343225Z    |
2019-11-22T00:36:56.7343336Z help: instead, use `break` on its own without a value inside this `while` loop
2019-11-22T00:36:56.7343452Z LL |         break;
2019-11-22T00:36:56.7343499Z    |         ^^^^^
2019-11-22T00:36:56.7343529Z 
2019-11-22T00:36:56.7343529Z 
2019-11-22T00:36:56.7343593Z error[E0571]: `break` with value from a `while` loop
2019-11-22T00:36:56.7343957Z    |
2019-11-22T00:36:56.7343957Z    |
2019-11-22T00:36:56.7344227Z LL |             break 'while_let_loop "nope";
2019-11-22T00:36:56.7344290Z    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7344344Z    |
2019-11-22T00:36:56.7344420Z help: instead, use `break` on its own without a value inside this `while` loop
2019-11-22T00:36:56.7344514Z LL |             break;
2019-11-22T00:36:56.7344559Z    |             ^^^^^
2019-11-22T00:36:56.7344615Z 
2019-11-22T00:36:56.7344615Z 
2019-11-22T00:36:56.7344671Z error[E0571]: `break` with value from a `for` loop
2019-11-22T00:36:56.7345019Z    |
2019-11-22T00:36:56.7345019Z    |
2019-11-22T00:36:56.7345071Z LL |         break (); //~ ERROR `break` with value from a `for` loop
2019-11-22T00:36:56.7345130Z    |         ^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7345193Z    |
2019-11-22T00:36:56.7345246Z help: instead, use `break` on its own without a value inside this `for` loop
2019-11-22T00:36:56.7345295Z    |
2019-11-22T00:36:56.7345403Z LL |         break; //~ ERROR `break` with value from a `for` loop
2019-11-22T00:36:56.7345500Z 
2019-11-22T00:36:56.7345500Z 
2019-11-22T00:36:56.7345548Z error[E0571]: `break` with value from a `for` loop
2019-11-22T00:36:56.7345892Z    |
2019-11-22T00:36:56.7345892Z    |
2019-11-22T00:36:56.7345937Z LL |         break [()];
2019-11-22T00:36:56.7346008Z    |         ^^^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7346072Z    |
2019-11-22T00:36:56.7346125Z help: instead, use `break` on its own without a value inside this `for` loop
2019-11-22T00:36:56.7346234Z LL |         break;
2019-11-22T00:36:56.7346280Z    |         ^^^^^
2019-11-22T00:36:56.7346309Z 
2019-11-22T00:36:56.7346309Z 
2019-11-22T00:36:56.7346357Z error[E0571]: `break` with value from a `for` loop
2019-11-22T00:36:56.7346704Z    |
2019-11-22T00:36:56.7346952Z LL |             break 'for_loop Some(17);
2019-11-22T00:36:56.7346952Z LL |             break 'for_loop Some(17);
2019-11-22T00:36:56.7347028Z    |             ^^^^^^^^^^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block
2019-11-22T00:36:56.7347079Z    |
2019-11-22T00:36:56.7347130Z help: instead, use `break` on its own without a value inside this `for` loop
2019-11-22T00:36:56.7347241Z LL |             break;
2019-11-22T00:36:56.7347302Z    |             ^^^^^
2019-11-22T00:36:56.7347332Z 
2019-11-22T00:36:56.7347393Z error[E0308]: mismatched types
2019-11-22T00:36:56.7347393Z error[E0308]: mismatched types
2019-11-22T00:36:56.7347665Z   --> /checkout/src/test/ui/loops/loop-break-value.rs:2:31
2019-11-22T00:36:56.7347715Z    |
2019-11-22T00:36:56.7347778Z LL |     let val: ! = loop { break break; };
2019-11-22T00:36:56.7347833Z    |                               ^^^^^ expected `!`, found `()`
2019-11-22T00:36:56.7347940Z    = note:   expected type `!`
2019-11-22T00:36:56.7347989Z            found unit type `()`
2019-11-22T00:36:56.7348020Z 
2019-11-22T00:36:56.7348064Z error[E0308]: mismatched types
---
2019-11-22T00:36:56.7348561Z 
2019-11-22T00:36:56.7348700Z error[E0308]: mismatched types
2019-11-22T00:36:56.7349079Z   --> /checkout/src/test/ui/loops/loop-break-value.rs:14:15
2019-11-22T00:36:56.7349157Z    |
2019-11-22T00:36:56.7349206Z LL |         break "asdf"; //~ ERROR mismatched types
2019-11-22T00:36:56.7349259Z    |               ^^^^^^ expected `i32`, found `&str`
2019-11-22T00:36:56.7349355Z error[E0308]: mismatched types
2019-11-22T00:36:56.7349658Z   --> /checkout/src/test/ui/loops/loop-break-value.rs:19:31
2019-11-22T00:36:56.7349709Z    |
2019-11-22T00:36:56.7349709Z    |
2019-11-22T00:36:56.7350003Z LL |             break 'outer_loop "nope"; //~ ERROR mismatched types
2019-11-22T00:36:56.7350062Z    |                               ^^^^^^ expected `i32`, found `&str`
2019-11-22T00:36:56.7350143Z error[E0308]: mismatched types
2019-11-22T00:36:56.7350431Z   --> /checkout/src/test/ui/loops/loop-break-value.rs:71:26
2019-11-22T00:36:56.7350481Z    |
2019-11-22T00:36:56.7350481Z    |
2019-11-22T00:36:56.7350749Z LL |                 break 'c 123; //~ ERROR mismatched types
2019-11-22T00:36:56.7350841Z    |                          ^^^ expected `()`, found integer
2019-11-22T00:36:56.7350920Z error[E0308]: mismatched types
2019-11-22T00:36:56.7351206Z   --> /checkout/src/test/ui/loops/loop-break-value.rs:78:15
2019-11-22T00:36:56.7351256Z    |
2019-11-22T00:36:56.7351256Z    |
2019-11-22T00:36:56.7351306Z LL |         break (break, break); //~ ERROR mismatched types
2019-11-22T00:36:56.7351360Z    |               ^^^^^^^^^^^^^^ expected `()`, found tuple
2019-11-22T00:36:56.7351468Z    = note: expected unit type `()`
2019-11-22T00:36:56.7351468Z    = note: expected unit type `()`
2019-11-22T00:36:56.7351518Z                   found tuple `(!, !)`
2019-11-22T00:36:56.7351613Z error[E0308]: mismatched types
2019-11-22T00:36:56.7352296Z   --> /checkout/src/test/ui/loops/loop-break-value.rs:83:15
2019-11-22T00:36:56.7352359Z    |
2019-11-22T00:36:56.7352427Z LL |         break 2; //~ ERROR mismatched types
---
2019-11-22T00:36:56.7353297Z    |
2019-11-22T00:36:56.7353346Z LL |         break; //~ ERROR mismatched types
2019-11-22T00:36:56.7353412Z    |         ^^^^^
2019-11-22T00:36:56.7353457Z    |         |
2019-11-22T00:36:56.7353506Z    |         expected integer, found `()`
2019-11-22T00:36:56.7353575Z    |         help: give it a value of the expected type: `break value`
2019-11-22T00:36:56.7353658Z error: aborting due to 16 previous errors
2019-11-22T00:36:56.7353690Z 
2019-11-22T00:36:56.7353756Z Some errors have detailed explanations: E0308, E0571.
2019-11-22T00:36:56.7354288Z For more information about an error, try `rustc --explain E0308`.
---
2019-11-22T00:36:56.7361281Z thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:537:22
2019-11-22T00:36:56.7361617Z note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
2019-11-22T00:36:56.7376513Z 
2019-11-22T00:36:56.7376782Z 
2019-11-22T00:36:56.7379312Z command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
2019-11-22T00:36:56.7380087Z 
2019-11-22T00:36:56.7380246Z 
2019-11-22T00:36:56.7385411Z failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
2019-11-22T00:36:56.7385647Z Build completed unsuccessfully in 1:05:48
2019-11-22T00:36:56.7385647Z Build completed unsuccessfully in 1:05:48
2019-11-22T00:36:56.7436453Z == clock drift check ==
2019-11-22T00:36:56.7456543Z   local time: Fri Nov 22 00:36:56 UTC 2019
2019-11-22T00:36:57.0280288Z   network time: Fri, 22 Nov 2019 00:36:57 GMT
2019-11-22T00:36:57.0285926Z == end clock drift check ==
2019-11-22T00:36:57.8599199Z 
2019-11-22T00:36:57.8730299Z ##[error]Bash exited with code '1'.
2019-11-22T00:36:57.8767554Z ##[section]Starting: Checkout
2019-11-22T00:36:57.8769322Z ==============================================================================
2019-11-22T00:36:57.8769374Z Task         : Get sources
2019-11-22T00:36:57.8769434Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

This creates a new test directory, `ui/consts/control-flow` to hold
tests related to control flow in a const context. It also blesses all
existing tests with the new error messages, and adds new tests for the
`const_if_match` feature.
@ecstatic-morse
Copy link
Contributor Author

ecstatic-morse commented Nov 22, 2019

@oli-obk Can you take a final look at this when you have the time? The inside Rust post should be ready as well, but it would also benefit from a review.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 22, 2019

@bors r+

@bors
Copy link
Contributor

bors commented Nov 22, 2019

📌 Commit b09bb15 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 Nov 22, 2019
@bors
Copy link
Contributor

bors commented Nov 23, 2019

⌛ Testing commit b09bb15 with merge 6d523ee...

bors added a commit that referenced this pull request Nov 23, 2019
Enable `if` and `match` in constants behind a feature flag

This PR is an initial implementation of #49146. It introduces a `const_if_match` feature flag and does the following if it is enabled:
- Allows `Downcast` projections, `SwitchInt` terminators and `FakeRead`s for matched places through the MIR const-checker.
- Allows `if` and `match` expressions through the HIR const-checker.
- Stops converting `&&` to `&` and `||` to `|` in `const` and `static` items.

As a result, the following operations are now allowed in a const context behind the feature flag:
- `if` and `match`
- short circuiting logic operators (`&&` and `||`)
- the `assert` and `debug_assert` macros (if the `const_panic` feature flag is also enabled)

However, the following operations remain forbidden:
- `while`, `loop` and `for` (see #52000)
- the `?` operator (calls `From::from` on its error variant)
- the `assert_eq` and `assert_ne` macros, along with their `debug` variants (calls `fmt::Debug`)

This PR is possible now that we use dataflow for const qualification (see #64470 and #66385).

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

bors commented Nov 23, 2019

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

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 23, 2019
@bors bors merged commit b09bb15 into rust-lang:master Nov 23, 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 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
yvt added a commit to yvt/Stella2 that referenced this pull request Jan 1, 2020
With rust-lang/rust#66507 merged, `Prop::kind_flags` can be `const fn`
and the `prop!` macro can use this method to get the kind flags for a
given prop.
@ecstatic-morse ecstatic-morse deleted the const-if-match 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
A-const-eval Area: Constant evaluation (MIR interpretation) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. 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.

8 participants