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

Stabilize underscore_const_names in 1.37.0 #61347

Open
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
6 participants
@Centril
Copy link
Member

commented May 30, 2019

You are now permitted to write:

const _: $type_expression = $term_expression;

That is, we change the grammar of items, as written in the .lyg notation, from:

Item = attrs:OuterAttr* vis:Vis? kind:ItemKind;
ItemKind =
  | ...
  | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" }
  | ...
  ;

into:

Item = attrs:OuterAttr* vis:Vis? kind:ItemKind;
ItemKind =
  | ...
  | Const:{ "const" name:IdentOrUnderscore ":" ty:Type "=" value:Expr ";" }
  | ...
  ;

IdentOrUnderscore =
  | Named:IDENT
  | NoName:"_"
  ;

r? @petrochenkov

@Centril Centril added this to the 1.37 milestone May 30, 2019

@Centril Centril changed the title Stabilize underscore_const_names in 1.37.0 [WIP] Stabilize underscore_const_names in 1.37.0 May 30, 2019

@Centril Centril force-pushed the Centril:stabilize-underscore_const_names branch from e998227 to 85b1489 May 30, 2019

@rust-highfive

This comment was marked as resolved.

Copy link
Collaborator

commented May 30, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (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.
travis_time:end:01014b7c:start=1559226135180126665,finish=1559226137334986621,duration=2154859956
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
[01:10:18] .................................................................................................... 3800/5598
[01:10:22] ..ii................................................................................................ 3900/5598
[01:10:24] .......................i............................................................................ 4000/5598
[01:10:26] .......................................................................................i............ 4100/5598
[01:10:28] .........................................................................................F.......... 4200/5598
[01:10:47] .................................................................................................... 4400/5598
[01:10:50] .................................................................................................... 4500/5598
[01:10:53] .................................................................................................... 4600/5598
[01:10:57] .................................................................................................... 4700/5598
---
[01:11:34] 1 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:4:11
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:6:11
[01:11:34] 3    |
[01:11:34] 4 LL |     const _: () = ();
[01:11:34] 
[01:11:34] 6 
[01:11:34] 7 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:7:11
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:7:11
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:9:11
[01:11:34] 9    |
[01:11:34] 10 LL |     const _: () = ();
[01:11:34] 
[01:11:34] 12 
[01:11:34] 13 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:10:11
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:10:11
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:12:11
[01:11:34] 15    |
[01:11:34] 16 LL |     const _: () = ();
[01:11:34] 
[01:11:34] 18 
[01:11:34] 19 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:15:8
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:15:8
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:17:8
[01:11:34] 21    |
[01:11:34] 22 LL | static _: () = ();
[01:11:34] 
[01:11:34] 24 
[01:11:34] 25 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:16:8
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:16:8
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:18:8
[01:11:34] 27    |
[01:11:34] 28 LL | struct _();
[01:11:34] 
[01:11:34] 30 
[01:11:34] 31 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:17:6
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:17:6
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:19:6
[01:11:34] 33    |
[01:11:34] 34 LL | enum _ {}
[01:11:34] 
[01:11:34] 36 
[01:11:34] 37 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:18:4
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:18:4
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:20:4
[01:11:34] 39    |
[01:11:34] 40 LL | fn _() {}
[01:11:34] 
[01:11:34] 42 
[01:11:34] 43 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:19:5
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:19:5
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:21:5
[01:11:34] 45    |
[01:11:34] 46 LL | mod _ {}
[01:11:34] 
[01:11:34] 48 
[01:11:34] 49 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:20:6
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:20:6
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:22:6
[01:11:34] 51    |
[01:11:34] 52 LL | type _ = ();
[01:11:34] 
[01:11:34] 54 
[01:11:34] 55 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:21:5
---
[01:11:34] 61 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:22:5
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:24:5
[01:11:34] 63    |
[01:11:34] 64 LL | use _ as g;
[01:11:34] 
[01:11:34] 66 
[01:11:34] 67 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:23:7
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:23:7
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:25:7
[01:11:34] 69    |
[01:11:34] 70 LL | trait _ {}
[01:11:34] 
[01:11:34] 72 
[01:11:34] 73 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:24:7
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:24:7
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:26:7
[01:11:34] 75    |
[01:11:34] 76 LL | trait _ = Copy;
[01:11:34] 
[01:11:34] 78 
[01:11:34] 79 error: expected identifier, found reserved identifier `_`
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:25:14
[01:11:34] -   --> $DIR/underscore_item_not_const.rs:25:14
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:27:14
[01:11:34] 81    |
[01:11:34] 82 LL | macro_rules! _ { () => {} }
[01:11:34] 
[01:11:34] 84 
[01:11:34] 84 
[01:11:34] 85 error: expected one of `!` or `::`, found `_`
[01:11:34] +   --> $DIR/underscore_item_not_const.rs:28:7
[01:11:34] 87    |
[01:11:34] 87    |
[01:11:34] 88 LL | union _ { f: u8 }
[01:11:34] 89    |       ^ expected one of `!` or `::` here
[01:11:34] 
[01:11:34] The actual stderr differed from the expected stderr.
[01:11:34] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/underscore_item_not_const/underscore_item_not_const.stderr
[01:11:34] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/underscore_item_not_const/underscore_item_not_const.stderr
[01:11:34] To update references, rerun the tests and pass the `--bless` flag
[01:11:34] To only update this specific test, also pass `--test-args parser/underscore_item_not_const.rs`
[01:11:34] error: 1 errors occurred comparing output.
[01:11:34] status: exit code: 1
[01:11:34] status: exit code: 1
[01:11:34] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/parser/underscore_item_not_const.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/parser/underscore_item_not_const" "-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/parser/underscore_item_not_const/auxiliary" "-A" "unused"
[01:11:34] ------------------------------------------
[01:11:34] 
[01:11:34] ------------------------------------------
[01:11:34] stderr:
[01:11:34] stderr:
[01:11:34] ------------------------------------------
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:6:11
[01:11:34]    |
[01:11:34] LL |     const _: () = (); //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:9:11
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL |     const _: () = (); //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:12:11
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL |     const _: () = (); //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:17:8
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | static _: () = (); //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:18:8
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | struct _(); //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:19:6
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | enum _ {} //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:20:4
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | fn _() {} //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:21:5
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | mod _ {} //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:22:6
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | type _ = (); //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:23:5
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | use _; //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:24:5
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | use _ as g; //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:25:7
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | trait _ {} //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:26:7
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | trait _ = Copy; //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] error: expected identifier, found reserved identifier `_`
[01:11:34]   --> /checkout/src/test/ui/parser/underscore_item_not_const.rs:27:14
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | macro_rules! _ { () => {} } //~ ERROR expected identifier, found reserved identifier `_`
[01:11:34] 
[01:11:34] 
[01:11:34] error: expected one of `!` or `::`, found `_`
[01:11:34]    |
[01:11:34]    |
[01:11:34] LL | union _ { f: u8 } //~ ERROR expected one of `!` or `::`, found `_`
[01:11:34]    |       ^ expected one of `!` or `::` here
[01:11:34] error: aborting due to 15 previous errors
[01:11:34] 
[01:11:34] 
[01:11:34] ------------------------------------------
---
[01:11:34] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:521:22
[01:11:34] note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
[01:11:34] 
[01:11:34] 
[01:11:34] 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"
[01:11:34] 
[01:11:34] 
[01:11:34] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:11:34] Build completed unsuccessfully in 0:04:46
[01:11:34] Build completed unsuccessfully in 0:04:46
[01:11:34] make: *** [check] Error 1
[01:11:34] Makefile:48: recipe for target 'check' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:003c0f34
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Thu May 30 15:34:02 UTC 2019
---
travis_time:end:00ccfe56:start=1559230443555786556,finish=1559230443560789183,duration=5002627
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0d8dfc68
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:224bc0bc
travis_time:start:224bc0bc
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:03e06140
$ dmesg | grep -i kill

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 force-pushed the Centril:stabilize-underscore_const_names branch from 85b1489 to 63829d2 May 30, 2019

@Centril Centril added I-nominated and removed I-nominated labels May 30, 2019

@Centril Centril changed the title [WIP] Stabilize underscore_const_names in 1.37.0 Stabilize underscore_const_names in 1.37.0 May 31, 2019

@Centril

This comment has been minimized.

Copy link
Member Author

commented May 31, 2019

Stabilization proposal

I propose that we stabilize #![feature(underscore_const_names)].

@rfcbot merge

Tracking issue: #54912
Version target: 1.37 (2019-07-04 => beta, 2019-08-15 => stable).

What is stabilized

You are now permitted to write:

const _: $type_expression = $term_expression;

That is, we change the grammar of items, as written in the .lyg notation, from:

Item = attrs:OuterAttr* vis:Vis? kind:ItemKind;
ItemKind =
  | ...
  | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" }
  | ...
  ;

into:

Item = attrs:OuterAttr* vis:Vis? kind:ItemKind;
ItemKind =
  | ...
  | Const:{ "const" name:IdentOrUnderscore ":" ty:Type "=" value:Expr ";" }
  | ...
  ;

IdentOrUnderscore =
  | Named:IDENT
  | NoName:"_"
  ;

When name = NoName occurs then there are no run-time semantics because an unnamed constant cannot be referred to. With respect to compile-time dynamic semantics, the same rules apply as an unused constant has today. E.g., if you have const _: () = <diverges>; then #[deny(const_err)] will trigger. As for static semantics, an unnamed constant item behaves as normal with respect to type checking.

What is not stabilized

  • Only a free const item may use _ as its name. Associated ones may not.
  • Non-const items may not use _ as a name. Notably, static items may not.
  • const items may not use arbitrary irrefutable patterns. E.g., we do not permit const (A, B): (u8, u8) = (1, 2);

Divergences from RFC and unresolved questions

None.

Tests

The tests can be primarily seen in the PR itself. Here are some of them:

History

  • In #48922 import renaming with _ was implemented.
    The PR was written by @petrochenkov, reviewed by @nikomatsakis, and was merged on 2018-03-16.
    The PR added the now stabilized underscore_imports feature under which you may write e.g.

    extern crate foo as _;
    use bar as _;
  • RFC 2526 by @joshlf then proposed to add const _: $type = $expr; and was merged on 2018-10-08 after which the tracking issue #54912 was filed.

  • The underscore_const_names feature was then implemented in #55015 on 2018-10-14 by @dsciarra. The PR was reviewed by @petrochenkov.

  • In #54912 (comment), @oli-obk found a stability hole which allowed static _: $type = $expr;. @oli-obk plugged this stability hole in #55983 which was then subsequently beta-backported. This PR, merged on 2019-11-20 was reviewed by @nikomatsakis.

  • In #56392, @petrochenkov adjusted underscore_imports and underscore_const_names such that gensym creation happens first after name resolution. Moreover, the PR, merged on 2018-12-06 and reviewed by @oli-obk, prohibited accidentally implemented static _: $type = $expr.

  • This PR stabilizes underscore_const_names and hardens the tests in some respects.

Motivation

The general motivation for const _: $type = $expr; is to facilitate writing well-behaved macros.
For example, procedural macros such as serde_derive generate a constant item to wrap the implementation into. Another example of this is proptest_derive which generates roughly:

#[allow(non_upper_case_globals)]
const _IMPL_ARBITRARY_FOR_MyType: () = {
    impl proptest::arbitrary::Arbitrary for MyType {
        ...
    }
};

Instead, it would be better to generate:

const _: () = {
    impl proptest::arbitrary::Arbitrary for MyType {
        ...
    }
};

This not only has the advantage of generating less code, but also produces better diagnostics.

Other motivational examples include:

More generally, const _: () = $expr; is an idiom allowing users to type check a piece of code but not necessarily more than that.

Potential concerns

There is some concern that underscore_const_names is an ad-hoc way to achieve the desired outcomes. In particular, instead of supporting identifiers or an underscore, we could support arbitrary irrefutable patterns for const items. Moreover, stabilizing const _ would further diverge constant items from static items which could ostensibly also support underscores or even arbitrary irrefutable patterns. However, there are open semantic questions with static _ and arbitrary irrefutable patterns for const requires more work in the compiler. In any case, the stabilization of const _ still keeps us forward compatible with such extensions and therefore these concerns may be put aside for the time being.

There is also some concern of how const _ would compose with associated constants as well as generic ones. Presumably, something like const (A, _)<T>... does not make sense but we also do not have to support the combination of arbitrary irrefutable patterns and generic constants. As for associated constants, one could imagine defining or providing multiple associated constants through pattern matching one constant expression inside an implementation. All in all, the generalization problems do not seem insurmountable.

Some considered alternatives

Unnamed modules, mod _ { ... }

As an alternative to const _: $type = $expr; one could allow mod _ { ... } instead.
The grammar for mod items would use the same IdentOrUnderscore production. When considering mod _ { ... } note that:

  • It is often the point of const _: $type = $expr; to check that an $expression satisfies some condition, e.g., that it is an expression that does not diverge (const_assert!(...)). In these cases, mod _ { ... } is at a disadvantage because the body accepts items and not expressions. To remedy this, you'd need a const item inside the mod item thus unnecessarily generating more tokens. Meanwhile, fitting an item inside an expr requires less.

  • mod _ { ... } has the same problems wrt. generics as const _: $type = $expr; has. Namely, one could consider generic modules mod _<T, ...> { ... }. However, there's no strange interactions between pattern matching and generics here.

  • mod _ { ... } has fewer interactions and is less generalizable. This can both be a good thing because it is more "complete" sooner but it can also feel more ad-hoc. However, we already have use foo as _; so the production IndentOrUnderscore already exists in stable Rust.

Overall, we believe const _ to be a better fit because it has a natural generalization and works better with macros overall.

const { ... } blocks

Another alternative would be some sort of const { ... } block. This would take the grammatical form:

ItemKind =
  | ...
  | ConstBlock:{ "const" value:Block }
  | ...
  ;

ExprKind =
  | ...
  | ConstBlock:{ "const" value:Block }
  | ...
  ;

Notably, const { ... } would have the double duty as an expression and item form.
Assigning unsurprising semantics to const { ... } as an expression is easy: the block is a const context and as any block it may contain a series of statements followed by an optional tail expression which is the value of the block. As an item, it is less clear what the tail expression would be. Would we require that the tail expression be implicitly coercible to ()? Would we allow a tail expression at all? Overall, a const { ... } is probably a better fit solely as an expression form and not as an item.

Possible future work

As aforementioned, natural extensions to const _: $type = $expr; primarily includes:

  • Extending _ to $pat.
  • Extending _ or $pat to static items as well. In this case we should figure out what consistent, useful, and expected dynamic semantics are for situations such as static (A, _): (u8, u8) = (1, 2);.
  • Finally, we should consider whether it would make sense to extend const _ to associated constants as well and what implications this has for static items.
@rfcbot

This comment has been minimized.

Copy link

commented May 31, 2019

Team member @Centril has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@Centril

This comment has been minimized.

Copy link
Member Author

commented May 31, 2019

N.B. Aaron is on leave so I've checked his box.

@petrochenkov

This comment has been minimized.

Copy link
Contributor

commented May 31, 2019

Implementation LGMT, marking as waiting on team.

@rfcbot

This comment has been minimized.

Copy link

commented Jun 6, 2019

🔔 This is now entering its final comment period, as per the review above. 🔔

@Centril Centril removed the I-nominated label Jun 6, 2019

@bors

This comment was marked as resolved.

Copy link
Contributor

commented Jun 10, 2019

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

@Centril Centril force-pushed the Centril:stabilize-underscore_const_names branch from 286ad9c to e62c9d7 Jun 10, 2019

@brson

This comment has been minimized.

Copy link
Contributor

commented Jun 14, 2019

Looks like quite a hack to achieve the stated outcome. Reminds me of javascript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.