From 0fdf24bcf332ebc96fcc4d292e6752ea0ec58640 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 17 Jul 2019 10:30:29 -0500 Subject: [PATCH 01/49] actually test rustc-guide with toolstate --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 9995d2aac7f24..2b5c3cc34b847 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -25,6 +25,7 @@ python2.7 "$X_PY" test --no-fail-fast \ src/doc/rust-by-example \ src/doc/embedded-book \ src/doc/edition-guide \ + src/doc/rustc-guide \ src/tools/clippy \ src/tools/rls \ src/tools/rustfmt \ From 97b4156398ee693dd492f70dfc33e80a93a5faf7 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 17 Jul 2019 11:44:33 -0500 Subject: [PATCH 02/49] don't fail builds for rustc-guide --- src/ci/docker/x86_64-gnu-tools/checkregression.py | 6 +++++- src/ci/docker/x86_64-gnu-tools/checktools.sh | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index 0cc0a6329e5bf..c1211579648eb 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -4,6 +4,9 @@ import sys import json +# Regressions for these tools does not cause failure +REGRESSION_OK = ["rustc-guide"] + if __name__ == '__main__': os_name = sys.argv[1] toolstate_file = sys.argv[2] @@ -32,7 +35,8 @@ 'The state of "{}" has {} from "{}" to "{}"' .format(tool, verb, state, new_state) ) - regressed = True + if tool not in REGRESSION_OK: + regressed = True if regressed: sys.exit(1) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 2b5c3cc34b847..4fb65b4e96192 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -89,7 +89,6 @@ status_check() { # these tools are not required for beta to successfully branch check_dispatch $1 nightly miri src/tools/miri check_dispatch $1 nightly embedded-book src/doc/embedded-book - check_dispatch $1 nightly rustc-guide src/doc/rustc-guide } # If this PR is intended to update one of these tools, do not let the build pass From 8070bb828c01c14bd16a6e9afca82c1d1fdff543 Mon Sep 17 00:00:00 2001 From: Who? Me?! Date: Thu, 18 Jul 2019 08:42:39 -0500 Subject: [PATCH 03/49] Regressions ok for miri too Co-Authored-By: kennytm --- src/ci/docker/x86_64-gnu-tools/checkregression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index c1211579648eb..f8d9190a066a9 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -5,7 +5,7 @@ import json # Regressions for these tools does not cause failure -REGRESSION_OK = ["rustc-guide"] +REGRESSION_OK = ["rustc-guide", "miri"] if __name__ == '__main__': os_name = sys.argv[1] From b2d05dba415ee7079dfcf1051a4474c7efd44bdf Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 18 Jul 2019 10:47:38 +0200 Subject: [PATCH 04/49] add a few comments for the toolstate stuff --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 12 ++++++++---- src/ci/docker/x86_64-gnu-tools/repo.sh | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 4fb65b4e96192..c8ef1a0f78f80 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -42,7 +42,7 @@ check_tool_failed() { } # This function checks that if a tool's submodule changed, the tool's state must improve -verify_status() { +verify_submodule_changed() { echo "Verifying status of $1..." if echo "$CHANGED_FILES" | grep -q "^M[[:blank:]]$2$"; then echo "This PR updated '$2', verifying if status is 'test-pass'..." @@ -67,7 +67,7 @@ verify_status() { check_dispatch() { if [ "$1" = submodule_changed ]; then # ignore $2 (branch id) - verify_status $3 $4 + verify_submodule_changed $3 $4 elif [ "$2" = beta ]; then echo "Requiring test passing for $3..." if check_tool_failed "$3"; then @@ -76,7 +76,9 @@ check_dispatch() { fi } -# list all tools here +# List all tools here. +# This function gets called with "submodule_changed" for each PR that changed a submodule, +# and with "beta_required" for each PR that lands on beta/stable. status_check() { check_dispatch $1 beta book src/doc/book check_dispatch $1 beta nomicon src/doc/nomicon @@ -86,7 +88,8 @@ status_check() { check_dispatch $1 beta rls src/tools/rls check_dispatch $1 beta rustfmt src/tools/rustfmt check_dispatch $1 beta clippy-driver src/tools/clippy - # these tools are not required for beta to successfully branch + # These tools are not required on the beta/stable branches. + # They will still cause failure during the beta cutoff week, see `src/tools/publish_toolstate.py` for that. check_dispatch $1 nightly miri src/tools/miri check_dispatch $1 nightly embedded-book src/doc/embedded-book } @@ -97,6 +100,7 @@ status_check() { status_check "submodule_changed" CHECK_NOT="$(readlink -f "$(dirname $0)/checkregression.py")" +# This callback is called by `commit_toolstate_change`, see `repo.sh`. change_toolstate() { # only update the history if python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" changed; then diff --git a/src/ci/docker/x86_64-gnu-tools/repo.sh b/src/ci/docker/x86_64-gnu-tools/repo.sh index 741d4dcbd9a45..35ab7e2b8c839 100644 --- a/src/ci/docker/x86_64-gnu-tools/repo.sh +++ b/src/ci/docker/x86_64-gnu-tools/repo.sh @@ -62,6 +62,10 @@ commit_toolstate_change() { MESSAGE_FILE="$1" shift for RETRY_COUNT in 1 2 3 4 5; do + # Call the callback; this will in the end call `change_toolstate` from + # `checktools.sh` if we are in the `auto` branch (pre-landing) or + # `src/tools/publish_toolstate.py` if we are in the `master` branch + # (post-landing). "$@" # `git commit` failing means nothing to commit. FAILURE=0 From 8b87162af2a505b187fd1f9c27c084b6c4174882 Mon Sep 17 00:00:00 2001 From: Who? Me?! Date: Thu, 18 Jul 2019 08:57:55 -0500 Subject: [PATCH 05/49] Update src/ci/docker/x86_64-gnu-tools/checktools.sh Co-Authored-By: Ralf Jung --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index c8ef1a0f78f80..8df63c214e189 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -89,7 +89,7 @@ status_check() { check_dispatch $1 beta rustfmt src/tools/rustfmt check_dispatch $1 beta clippy-driver src/tools/clippy # These tools are not required on the beta/stable branches. - # They will still cause failure during the beta cutoff week, see `src/tools/publish_toolstate.py` for that. + # They will still cause failure during the beta cutoff week, see `checkregression.py` for that. check_dispatch $1 nightly miri src/tools/miri check_dispatch $1 nightly embedded-book src/doc/embedded-book } From 17c4084ebac2f5b4bd8c9b3900f492420844f3ca Mon Sep 17 00:00:00 2001 From: Who? Me?! Date: Thu, 18 Jul 2019 10:02:59 -0500 Subject: [PATCH 06/49] Update src/ci/docker/x86_64-gnu-tools/checkregression.py Co-Authored-By: Ralf Jung --- src/ci/docker/x86_64-gnu-tools/checkregression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index f8d9190a066a9..6bfdc9e8a14ed 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -4,7 +4,7 @@ import sys import json -# Regressions for these tools does not cause failure +# Regressions for these tools do not cause failure. REGRESSION_OK = ["rustc-guide", "miri"] if __name__ == '__main__': From 8940a27437f4243a27ff4def2de2590e901973b0 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 18 Jul 2019 10:24:20 -0500 Subject: [PATCH 07/49] embedded-book failures don't block beta --- src/ci/docker/x86_64-gnu-tools/checkregression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index 6bfdc9e8a14ed..081beb932b201 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -5,7 +5,7 @@ import json # Regressions for these tools do not cause failure. -REGRESSION_OK = ["rustc-guide", "miri"] +REGRESSION_OK = ["rustc-guide", "miri", "embedded-book"] if __name__ == '__main__': os_name = sys.argv[1] From 1aa10797df9ef70bd08011811d6a822a7b58e1a3 Mon Sep 17 00:00:00 2001 From: Who? Me?! Date: Thu, 18 Jul 2019 12:20:34 -0500 Subject: [PATCH 08/49] Update src/ci/docker/x86_64-gnu-tools/checkregression.py Co-Authored-By: kennytm --- src/ci/docker/x86_64-gnu-tools/checkregression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index 081beb932b201..72acb107405e5 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -35,7 +35,7 @@ 'The state of "{}" has {} from "{}" to "{}"' .format(tool, verb, state, new_state) ) - if tool not in REGRESSION_OK: + if not (verb == 'regressed' and tool in REGRESSION_OK): regressed = True if regressed: From 9c48ed4eab3d2f6050803479f76db0aafecdd7c7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 23 Jul 2019 10:34:19 +0200 Subject: [PATCH 09/49] more comments for toolstate scripts --- src/ci/docker/x86_64-gnu-tools/checkregression.py | 8 +++++++- src/ci/docker/x86_64-gnu-tools/checktools.sh | 9 +++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py index 72acb107405e5..4fbb8c4d20349 100755 --- a/src/ci/docker/x86_64-gnu-tools/checkregression.py +++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py @@ -1,10 +1,16 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +## This script has two purposes: detect any tool that *regressed*, which is used +## during the week before the beta branches to reject PRs; and detect any tool +## that *changed* to see if we need to update the toolstate repo. + import sys import json -# Regressions for these tools do not cause failure. +# Regressions for these tools during the beta cutoff week do not cause failure. +# See `status_check` in `checktools.sh` for tools that have to pass on the +# beta/stable branches. REGRESSION_OK = ["rustc-guide", "miri", "embedded-book"] if __name__ == '__main__': diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 8df63c214e189..db10c84a9977c 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -79,6 +79,9 @@ check_dispatch() { # List all tools here. # This function gets called with "submodule_changed" for each PR that changed a submodule, # and with "beta_required" for each PR that lands on beta/stable. +# The purpose of this function is to *reject* PRs if a tool is not "test-pass" and +# (a) the tool's submodule has been updated, or (b) we landed on beta/stable and the +# tool has to "test-pass" on that branch. status_check() { check_dispatch $1 beta book src/doc/book check_dispatch $1 beta nomicon src/doc/nomicon @@ -88,8 +91,10 @@ status_check() { check_dispatch $1 beta rls src/tools/rls check_dispatch $1 beta rustfmt src/tools/rustfmt check_dispatch $1 beta clippy-driver src/tools/clippy - # These tools are not required on the beta/stable branches. - # They will still cause failure during the beta cutoff week, see `checkregression.py` for that. + # These tools are not required on the beta/stable branches, but they *do* cause + # PRs to fail if a submodule update does not fix them. + # They will still cause failure during the beta cutoff week, unless `checkregression.py` + # exempts them from that. check_dispatch $1 nightly miri src/tools/miri check_dispatch $1 nightly embedded-book src/doc/embedded-book } From 92d432a0c710dfabf507de24ab95e491dc6a7449 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 23 Jul 2019 10:50:45 +0200 Subject: [PATCH 10/49] more callback docs --- src/ci/docker/x86_64-gnu-tools/repo.sh | 11 +++++++---- src/tools/publish_toolstate.py | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/repo.sh b/src/ci/docker/x86_64-gnu-tools/repo.sh index 35ab7e2b8c839..f06129551a464 100644 --- a/src/ci/docker/x86_64-gnu-tools/repo.sh +++ b/src/ci/docker/x86_64-gnu-tools/repo.sh @@ -62,10 +62,13 @@ commit_toolstate_change() { MESSAGE_FILE="$1" shift for RETRY_COUNT in 1 2 3 4 5; do - # Call the callback; this will in the end call `change_toolstate` from - # `checktools.sh` if we are in the `auto` branch (pre-landing) or - # `src/tools/publish_toolstate.py` if we are in the `master` branch - # (post-landing). + # Call the callback. + # - If we are in the `auto` branch (pre-landing), this is called from `checktools.sh` and + # the callback is `change_toolstate` in that file. The purpose of this is to publish the + # test results (the new commit-to-toolstate mapping) in the toolstate repo. + # - If we are in the `master` branch (post-landing), this is called by the CI pipeline + # and the callback is `src/tools/publish_toolstate.py`. The purpose is to publish + # the new "current" toolstate in the toolstate repo. "$@" # `git commit` failing means nothing to commit. FAILURE=0 diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 8f9061d7c1811..0f1ae5e0eb2ed 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +## This is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts +## when a new commit lands on `master` (i.e., after it passed all checks on `auto`). + import sys import re import os From 82d18412d1478a5c2db8bf6ed6c32e4b1c668dfe Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 23 Jul 2019 10:54:30 +0200 Subject: [PATCH 11/49] more comments --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 1 + src/tools/publish_toolstate.py | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index db10c84a9977c..e0de51e2cb0ab 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -112,6 +112,7 @@ change_toolstate() { echo 'Toolstate is not changed. Not updating.' else if [ $SIX_WEEK_CYCLE -ge 35 ]; then + # Reject any regressions during the week before beta cutoff. python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" regressed fi sed -i "1 a\\ diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 0f1ae5e0eb2ed..b8dcba3afc3a1 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -1,7 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -## This is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts +## This script publishes the new "current" toolstate in the toolstate repo (not to be +## confused with publishing the test results, which happens in +## `src/ci/docker/x86_64-gnu-tools/checktools.sh`). +## It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts ## when a new commit lands on `master` (i.e., after it passed all checks on `auto`). import sys From 11a3b742d8dfae9c9d4858adc5417918e13d84a5 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 23 Jul 2019 15:33:41 -0500 Subject: [PATCH 12/49] add back check for update prs --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index e0de51e2cb0ab..04fbe728debc6 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -97,6 +97,7 @@ status_check() { # exempts them from that. check_dispatch $1 nightly miri src/tools/miri check_dispatch $1 nightly embedded-book src/doc/embedded-book + check_dispatch $1 nightly rustc-guide src/doc/rustc-guide } # If this PR is intended to update one of these tools, do not let the build pass From c7a599e4df18acae8555a5b9940840349a555560 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Jul 2019 15:57:25 +0200 Subject: [PATCH 13/49] bump crossbeam-epoch dependency --- Cargo.lock | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bdc746c0bb0e0..d20a401496ff1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -589,7 +589,7 @@ name = "crossbeam-deque" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -609,15 +609,15 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1670,6 +1670,14 @@ name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "memoffset" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mime" version = "0.3.13" @@ -3329,6 +3337,11 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "security-framework" version = "0.3.1" @@ -4346,7 +4359,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f10a4f8f409aaac4b16a5474fb233624238fcdeefb9ba50d5ea059aab63ba31c" +"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" @@ -4456,6 +4469,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425" "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" "checksum minifier 0.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "4c909e78edf61f3aa0dd2086da168cdf304329044bbf248768ca3d20253ec8c0" @@ -4558,6 +4572,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" "checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" From a120caf8b4f8e77168378e6ad2b85d077baaa27b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 19 Jul 2019 07:08:37 -0700 Subject: [PATCH 14/49] rustc: Update wasm32 support for LLVM 9 This commit brings in a number of minor updates for rustc's support for the wasm target which has changed in the LLVM 9 update. Notable updates include: * The compiler now no longer manually inserts the `producers` section, instead relying on LLVM to do so. LLVM uses the `llvm.ident` metadata for the `processed-by` directive (which is now emitted on the wasm target in this PR) and it uses debuginfo to figure out what `language` to put in the `producers` section. * Threaded WebAssembly code now requires different flags to be passed with LLD. In LLD we now pass: * `--shared-memory` - required since objects are compiled with atomics. This also means that the generated memory will be marked as `shared`. * `--max-memory=1GB` - required with the `--shared-memory` argument since shared memories in WebAssembly must have a maximum size. The 1GB number is intended to be a conservative estimate for rustc, but it should be overridable with `-C link-arg` if necessary. * `--passive-segments` - this has become the default for multithreaded memory, but when compiling a threaded module all data segments need to be marked as passive to ensure they don't re-initialize memory for each thread. This will also cause LLD to emit a synthetic function to initialize memory which users will have to arrange to call. * The `__heap_base` and `__data_end` globals are explicitly exported since they're now hidden by default due to the `--export` flags we pass to LLD. --- .../debuginfo/metadata.rs | 22 +- src/librustc_codegen_ssa/back/link.rs | 8 - src/librustc_codegen_ssa/back/linker.rs | 40 +++- src/librustc_codegen_ssa/back/mod.rs | 1 - src/librustc_codegen_ssa/back/wasm.rs | 191 ------------------ 5 files changed, 59 insertions(+), 203 deletions(-) delete mode 100644 src/librustc_codegen_ssa/back/wasm.rs diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index fbeda43af42b0..f0bdb0018efe7 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -913,9 +913,12 @@ pub fn compile_unit_metadata( } debug!("compile_unit_metadata: {:?}", name_in_debuginfo); + let rustc_producer = format!( + "rustc version {}", + option_env!("CFG_VERSION").expect("CFG_VERSION"), + ); // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice. - let producer = format!("clang LLVM (rustc version {})", - (option_env!("CFG_VERSION")).expect("CFG_VERSION")); + let producer = format!("clang LLVM ({})", rustc_producer); let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo); @@ -980,6 +983,21 @@ pub fn compile_unit_metadata( gcov_metadata); } + // Insert `llvm.ident` metadata on the wasm32 targets since that will + // get hooked up to the "producer" sections `processed-by` information. + if tcx.sess.opts.target_triple.triple().starts_with("wasm32") { + let name_metadata = llvm::LLVMMDStringInContext( + debug_context.llcontext, + rustc_producer.as_ptr() as *const _, + rustc_producer.as_bytes().len() as c_uint, + ); + llvm::LLVMAddNamedMetadataOperand( + debug_context.llmod, + const_cstr!("llvm.ident").as_ptr(), + llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1), + ); + } + return unit_metadata; }; diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 707b7cae16ce7..3f6a1a72ea61e 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -678,14 +678,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, sess.fatal(&format!("failed to run dsymutil: {}", e)) } } - - if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" { - super::wasm::add_producer_section( - &out_filename, - &sess.edition().to_string(), - option_env!("CFG_VERSION").unwrap_or("unknown"), - ); - } } /// Returns a boolean indicating whether the specified crate should be ignored diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 882963f9174ec..94356468fb9d9 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -881,7 +881,38 @@ pub struct WasmLd<'a> { } impl<'a> WasmLd<'a> { - fn new(cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { + fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> { + // If the atomics feature is enabled for wasm then we need a whole bunch + // of flags: + // + // * `--shared-memory` - the link won't even succeed without this, flags + // the one linear memory as `shared` + // + // * `--max-memory=1G` - when specifying a shared memory this must also + // be specified. We conservatively choose 1GB but users should be able + // to override this with `-C link-arg`. + // + // * `--import-memory` - it doesn't make much sense for memory to be + // exported in a threaded module because typically you're + // sharing memory and instantiating the module multiple times. As a + // result if it were exported then we'd just have no sharing. + // + // * `--passive-segments` - all memory segments should be passive to + // prevent each module instantiation from reinitializing memory. + // + // * `--export=__wasm_init_memory` - when using `--passive-segments` the + // linker will synthesize this function, and so we need to make sure + // that our usage of `--export` below won't accidentally cause this + // function to get deleted. + let atomics = sess.opts.cg.target_feature.contains("+atomics") || + sess.target.target.options.features.contains("+atomics"); + if atomics { + cmd.arg("--shared-memory"); + cmd.arg("--max-memory=1073741824"); + cmd.arg("--import-memory"); + cmd.arg("--passive-segments"); + cmd.arg("--export=__wasm_init_memory"); + } WasmLd { cmd, sess, info } } } @@ -984,6 +1015,13 @@ impl<'a> Linker for WasmLd<'a> { for sym in self.info.exports[&crate_type].iter() { self.cmd.arg("--export").arg(&sym); } + + // LLD will hide these otherwise-internal symbols since our `--export` + // list above is a whitelist of what to export. Various bits and pieces + // of tooling use this, so be sure these symbols make their way out of + // the linker as well. + self.cmd.arg("--export=__heap_base"); + self.cmd.arg("--export=__data_end"); } fn subsystem(&mut self, _subsystem: &str) { diff --git a/src/librustc_codegen_ssa/back/mod.rs b/src/librustc_codegen_ssa/back/mod.rs index a16d099ee3e4d..901891d85a465 100644 --- a/src/librustc_codegen_ssa/back/mod.rs +++ b/src/librustc_codegen_ssa/back/mod.rs @@ -6,4 +6,3 @@ pub mod command; pub mod symbol_export; pub mod archive; pub mod rpath; -pub mod wasm; diff --git a/src/librustc_codegen_ssa/back/wasm.rs b/src/librustc_codegen_ssa/back/wasm.rs deleted file mode 100644 index 2a9e81a788e52..0000000000000 --- a/src/librustc_codegen_ssa/back/wasm.rs +++ /dev/null @@ -1,191 +0,0 @@ -use std::fs; -use std::path::Path; -use std::str; - -use rustc_serialize::leb128; - -// https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec -const WASM_CUSTOM_SECTION_ID: u8 = 0; - -/// Adds or augment the existing `producers` section to encode information about -/// the Rust compiler used to produce the wasm file. -pub fn add_producer_section( - path: &Path, - rust_version: &str, - rustc_version: &str, -) { - struct Field<'a> { - name: &'a str, - values: Vec>, - } - - #[derive(Copy, Clone)] - struct FieldValue<'a> { - name: &'a str, - version: &'a str, - } - - let wasm = fs::read(path).expect("failed to read wasm output"); - let mut ret = WasmEncoder::new(); - ret.data.extend(&wasm[..8]); - - // skip the 8 byte wasm/version header - let rustc_value = FieldValue { - name: "rustc", - version: rustc_version, - }; - let rust_value = FieldValue { - name: "Rust", - version: rust_version, - }; - let mut fields = Vec::new(); - let mut wrote_rustc = false; - let mut wrote_rust = false; - - // Move all sections from the original wasm file to our output, skipping - // everything except the producers section - for (id, raw) in WasmSections(WasmDecoder::new(&wasm[8..])) { - if id != WASM_CUSTOM_SECTION_ID { - ret.byte(id); - ret.bytes(raw); - continue - } - let mut decoder = WasmDecoder::new(raw); - if decoder.str() != "producers" { - ret.byte(id); - ret.bytes(raw); - continue - } - - // Read off the producers section into our fields outside the loop, - // we'll re-encode the producers section when we're done (to handle an - // entirely missing producers section as well). - info!("rewriting existing producers section"); - - for _ in 0..decoder.u32() { - let name = decoder.str(); - let mut values = Vec::new(); - for _ in 0..decoder.u32() { - let name = decoder.str(); - let version = decoder.str(); - values.push(FieldValue { name, version }); - } - - if name == "language" { - values.push(rust_value); - wrote_rust = true; - } else if name == "processed-by" { - values.push(rustc_value); - wrote_rustc = true; - } - fields.push(Field { name, values }); - } - } - - if !wrote_rust { - fields.push(Field { - name: "language", - values: vec![rust_value], - }); - } - if !wrote_rustc { - fields.push(Field { - name: "processed-by", - values: vec![rustc_value], - }); - } - - // Append the producers section to the end of the wasm file. - let mut section = WasmEncoder::new(); - section.str("producers"); - section.u32(fields.len() as u32); - for field in fields { - section.str(field.name); - section.u32(field.values.len() as u32); - for value in field.values { - section.str(value.name); - section.str(value.version); - } - } - ret.byte(WASM_CUSTOM_SECTION_ID); - ret.bytes(§ion.data); - - fs::write(path, &ret.data).expect("failed to write wasm output"); -} - -struct WasmSections<'a>(WasmDecoder<'a>); - -impl<'a> Iterator for WasmSections<'a> { - type Item = (u8, &'a [u8]); - - fn next(&mut self) -> Option<(u8, &'a [u8])> { - if self.0.data.is_empty() { - return None - } - - // see https://webassembly.github.io/spec/core/binary/modules.html#sections - let id = self.0.byte(); - let section_len = self.0.u32(); - info!("new section {} / {} bytes", id, section_len); - let section = self.0.skip(section_len as usize); - Some((id, section)) - } -} - -struct WasmDecoder<'a> { - data: &'a [u8], -} - -impl<'a> WasmDecoder<'a> { - fn new(data: &'a [u8]) -> WasmDecoder<'a> { - WasmDecoder { data } - } - - fn byte(&mut self) -> u8 { - self.skip(1)[0] - } - - fn u32(&mut self) -> u32 { - let (n, l1) = leb128::read_u32_leb128(self.data); - self.data = &self.data[l1..]; - return n - } - - fn skip(&mut self, amt: usize) -> &'a [u8] { - let (data, rest) = self.data.split_at(amt); - self.data = rest; - data - } - - fn str(&mut self) -> &'a str { - let len = self.u32(); - str::from_utf8(self.skip(len as usize)).unwrap() - } -} - -struct WasmEncoder { - data: Vec, -} - -impl WasmEncoder { - fn new() -> WasmEncoder { - WasmEncoder { data: Vec::new() } - } - - fn u32(&mut self, val: u32) { - leb128::write_u32_leb128(&mut self.data, val); - } - - fn byte(&mut self, val: u8) { - self.data.push(val); - } - - fn bytes(&mut self, val: &[u8]) { - self.u32(val.len() as u32); - self.data.extend_from_slice(val); - } - - fn str(&mut self, val: &str) { - self.bytes(val.as_bytes()) - } -} From dc50a633f3260a3aeb79a4ca9800587be7f732e7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 19 Jul 2019 12:02:34 -0700 Subject: [PATCH 15/49] std: Use native `#[thread_local]` TLS on wasm This commit moves `thread_local!` on WebAssembly targets to using the `#[thread_local]` attribute in LLVM. This was recently implemented upstream and is [in the process of being documented][dox]. This change only takes affect if modules are compiled with `+atomics` which is currently unstable and a pretty esoteric method of compiling wasm artifacts. This "new power" of the wasm toolchain means that the old `wasm-bindgen-threads` feature of the standard library can be removed since it should now be possible to create a fully functioning threaded wasm module without intrusively dealing with libstd symbols or intrinsics. Yay! [dox]: https://github.com/WebAssembly/tool-conventions/pull/116 --- src/librustc_codegen_ssa/back/linker.rs | 7 ++ src/librustc_target/spec/wasm32_base.rs | 8 +++ src/libstd/Cargo.toml | 5 -- src/libstd/sys/wasi/mod.rs | 2 + src/libstd/sys/wasm/fast_thread_local.rs | 9 +++ src/libstd/sys/wasm/mod.rs | 5 +- src/libstd/sys/wasm/thread.rs | 76 +++++++++------------ src/libstd/sys/wasm/thread_local.rs | 32 +++------ src/libstd/sys/wasm/thread_local_atomics.rs | 61 ----------------- src/llvm-project | 2 +- 10 files changed, 72 insertions(+), 135 deletions(-) create mode 100644 src/libstd/sys/wasm/fast_thread_local.rs delete mode 100644 src/libstd/sys/wasm/thread_local_atomics.rs diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 94356468fb9d9..5aa0e20d8308d 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -904,6 +904,9 @@ impl<'a> WasmLd<'a> { // linker will synthesize this function, and so we need to make sure // that our usage of `--export` below won't accidentally cause this // function to get deleted. + // + // * `--export=*tls*` - when `#[thread_local]` symbols are used these + // symbols are how the TLS segments are initialized and configured. let atomics = sess.opts.cg.target_feature.contains("+atomics") || sess.target.target.options.features.contains("+atomics"); if atomics { @@ -912,6 +915,10 @@ impl<'a> WasmLd<'a> { cmd.arg("--import-memory"); cmd.arg("--passive-segments"); cmd.arg("--export=__wasm_init_memory"); + cmd.arg("--export=__wasm_init_tls"); + cmd.arg("--export=__tls_size"); + cmd.arg("--export=__tls_align"); + cmd.arg("--export=__tls_base"); } WasmLd { cmd, sess, info } } diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs index 39a8ce9282573..6f00245b00941 100644 --- a/src/librustc_target/spec/wasm32_base.rs +++ b/src/librustc_target/spec/wasm32_base.rs @@ -132,6 +132,14 @@ pub fn options() -> TargetOptions { // non-relative calls and such later on). relocation_model: "static".to_string(), + // When the atomics feature is activated then these two keys matter, + // otherwise they're basically ignored by the standard library. In this + // mode, however, the `#[thread_local]` attribute works (i.e. + // `has_elf_tls`) and we need to get it to work by specifying + // `local-exec` as that's all that's implemented in LLVM today for wasm. + has_elf_tls: true, + tls_model: "local-exec".to_string(), + .. Default::default() } } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 6da77ab57d11e..2e0da0409eb09 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -75,11 +75,6 @@ panic_immediate_abort = ["core/panic_immediate_abort"] # requires rebuilding the standard library to use it. wasm_syscall = [] -# An off-by-default features to enable libstd to assume that wasm-bindgen is in -# the environment for hooking up some thread-related information like the -# current thread id and accessing/getting the current thread's TCB -wasm-bindgen-threads = [] - # Enable std_detect default features for stdarch/crates/std_detect: # https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml std_detect_file_io = [] diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index e22434439f5bb..f842869e08ee6 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -47,6 +47,8 @@ pub mod stdio; pub mod thread; #[path = "../wasm/thread_local.rs"] pub mod thread_local; +#[path = "../wasm/fast_thread_local.rs"] +pub mod fast_thread_local; pub mod time; pub mod ext; diff --git a/src/libstd/sys/wasm/fast_thread_local.rs b/src/libstd/sys/wasm/fast_thread_local.rs new file mode 100644 index 0000000000000..ff2198175f0a9 --- /dev/null +++ b/src/libstd/sys/wasm/fast_thread_local.rs @@ -0,0 +1,9 @@ +#![unstable(feature = "thread_local_internals", issue = "0")] + +pub unsafe fn register_dtor(_t: *mut u8, _dtor: unsafe extern fn(*mut u8)) { + // FIXME: right now there is no concept of "thread exit", but this is likely + // going to show up at some point in the form of an exported symbol that the + // wasm runtime is oging to be expected to call. For now we basically just + // ignore the arguments, but if such a function starts to exist it will + // likely look like the OSX implementation in `unix/fast_thread_local.rs` +} diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs index 7d157709eb6bf..56cbafcfdb8a2 100644 --- a/src/libstd/sys/wasm/mod.rs +++ b/src/libstd/sys/wasm/mod.rs @@ -37,6 +37,8 @@ pub mod stack_overflow; pub mod thread; pub mod time; pub mod stdio; +pub mod thread_local; +pub mod fast_thread_local; pub use crate::sys_common::os_str_bytes as os_str; @@ -48,13 +50,10 @@ cfg_if::cfg_if! { pub mod mutex; #[path = "rwlock_atomics.rs"] pub mod rwlock; - #[path = "thread_local_atomics.rs"] - pub mod thread_local; } else { pub mod condvar; pub mod mutex; pub mod rwlock; - pub mod thread_local; } } diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 61b4003cd3d14..d06965f327849 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -59,48 +59,40 @@ pub mod guard { pub unsafe fn init() -> Option { None } } -cfg_if::cfg_if! { - if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] { - #[link(wasm_import_module = "__wbindgen_thread_xform__")] - extern { - fn __wbindgen_current_id() -> u32; - fn __wbindgen_tcb_get() -> u32; - fn __wbindgen_tcb_set(ptr: u32); +// This is only used by atomics primitives when the `atomics` feature is +// enabled. In that mode we currently just use our own thread-local to store our +// current thread's ID, and then we lazily initialize it to something allocated +// from a global counter. +#[cfg(target_feature = "atomics")] +pub fn my_id() -> u32 { + use crate::sync::atomic::{AtomicU32, Ordering::SeqCst}; + + static NEXT_ID: AtomicU32 = AtomicU32::new(0); + + #[thread_local] + static mut MY_ID: u32 = 0; + + unsafe { + // If our thread ID isn't set yet then we need to allocate one. Do so + // with with a simple "atomically add to a global counter" strategy. + // This strategy doesn't handled what happens when the counter + // overflows, however, so just abort everything once the counter + // overflows and eventually we could have some sort of recycling scheme + // (or maybe this is all totally irrelevant by that point!). In any case + // though we're using a CAS loop instead of a `fetch_add` to ensure that + // the global counter never overflows. + if MY_ID == 0 { + let mut cur = NEXT_ID.load(SeqCst); + MY_ID = loop { + let next = cur.checked_add(1).unwrap_or_else(|| { + crate::arch::wasm32::unreachable() + }); + match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) { + Ok(_) => break next, + Err(i) => cur = i, + } + }; } - pub fn my_id() -> u32 { - unsafe { __wbindgen_current_id() } - } - - // These are currently only ever used in `thread_local_atomics.rs`, if - // you'd like to use them be sure to update that and make sure everyone - // agrees what's what. - pub fn tcb_get() -> *mut u8 { - use crate::mem; - assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::()); - unsafe { __wbindgen_tcb_get() as *mut u8 } - } - - pub fn tcb_set(ptr: *mut u8) { - unsafe { __wbindgen_tcb_set(ptr as u32); } - } - - // FIXME: still need something for hooking exiting a thread to free - // data... - - } else if #[cfg(target_feature = "atomics")] { - pub fn my_id() -> u32 { - panic!("thread ids not implemented on wasm with atomics yet") - } - - pub fn tcb_get() -> *mut u8 { - panic!("thread local data not implemented on wasm with atomics yet") - } - - pub fn tcb_set(_ptr: *mut u8) { - panic!("thread local data not implemented on wasm with atomics yet") - } - } else { - // stubbed out because no functions actually access these intrinsics - // unless atomics are enabled + MY_ID } } diff --git a/src/libstd/sys/wasm/thread_local.rs b/src/libstd/sys/wasm/thread_local.rs index 29e9854bcfccb..8a0ca6f3d25a8 100644 --- a/src/libstd/sys/wasm/thread_local.rs +++ b/src/libstd/sys/wasm/thread_local.rs @@ -1,40 +1,26 @@ -use crate::boxed::Box; -use crate::ptr; - pub type Key = usize; -struct Allocated { - value: *mut u8, - dtor: Option, -} - #[inline] -pub unsafe fn create(dtor: Option) -> Key { - Box::into_raw(Box::new(Allocated { - value: ptr::null_mut(), - dtor, - })) as usize +pub unsafe fn create(_dtor: Option) -> Key { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn set(key: Key, value: *mut u8) { - (*(key as *mut Allocated)).value = value; +pub unsafe fn set(_key: Key, _value: *mut u8) { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn get(key: Key) -> *mut u8 { - (*(key as *mut Allocated)).value +pub unsafe fn get(_key: Key) -> *mut u8 { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn destroy(key: Key) { - let key = Box::from_raw(key as *mut Allocated); - if let Some(f) = key.dtor { - f(key.value); - } +pub unsafe fn destroy(_key: Key) { + panic!("should not be used on the wasm target"); } #[inline] pub fn requires_synchronized_create() -> bool { - false + panic!("should not be used on the wasm target"); } diff --git a/src/libstd/sys/wasm/thread_local_atomics.rs b/src/libstd/sys/wasm/thread_local_atomics.rs deleted file mode 100644 index 3dc0bb24553fd..0000000000000 --- a/src/libstd/sys/wasm/thread_local_atomics.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::sys::thread; -use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; - -const MAX_KEYS: usize = 128; -static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); - -struct ThreadControlBlock { - keys: [*mut u8; MAX_KEYS], -} - -impl ThreadControlBlock { - fn new() -> ThreadControlBlock { - ThreadControlBlock { - keys: [core::ptr::null_mut(); MAX_KEYS], - } - } - - fn get() -> *mut ThreadControlBlock { - let ptr = thread::tcb_get(); - if !ptr.is_null() { - return ptr as *mut ThreadControlBlock - } - let tcb = Box::into_raw(Box::new(ThreadControlBlock::new())); - thread::tcb_set(tcb as *mut u8); - tcb - } -} - -pub type Key = usize; - -pub unsafe fn create(dtor: Option) -> Key { - drop(dtor); // FIXME: need to figure out how to hook thread exit to run this - let key = NEXT_KEY.fetch_add(1, SeqCst); - if key >= MAX_KEYS { - NEXT_KEY.store(MAX_KEYS, SeqCst); - panic!("cannot allocate space for more TLS keys"); - } - // offset by 1 so we never hand out 0. This is currently required by - // `sys_common/thread_local.rs` where it can't cope with keys of value 0 - // because it messes up the atomic management. - return key + 1 -} - -pub unsafe fn set(key: Key, value: *mut u8) { - (*ThreadControlBlock::get()).keys[key - 1] = value; -} - -pub unsafe fn get(key: Key) -> *mut u8 { - (*ThreadControlBlock::get()).keys[key - 1] -} - -pub unsafe fn destroy(_key: Key) { - // FIXME: should implement this somehow, this isn't typically called but it - // can be called if two threads race to initialize a TLS slot and one ends - // up not being needed. -} - -#[inline] -pub fn requires_synchronized_create() -> bool { - false -} diff --git a/src/llvm-project b/src/llvm-project index f6446fa8e9629..9b64ca5b7e1e3 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit f6446fa8e9629ffb1861303f17930c3aa83ef660 +Subproject commit 9b64ca5b7e1e3583978f9ac8af6d93b220a13d90 From f7c75cc11ac56535e3956a50a024296f94a67b8b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 7 Jul 2019 00:26:55 +0200 Subject: [PATCH 16/49] Add 'ast::PatKind::Rest'. --- src/librustc/hir/lowering.rs | 17 +++++++++++++++++ src/libsyntax/ast.rs | 15 +++++++++++++++ src/libsyntax/mut_visit.rs | 2 +- src/libsyntax/print/pprust.rs | 1 + src/libsyntax/visit.rs | 2 +- 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 639994ed14d86..d9848c49773e2 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4264,6 +4264,10 @@ impl<'a> LoweringContext<'a> { slice.as_ref().map(|x| self.lower_pat(x)), after.iter().map(|x| self.lower_pat(x)).collect(), ), + PatKind::Rest => { + // If we reach here the `..` pattern is not semantically allowed. + self.ban_illegal_rest_pat(p.span) + } PatKind::Paren(ref inner) => return self.lower_pat(inner), PatKind::Mac(_) => panic!("Shouldn't exist here"), }; @@ -4275,6 +4279,19 @@ impl<'a> LoweringContext<'a> { }) } + /// Used to ban the `..` pattern in places it shouldn't be semantically. + fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind { + self.diagnostic() + .struct_span_err(sp, "`..` patterns are not allowed here") + .note("only allowed in tuple, tuple struct, and slice patterns") + .emit(); + + // We're not in a list context so `..` can be reasonably treated + // as `_` because it should always be valid and roughly matches the + // intent of `..` (notice that the rest of a single slot is that slot). + hir::PatKind::Wild + } + fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd { match *e { RangeEnd::Included(_) => hir::RangeEnd::Included, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index dbfad3ef7f4de..37889c4918ba9 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -572,6 +572,7 @@ impl Pat { && after.iter().all(|p| p.walk(it)) } PatKind::Wild + | PatKind::Rest | PatKind::Lit(_) | PatKind::Range(..) | PatKind::Ident(..) @@ -661,6 +662,20 @@ pub enum PatKind { /// `PatKind::Slice(box [a, b], Some(i), box [y, z])` Slice(Vec>, Option>, Vec>), + /// A rest pattern `..`. + /// + /// Syntactically it is valid anywhere. + /// + /// Semantically however, it only has meaning immediately inside: + /// - a slice pattern: `[a, .., b]`, + /// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`, + /// - a tuple pattern: `(a, .., b)`, + /// - a tuple struct/variant pattern: `$path(a, .., b)`. + /// + /// In all of these cases, an additional restriction applies, + /// only one rest pattern may occur in the pattern sequences. + Rest, + /// Parentheses in patterns used for grouping (i.e., `(PAT)`). Paren(P), diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index dc656222fbc10..eb25956a7699f 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -1020,7 +1020,7 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { let Pat { id, node, span } = pat.deref_mut(); vis.visit_id(id); match node { - PatKind::Wild => {} + PatKind::Wild | PatKind::Rest => {} PatKind::Ident(_binding_mode, ident, sub) => { vis.visit_ident(ident); visit_opt(sub, |sub| vis.visit_pat(sub)); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 16e0bace92584..a067ae0e91889 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2478,6 +2478,7 @@ impl<'a> State<'a> { |s, p| s.print_pat(p)); self.s.word("]"); } + PatKind::Rest => self.s.word(".."), PatKind::Paren(ref inner) => { self.popen(); self.print_pat(inner); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9ec9550f93ab9..7c814bf3397f3 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -463,7 +463,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { visitor.visit_expr(lower_bound); visitor.visit_expr(upper_bound); } - PatKind::Wild => (), + PatKind::Wild | PatKind::Rest => {}, PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => { walk_list!(visitor, visit_pat, prepatterns); walk_list!(visitor, visit_pat, slice_pattern); From ff77ef2d704658a90493dc8210f52f88697ee326 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 09:26:11 +0200 Subject: [PATCH 17/49] Introduce 'ast::Pat::is_rest(&self) -> bool'. --- src/libsyntax/ast.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 37889c4918ba9..61a6c199701a8 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -580,6 +580,14 @@ impl Pat { | PatKind::Mac(_) => true, } } + + /// Is this a `..` pattern? + pub fn is_rest(&self) -> bool { + match self.node { + PatKind::Rest => true, + _ => false, + } + } } /// A single field in a struct pattern From 633c9972ac3b3e10e8f5752cb1427eabccfb3074 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 09:25:18 +0200 Subject: [PATCH 18/49] Adjust 'ast::PatKind::{TupleStruct,Tuple,Slice}'. --- src/libsyntax/ast.rs | 28 +++++++++------------------- src/libsyntax/ext/build.rs | 4 ++-- src/libsyntax/mut_visit.rs | 12 ++++-------- src/libsyntax/visit.rs | 14 ++++++-------- 4 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 61a6c199701a8..a49b6f7e2a631 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -559,18 +559,13 @@ impl Pat { return false; } - match self.node { - PatKind::Ident(_, _, Some(ref p)) => p.walk(it), - PatKind::Struct(_, ref fields, _) => fields.iter().all(|field| field.node.pat.walk(it)), - PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => { + match &self.node { + PatKind::Ident(_, _, Some(p)) => p.walk(it), + PatKind::Struct(_, fields, _) => fields.iter().all(|field| field.node.pat.walk(it)), + PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) => { s.iter().all(|p| p.walk(it)) } - PatKind::Box(ref s) | PatKind::Ref(ref s, _) | PatKind::Paren(ref s) => s.walk(it), - PatKind::Slice(ref before, ref slice, ref after) => { - before.iter().all(|p| p.walk(it)) - && slice.iter().all(|p| p.walk(it)) - && after.iter().all(|p| p.walk(it)) - } + PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it), PatKind::Wild | PatKind::Rest | PatKind::Lit(_) @@ -639,9 +634,7 @@ pub enum PatKind { Struct(Path, Vec>, /* recovered */ bool), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). - /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// `0 <= position <= subpats.len()`. - TupleStruct(Path, Vec>, Option), + TupleStruct(Path, Vec>), /// A possibly qualified path pattern. /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants @@ -650,9 +643,7 @@ pub enum PatKind { Path(Option, Path), /// A tuple pattern (`(a, b)`). - /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// `0 <= position <= subpats.len()`. - Tuple(Vec>, Option), + Tuple(Vec>), /// A `box` pattern. Box(P), @@ -666,9 +657,8 @@ pub enum PatKind { /// A range pattern (e.g., `1...2`, `1..=2` or `1..2`). Range(P, P, Spanned), - /// `[a, b, ..i, y, z]` is represented as: - /// `PatKind::Slice(box [a, b], Some(i), box [y, z])` - Slice(Vec>, Option>, Vec>), + /// A slice pattern `[a, b, c]`. + Slice(Vec>), /// A rest pattern `..`. /// diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index baf1031de1e7c..528b27d6153df 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -840,14 +840,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn pat_tuple_struct(&self, span: Span, path: ast::Path, subpats: Vec>) -> P { - self.pat(span, PatKind::TupleStruct(path, subpats, None)) + self.pat(span, PatKind::TupleStruct(path, subpats)) } fn pat_struct(&self, span: Span, path: ast::Path, field_pats: Vec>) -> P { self.pat(span, PatKind::Struct(path, field_pats, false)) } fn pat_tuple(&self, span: Span, pats: Vec>) -> P { - self.pat(span, PatKind::Tuple(pats, None)) + self.pat(span, PatKind::Tuple(pats)) } fn pat_some(&self, span: Span, pat: P) -> P { diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index eb25956a7699f..86525406718b6 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -1026,9 +1026,9 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { visit_opt(sub, |sub| vis.visit_pat(sub)); } PatKind::Lit(e) => vis.visit_expr(e), - PatKind::TupleStruct(path, pats, _ddpos) => { + PatKind::TupleStruct(path, elems) => { vis.visit_path(path); - visit_vec(pats, |pat| vis.visit_pat(pat)); + visit_vec(elems, |elem| vis.visit_pat(elem)); } PatKind::Path(qself, path) => { vis.visit_qself(qself); @@ -1043,7 +1043,7 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { vis.visit_span(span); }; } - PatKind::Tuple(elts, _ddpos) => visit_vec(elts, |elt| vis.visit_pat(elt)), + PatKind::Tuple(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)), PatKind::Box(inner) => vis.visit_pat(inner), PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { @@ -1051,11 +1051,7 @@ pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { vis.visit_expr(e2); vis.visit_span(span); } - PatKind::Slice(before, slice, after) => { - visit_vec(before, |pat| vis.visit_pat(pat)); - visit_opt(slice, |slice| vis.visit_pat(slice)); - visit_vec(after, |pat| vis.visit_pat(pat)); - } + PatKind::Slice(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)), PatKind::Paren(inner) => vis.visit_pat(inner), PatKind::Mac(mac) => vis.visit_mac(mac), } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 7c814bf3397f3..ff6440fb9dceb 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -428,9 +428,9 @@ pub fn walk_assoc_ty_constraint<'a, V: Visitor<'a>>(visitor: &mut V, pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { match pattern.node { - PatKind::TupleStruct(ref path, ref children, _) => { + PatKind::TupleStruct(ref path, ref elems) => { visitor.visit_path(path, pattern.id); - walk_list!(visitor, visit_pat, children); + walk_list!(visitor, visit_pat, elems); } PatKind::Path(ref opt_qself, ref path) => { if let Some(ref qself) = *opt_qself { @@ -446,8 +446,8 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { visitor.visit_pat(&field.node.pat) } } - PatKind::Tuple(ref tuple_elements, _) => { - walk_list!(visitor, visit_pat, tuple_elements); + PatKind::Tuple(ref elems) => { + walk_list!(visitor, visit_pat, elems); } PatKind::Box(ref subpattern) | PatKind::Ref(ref subpattern, _) | @@ -464,10 +464,8 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { visitor.visit_expr(upper_bound); } PatKind::Wild | PatKind::Rest => {}, - PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => { - walk_list!(visitor, visit_pat, prepatterns); - walk_list!(visitor, visit_pat, slice_pattern); - walk_list!(visitor, visit_pat, postpatterns); + PatKind::Slice(ref elems) => { + walk_list!(visitor, visit_pat, elems); } PatKind::Mac(ref mac) => visitor.visit_mac(mac), } From 12250a2017b1a9837f918905e870761a0a03bfaf Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 09:12:49 +0200 Subject: [PATCH 19/49] Adjust feature gating of subslice patterns accordingly. --- src/libsyntax/feature_gate.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 72184b0bd6400..384474b08f6ee 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -2151,11 +2151,23 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_pat(&mut self, pattern: &'a ast::Pat) { - match pattern.node { - PatKind::Slice(_, Some(ref subslice), _) => { - gate_feature_post!(&self, slice_patterns, - subslice.span, - "syntax for subslices in slice patterns is not yet stabilized"); + match &pattern.node { + PatKind::Slice(pats) => { + for pat in &*pats { + let span = pat.span; + let inner_pat = match &pat.node { + PatKind::Ident(.., Some(pat)) => pat, + _ => pat, + }; + if inner_pat.is_rest() { + gate_feature_post!( + &self, + slice_patterns, + span, + "subslice patterns are unstable" + ); + } + } } PatKind::Box(..) => { gate_feature_post!(&self, box_patterns, From b02941f2a679381d15a7c735d0c644935c9a62b0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 09:12:14 +0200 Subject: [PATCH 20/49] Adjust pretty printing accordingly. --- src/libsyntax/print/pprust.rs | 55 +++++------------------------------ 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a067ae0e91889..36cd656f7277e 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2369,22 +2369,10 @@ impl<'a> State<'a> { self.print_pat(p); } } - PatKind::TupleStruct(ref path, ref elts, ddpos) => { + PatKind::TupleStruct(ref path, ref elts) => { self.print_path(path, true, 0); self.popen(); - if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p)); - if ddpos != 0 { - self.word_space(","); - } - self.s.word(".."); - if ddpos != elts.len() { - self.s.word(","); - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p)); - } - } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); - } + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); self.pclose(); } PatKind::Path(None, ref path) => { @@ -2416,23 +2404,11 @@ impl<'a> State<'a> { self.s.space(); self.s.word("}"); } - PatKind::Tuple(ref elts, ddpos) => { + PatKind::Tuple(ref elts) => { self.popen(); - if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p)); - if ddpos != 0 { - self.word_space(","); - } - self.s.word(".."); - if ddpos != elts.len() { - self.s.word(","); - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p)); - } - } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); - if elts.len() == 1 { - self.s.word(","); - } + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); + if elts.len() == 1 { + self.s.word(","); } self.pclose(); } @@ -2458,24 +2434,9 @@ impl<'a> State<'a> { } self.print_expr(end); } - PatKind::Slice(ref before, ref slice, ref after) => { + PatKind::Slice(ref elts) => { self.s.word("["); - self.commasep(Inconsistent, - &before[..], - |s, p| s.print_pat(p)); - if let Some(ref p) = *slice { - if !before.is_empty() { self.word_space(","); } - if let PatKind::Wild = p.node { - // Print nothing - } else { - self.print_pat(p); - } - self.s.word(".."); - if !after.is_empty() { self.word_space(","); } - } - self.commasep(Inconsistent, - &after[..], - |s, p| s.print_pat(p)); + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); self.s.word("]"); } PatKind::Rest => self.s.word(".."), From 8ba5f49f6fad86b813c2b086538586c93127bfff Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 09:23:51 +0200 Subject: [PATCH 21/49] Adjust and document 'Pat::to_ty' accordingly. --- src/libsyntax/ast.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a49b6f7e2a631..a7453f4f9dac2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -519,21 +519,28 @@ impl fmt::Debug for Pat { } impl Pat { + /// Attempt reparsing the pattern as a type. + /// This is intended for use by diagnostics. pub(super) fn to_ty(&self) -> Option> { let node = match &self.node { + // In a type expression `_` is an inference variable. PatKind::Wild => TyKind::Infer, + // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`. PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None) => { TyKind::Path(None, Path::from_ident(*ident)) } PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), PatKind::Mac(mac) => TyKind::Mac(mac.clone()), + // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type. PatKind::Ref(pat, mutbl) => pat .to_ty() .map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?, - PatKind::Slice(pats, None, _) if pats.len() == 1 => { - pats[0].to_ty().map(TyKind::Slice)? - } - PatKind::Tuple(pats, None) => { + // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array, + // when `P` can be reparsed as a type `T`. + PatKind::Slice(pats) if pats.len() == 1 => pats[0].to_ty().map(TyKind::Slice)?, + // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)` + // assuming `T0` to `Tn` are all syntactically valid as types. + PatKind::Tuple(pats) => { let mut tys = Vec::with_capacity(pats.len()); // FIXME(#48994) - could just be collected into an Option for pat in pats { From d5df1e0b0f99e7dad81c573cc2beb03d3023d433 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 10:11:21 +0200 Subject: [PATCH 22/49] Adjust lowering of Tuple/TupleStruct patterns. - Make sure we ban duplicate '..'. - Avoid ICEs on PatKind::Rest that doesn't generate HIR nodes. --- src/librustc/hir/lowering.rs | 57 ++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d9848c49773e2..b552047f59e1d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -58,6 +58,7 @@ use std::mem; use smallvec::SmallVec; use syntax::attr; use syntax::ast; +use syntax::ptr::P as AstP; use syntax::ast::*; use syntax::errors; use syntax::ext::hygiene::ExpnId; @@ -468,7 +469,7 @@ impl<'a> LoweringContext<'a> { fn visit_pat(&mut self, p: &'tcx Pat) { match p.node { // Doesn't generate a HIR node - PatKind::Paren(..) => {}, + PatKind::Paren(..) | PatKind::Rest => {}, _ => { if let Some(owner) = self.hir_id_owner { self.lctx.lower_node_id_with_owner(p.id, owner); @@ -4198,7 +4199,7 @@ impl<'a> LoweringContext<'a> { } } PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))), - PatKind::TupleStruct(ref path, ref pats, ddpos) => { + PatKind::TupleStruct(ref path, ref pats) => { let qpath = self.lower_qpath( p.id, &None, @@ -4206,11 +4207,8 @@ impl<'a> LoweringContext<'a> { ParamMode::Optional, ImplTraitContext::disallowed(), ); - hir::PatKind::TupleStruct( - qpath, - pats.iter().map(|x| self.lower_pat(x)).collect(), - ddpos, - ) + let (pats, ddpos) = self.lower_pat_tuple(&*pats, "tuple struct"); + hir::PatKind::TupleStruct(qpath, pats, ddpos) } PatKind::Path(ref qself, ref path) => { let qpath = self.lower_qpath( @@ -4247,8 +4245,9 @@ impl<'a> LoweringContext<'a> { .collect(); hir::PatKind::Struct(qpath, fs, etc) } - PatKind::Tuple(ref elts, ddpos) => { - hir::PatKind::Tuple(elts.iter().map(|x| self.lower_pat(x)).collect(), ddpos) + PatKind::Tuple(ref pats) => { + let (pats, ddpos) = self.lower_pat_tuple(&*pats, "tuple"); + hir::PatKind::Tuple(pats, ddpos) } PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), PatKind::Ref(ref inner, mutbl) => { @@ -4279,6 +4278,46 @@ impl<'a> LoweringContext<'a> { }) } + fn lower_pat_tuple( + &mut self, + pats: &[AstP], + ctx: &str, + ) -> (HirVec>, Option) { + let mut elems = Vec::with_capacity(pats.len()); + let mut rest = None; + + let mut iter = pats.iter().enumerate(); + while let Some((idx, pat)) = iter.next() { + // Interpret the first `..` pattern as a subtuple pattern. + if pat.is_rest() { + rest = Some((idx, pat.span)); + break; + } + // It was not a subslice pattern so lower it normally. + elems.push(self.lower_pat(pat)); + } + + while let Some((_, pat)) = iter.next() { + // There was a previous subtuple pattern; make sure we don't allow more. + if pat.is_rest() { + self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx); + } else { + elems.push(self.lower_pat(pat)); + } + } + + (elems.into(), rest.map(|(ddpos, _)| ddpos)) + } + + /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. + fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { + self.diagnostic() + .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx)) + .span_label(sp, &format!("can only be used once per {} pattern", ctx)) + .span_label(prev_sp, "previously used here") + .emit(); + } + /// Used to ban the `..` pattern in places it shouldn't be semantically. fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind { self.diagnostic() From 694b3c3ef2c7322c2d490ac4896b74ac7b877cc8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 10:03:30 +0200 Subject: [PATCH 23/49] Adjust lowering of Slice patterns. - Make sure extra `x @ ..` do not cause ICEs. --- src/librustc/hir/lowering.rs | 134 ++++++++++++++++++++++++++--------- 1 file changed, 100 insertions(+), 34 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b552047f59e1d..094a509a18d69 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4173,30 +4173,8 @@ impl<'a> LoweringContext<'a> { let node = match p.node { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, ident, ref sub) => { - match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) { - // `None` can occur in body-less function signatures - res @ None | res @ Some(Res::Local(_)) => { - let canonical_id = match res { - Some(Res::Local(id)) => id, - _ => p.id, - }; - - hir::PatKind::Binding( - self.lower_binding_mode(binding_mode), - self.lower_node_id(canonical_id), - ident, - sub.as_ref().map(|x| self.lower_pat(x)), - ) - } - Some(res) => hir::PatKind::Path(hir::QPath::Resolved( - None, - P(hir::Path { - span: ident.span, - res: self.lower_res(res), - segments: hir_vec![hir::PathSegment::from_ident(ident)], - }), - )), - } + let lower_sub = |this: &mut Self| sub.as_ref().map(|x| this.lower_pat(x)); + self.lower_pat_ident(p, binding_mode, ident, lower_sub) } PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))), PatKind::TupleStruct(ref path, ref pats) => { @@ -4258,11 +4236,7 @@ impl<'a> LoweringContext<'a> { P(self.lower_expr(e2)), self.lower_range_end(end), ), - PatKind::Slice(ref before, ref slice, ref after) => hir::PatKind::Slice( - before.iter().map(|x| self.lower_pat(x)).collect(), - slice.as_ref().map(|x| self.lower_pat(x)), - after.iter().map(|x| self.lower_pat(x)).collect(), - ), + PatKind::Slice(ref pats) => self.lower_pat_slice(pats), PatKind::Rest => { // If we reach here the `..` pattern is not semantically allowed. self.ban_illegal_rest_pat(p.span) @@ -4271,11 +4245,7 @@ impl<'a> LoweringContext<'a> { PatKind::Mac(_) => panic!("Shouldn't exist here"), }; - P(hir::Pat { - hir_id: self.lower_node_id(p.id), - node, - span: p.span, - }) + self.pat_bound(p, node) } fn lower_pat_tuple( @@ -4309,6 +4279,102 @@ impl<'a> LoweringContext<'a> { (elems.into(), rest.map(|(ddpos, _)| ddpos)) } + fn lower_pat_slice(&mut self, pats: &[AstP]) -> hir::PatKind { + let mut before = Vec::new(); + let mut after = Vec::new(); + let mut slice = None; + let mut prev_rest_span = None; + + let mut iter = pats.iter(); + while let Some(pat) = iter.next() { + // Interpret the first `((ref mut?)? x @)? ..` pattern as a subslice pattern. + match pat.node { + PatKind::Rest => { + prev_rest_span = Some(pat.span); + slice = Some(self.pat_bound_wild(pat)); + break; + }, + PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { + prev_rest_span = Some(sub.span); + let lower_sub = |this: &mut Self| Some(this.pat_bound_wild(sub)); + let node = self.lower_pat_ident(pat, bm, ident, lower_sub); + slice = Some(self.pat_bound(pat, node)); + break; + }, + _ => {} + } + + // It was not a subslice pattern so lower it normally. + before.push(self.lower_pat(pat)); + } + + while let Some(pat) = iter.next() { + // There was a previous subslice pattern; make sure we don't allow more. + let rest_span = match pat.node { + PatKind::Rest => Some(pat.span), + PatKind::Ident(.., Some(ref sub)) if sub.is_rest() => { + // The `HirValidator` is merciless; add a `_` pattern to avoid ICEs. + after.push(self.pat_bound_wild(pat)); + Some(sub.span) + }, + _ => None, + }; + if let Some(rest_span) = rest_span { + self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice"); + } else { + after.push(self.lower_pat(pat)); + } + } + + hir::PatKind::Slice(before.into(), slice, after.into()) + } + + fn lower_pat_ident( + &mut self, + p: &Pat, + binding_mode: &BindingMode, + ident: Ident, + lower_sub: impl FnOnce(&mut Self) -> Option>, + ) -> hir::PatKind { + match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) { + // `None` can occur in body-less function signatures + res @ None | res @ Some(Res::Local(_)) => { + let canonical_id = match res { + Some(Res::Local(id)) => id, + _ => p.id, + }; + + hir::PatKind::Binding( + self.lower_binding_mode(binding_mode), + self.lower_node_id(canonical_id), + ident, + lower_sub(self), + ) + } + Some(res) => hir::PatKind::Path(hir::QPath::Resolved( + None, + P(hir::Path { + span: ident.span, + res: self.lower_res(res), + segments: hir_vec![hir::PathSegment::from_ident(ident)], + }), + )), + } + } + + fn pat_bound_wild(&mut self, p: &Pat) -> P { + self.pat_bound(p, hir::PatKind::Wild) + } + + /// Construct a `Pat` with the `HirId` of `p.id` lowered. + fn pat_bound(&mut self, p: &Pat, node: hir::PatKind) -> P { + P(hir::Pat { + hir_id: self.lower_node_id(p.id), + node, + span: p.span, + }) + } + /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { self.diagnostic() From 0a40ef23ad2a1630cdc226a71bf62bb51d6a0588 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 10:27:07 +0200 Subject: [PATCH 24/49] Cleanup parse_seq_* methods + record trailing separators. --- src/libsyntax/parse/parser.rs | 77 ++++++++++++++++------------------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a5b6f0d683629..ca066269f784b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -890,14 +890,13 @@ impl<'a> Parser<'a> { /// Parses a sequence, including the closing delimiter. The function /// `f` must consume tokens until reaching the next separator or /// closing bracket. - pub fn parse_seq_to_end(&mut self, - ket: &TokenKind, - sep: SeqSep, - f: F) - -> PResult<'a, Vec> where - F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, - { - let (val, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; + pub fn parse_seq_to_end( + &mut self, + ket: &TokenKind, + sep: SeqSep, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, Vec> { + let (val, _, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; if !recovered { self.bump(); } @@ -907,39 +906,39 @@ impl<'a> Parser<'a> { /// Parses a sequence, not including the closing delimiter. The function /// `f` must consume tokens until reaching the next separator or /// closing bracket. - pub fn parse_seq_to_before_end( + pub fn parse_seq_to_before_end( &mut self, ket: &TokenKind, sep: SeqSep, - f: F, - ) -> PResult<'a, (Vec, bool)> - where F: FnMut(&mut Parser<'a>) -> PResult<'a, T> - { + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool, bool)> { self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f) } - crate fn parse_seq_to_before_tokens( + fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType) -> bool { + kets.iter().any(|k| { + match expect { + TokenExpectType::Expect => self.check(k), + TokenExpectType::NoExpect => self.token == **k, + } + }) + } + + crate fn parse_seq_to_before_tokens( &mut self, kets: &[&TokenKind], sep: SeqSep, expect: TokenExpectType, - mut f: F, - ) -> PResult<'a, (Vec, bool /* recovered */)> - where F: FnMut(&mut Parser<'a>) -> PResult<'a, T> - { + mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool /* trailing */, bool /* recovered */)> { let mut first = true; let mut recovered = false; + let mut trailing = false; let mut v = vec![]; - while !kets.iter().any(|k| { - match expect { - TokenExpectType::Expect => self.check(k), - TokenExpectType::NoExpect => self.token == **k, - } - }) { - match self.token.kind { - token::CloseDelim(..) | token::Eof => break, - _ => {} - }; + while !self.expect_any_with_type(kets, expect) { + if let token::CloseDelim(..) | token::Eof = self.token.kind { + break + } if let Some(ref t) = sep.sep { if first { first = false; @@ -973,12 +972,8 @@ impl<'a> Parser<'a> { } } } - if sep.trailing_sep_allowed && kets.iter().any(|k| { - match expect { - TokenExpectType::Expect => self.check(k), - TokenExpectType::NoExpect => self.token == **k, - } - }) { + if sep.trailing_sep_allowed && self.expect_any_with_type(kets, expect) { + trailing = true; break; } @@ -986,27 +981,25 @@ impl<'a> Parser<'a> { v.push(t); } - Ok((v, recovered)) + Ok((v, trailing, recovered)) } /// Parses a sequence, including the closing delimiter. The function /// `f` must consume tokens until reaching the next separator or /// closing bracket. - fn parse_unspanned_seq( + fn parse_unspanned_seq( &mut self, bra: &TokenKind, ket: &TokenKind, sep: SeqSep, - f: F, - ) -> PResult<'a, Vec> where - F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, - { + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool)> { self.expect(bra)?; - let (result, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; + let (result, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; if !recovered { self.eat(ket); } - Ok(result) + Ok((result, trailing)) } /// Advance the parser by one token From 7aeb4b732796449237d3098f5cbe44f468fe6ef1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 10:31:24 +0200 Subject: [PATCH 25/49] Add more parse_*_seq methods for code reuse. --- src/libsyntax/parse/parser.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ca066269f784b..27bf9917917c9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1002,6 +1002,26 @@ impl<'a> Parser<'a> { Ok((result, trailing)) } + fn parse_delim_comma_seq( + &mut self, + delim: DelimToken, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool)> { + self.parse_unspanned_seq( + &token::OpenDelim(delim), + &token::CloseDelim(delim), + SeqSep::trailing_allowed(token::Comma), + f, + ) + } + + fn parse_paren_comma_seq( + &mut self, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, bool)> { + self.parse_delim_comma_seq(token::Paren, f) + } + /// Advance the parser by one token pub fn bump(&mut self) { if self.prev_token_kind == PrevTokenKind::Eof { @@ -2628,6 +2648,10 @@ impl<'a> Parser<'a> { return Ok(e); } + fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec>> { + self.parse_paren_comma_seq(|p| p.parse_expr()).map(|(r, _)| r) + } + crate fn process_potential_macro_variable(&mut self) { self.token = match self.token.kind { token::Dollar if self.token.span.ctxt() != SyntaxContext::empty() && From 7e1b671f8ac935eeda9cf2c111c7c4eacc31e130 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 10:34:53 +0200 Subject: [PATCH 26/49] Cleanup using the new parse_*_seq methods. --- src/libsyntax/parse/parser.rs | 156 +++++++++++++--------------------- 1 file changed, 60 insertions(+), 96 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 27bf9917917c9..ec55c52745327 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1817,15 +1817,7 @@ impl<'a> Parser<'a> { AngleBracketedArgs { args, constraints, span }.into() } else { // `(T, U) -> R` - self.bump(); // `(` - let (inputs, recovered) = self.parse_seq_to_before_tokens( - &[&token::CloseDelim(token::Paren)], - SeqSep::trailing_allowed(token::Comma), - TokenExpectType::Expect, - |p| p.parse_ty())?; - if !recovered { - self.bump(); // `)` - } + let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; let span = lo.to(self.prev_span); let output = if self.eat(&token::RArrow) { Some(self.parse_ty_common(false, false, false)?) @@ -2529,12 +2521,7 @@ impl<'a> Parser<'a> { Ok(match self.token.kind { token::OpenDelim(token::Paren) => { // Method call `expr.f()` - let mut args = self.parse_unspanned_seq( - &token::OpenDelim(token::Paren), - &token::CloseDelim(token::Paren), - SeqSep::trailing_allowed(token::Comma), - |p| Ok(p.parse_expr()?) - )?; + let mut args = self.parse_paren_expr_seq()?; args.insert(0, self_arg); let span = lo.to(self.prev_span); @@ -2619,12 +2606,7 @@ impl<'a> Parser<'a> { match self.token.kind { // expr(...) token::OpenDelim(token::Paren) => { - let seq = self.parse_unspanned_seq( - &token::OpenDelim(token::Paren), - &token::CloseDelim(token::Paren), - SeqSep::trailing_allowed(token::Comma), - |p| Ok(p.parse_expr()?) - ).map(|es| { + let seq = self.parse_paren_expr_seq().map(|es| { let nd = self.mk_call(e, es); let hi = self.prev_span; self.mk_expr(lo.to(hi), nd, ThinVec::new()) @@ -5376,59 +5358,48 @@ impl<'a> Parser<'a> { fn parse_fn_args(&mut self, named_args: bool, allow_c_variadic: bool) -> PResult<'a, (Vec , bool)> { - self.expect(&token::OpenDelim(token::Paren))?; - let sp = self.token.span; let mut c_variadic = false; - let (args, recovered): (Vec>, bool) = - self.parse_seq_to_before_end( - &token::CloseDelim(token::Paren), - SeqSep::trailing_allowed(token::Comma), - |p| { - let do_not_enforce_named_arguments_for_c_variadic = - |token: &token::Token| -> bool { - if token == &token::DotDotDot { - false - } else { - named_args - } - }; - match p.parse_arg_general( - false, - allow_c_variadic, - do_not_enforce_named_arguments_for_c_variadic - ) { - Ok(arg) => { - if let TyKind::CVarArgs = arg.ty.node { - c_variadic = true; - if p.token != token::CloseDelim(token::Paren) { - let span = p.token.span; - p.span_err(span, - "`...` must be the last argument of a C-variadic function"); - Ok(None) - } else { - Ok(Some(arg)) - } - } else { - Ok(Some(arg)) - } - }, - Err(mut e) => { - e.emit(); - let lo = p.prev_span; - // Skip every token until next possible arg or end. - p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]); - // Create a placeholder argument for proper arg count (issue #34264). - let span = lo.to(p.prev_span); - Ok(Some(dummy_arg(Ident::new(kw::Invalid, span)))) + let (args, _): (Vec>, _) = self.parse_paren_comma_seq(|p| { + let do_not_enforce_named_arguments_for_c_variadic = + |token: &token::Token| -> bool { + if token == &token::DotDotDot { + false + } else { + named_args + } + }; + match p.parse_arg_general( + false, + allow_c_variadic, + do_not_enforce_named_arguments_for_c_variadic + ) { + Ok(arg) => { + if let TyKind::CVarArgs = arg.ty.node { + c_variadic = true; + if p.token != token::CloseDelim(token::Paren) { + let span = p.token.span; + p.span_err(span, + "`...` must be the last argument of a C-variadic function"); + Ok(None) + } else { + Ok(Some(arg)) } + } else { + Ok(Some(arg)) } + }, + Err(mut e) => { + e.emit(); + let lo = p.prev_span; + // Skip every token until next possible arg or end. + p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]); + // Create a placeholder argument for proper arg count (issue #34264). + let span = lo.to(p.prev_span); + Ok(Some(dummy_arg(Ident::new(kw::Invalid, span)))) } - )?; - - if !recovered { - self.eat(&token::CloseDelim(token::Paren)); - } + } + })?; let args: Vec<_> = args.into_iter().filter_map(|x| x).collect(); @@ -5590,7 +5561,7 @@ impl<'a> Parser<'a> { (vec![self_arg], false) } else if self.eat(&token::Comma) { let mut fn_inputs = vec![self_arg]; - let (mut input, recovered) = self.parse_seq_to_before_end( + let (mut input, _, recovered) = self.parse_seq_to_before_end( &token::CloseDelim(token::Paren), sep, parse_arg_fn)?; fn_inputs.append(&mut input); (fn_inputs, recovered) @@ -5601,7 +5572,9 @@ impl<'a> Parser<'a> { } } } else { - self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)? + let (input, _, recovered) = + self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?; + (input, recovered) }; if !recovered { @@ -6202,26 +6175,20 @@ impl<'a> Parser<'a> { fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec> { // This is the case where we find `struct Foo(T) where T: Copy;` // Unit like structs are handled in parse_item_struct function - let fields = self.parse_unspanned_seq( - &token::OpenDelim(token::Paren), - &token::CloseDelim(token::Paren), - SeqSep::trailing_allowed(token::Comma), - |p| { - let attrs = p.parse_outer_attributes()?; - let lo = p.token.span; - let vis = p.parse_visibility(true)?; - let ty = p.parse_ty()?; - Ok(StructField { - span: lo.to(ty.span), - vis, - ident: None, - id: ast::DUMMY_NODE_ID, - ty, - attrs, - }) - })?; - - Ok(fields) + self.parse_paren_comma_seq(|p| { + let attrs = p.parse_outer_attributes()?; + let lo = p.token.span; + let vis = p.parse_visibility(true)?; + let ty = p.parse_ty()?; + Ok(StructField { + span: lo.to(ty.span), + vis, + ident: None, + id: ast::DUMMY_NODE_ID, + ty, + attrs, + }) + }).map(|(r, _)| r) } /// Parses a structure field declaration. @@ -7803,11 +7770,8 @@ impl<'a> Parser<'a> { /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`] /// ``` fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> { - self.parse_unspanned_seq(&token::OpenDelim(token::Brace), - &token::CloseDelim(token::Brace), - SeqSep::trailing_allowed(token::Comma), |this| { - Ok((this.parse_use_tree()?, ast::DUMMY_NODE_ID)) - }) + self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, ast::DUMMY_NODE_ID))) + .map(|(r, _)| r) } fn parse_rename(&mut self) -> PResult<'a, Option> { From 62b29a1e1774e8bf6c4246f2b47d556a9178ed67 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 10:36:14 +0200 Subject: [PATCH 27/49] Adjust parsing of Slice, Tuple, TupleStruct patterns. --- src/libsyntax/parse/parser.rs | 153 ++++++---------------------------- 1 file changed, 26 insertions(+), 127 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ec55c52745327..04e4dcfcb1aed 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3535,122 +3535,6 @@ impl<'a> Parser<'a> { }; } - // Parses a parenthesized list of patterns like - // `()`, `(p)`, `(p,)`, `(p, q)`, or `(p, .., q)`. Returns: - // - a vector of the patterns that were parsed - // - an option indicating the index of the `..` element - // - a boolean indicating whether a trailing comma was present. - // Trailing commas are significant because (p) and (p,) are different patterns. - fn parse_parenthesized_pat_list(&mut self) -> PResult<'a, (Vec>, Option, bool)> { - self.expect(&token::OpenDelim(token::Paren))?; - let result = match self.parse_pat_list() { - Ok(result) => result, - Err(mut err) => { // recover from parse error in tuple pattern list - err.emit(); - self.consume_block(token::Paren); - return Ok((vec![], Some(0), false)); - } - }; - self.expect(&token::CloseDelim(token::Paren))?; - Ok(result) - } - - fn parse_pat_list(&mut self) -> PResult<'a, (Vec>, Option, bool)> { - let mut fields = Vec::new(); - let mut ddpos = None; - let mut prev_dd_sp = None; - let mut trailing_comma = false; - loop { - if self.eat(&token::DotDot) { - if ddpos.is_none() { - ddpos = Some(fields.len()); - prev_dd_sp = Some(self.prev_span); - } else { - // Emit a friendly error, ignore `..` and continue parsing - let mut err = self.struct_span_err( - self.prev_span, - "`..` can only be used once per tuple or tuple struct pattern", - ); - err.span_label(self.prev_span, "can only be used once per pattern"); - if let Some(sp) = prev_dd_sp { - err.span_label(sp, "previously present here"); - } - err.emit(); - } - } else if !self.check(&token::CloseDelim(token::Paren)) { - fields.push(self.parse_pat(None)?); - } else { - break - } - - trailing_comma = self.eat(&token::Comma); - if !trailing_comma { - break - } - } - - if ddpos == Some(fields.len()) && trailing_comma { - // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed. - let msg = "trailing comma is not permitted after `..`"; - self.struct_span_err(self.prev_span, msg) - .span_label(self.prev_span, msg) - .emit(); - } - - Ok((fields, ddpos, trailing_comma)) - } - - fn parse_pat_vec_elements( - &mut self, - ) -> PResult<'a, (Vec>, Option>, Vec>)> { - let mut before = Vec::new(); - let mut slice = None; - let mut after = Vec::new(); - let mut first = true; - let mut before_slice = true; - - while self.token != token::CloseDelim(token::Bracket) { - if first { - first = false; - } else { - self.expect(&token::Comma)?; - - if self.token == token::CloseDelim(token::Bracket) - && (before_slice || !after.is_empty()) { - break - } - } - - if before_slice { - if self.eat(&token::DotDot) { - - if self.check(&token::Comma) || - self.check(&token::CloseDelim(token::Bracket)) { - slice = Some(P(Pat { - id: ast::DUMMY_NODE_ID, - node: PatKind::Wild, - span: self.prev_span, - })); - before_slice = false; - } - continue - } - } - - let subpat = self.parse_pat(None)?; - if before_slice && self.eat(&token::DotDot) { - slice = Some(subpat); - before_slice = false; - } else if before_slice { - before.push(subpat); - } else { - after.push(subpat); - } - } - - Ok((before, slice, after)) - } - fn parse_pat_field( &mut self, lo: Span, @@ -3862,6 +3746,17 @@ impl<'a> Parser<'a> { })) } + /// Parse a parentesized comma separated sequence of patterns until `delim` is reached. + fn parse_recover_pat_list(&mut self) -> PResult<'a, ()> { + while !self.check(&token::CloseDelim(token::Paren)) { + self.parse_pat(None)?; + if !self.eat(&token::Comma) { + return Ok(()) + } + } + Ok(()) + } + /// A wrapper around `parse_pat` with some special error handling for the /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast /// to subpatterns within such). @@ -3875,7 +3770,7 @@ impl<'a> Parser<'a> { // later. let comma_span = self.token.span; self.bump(); - if let Err(mut err) = self.parse_pat_list() { + if let Err(mut err) = self.parse_recover_pat_list() { // We didn't expect this to work anyway; we just wanted // to advance to the end of the comma-sequence so we know // the span to suggest parenthesizing @@ -3933,20 +3828,24 @@ impl<'a> Parser<'a> { pat = PatKind::Ref(subpat, mutbl); } token::OpenDelim(token::Paren) => { - // Parse (pat,pat,pat,...) as tuple pattern - let (fields, ddpos, trailing_comma) = self.parse_parenthesized_pat_list()?; - pat = if fields.len() == 1 && ddpos.is_none() && !trailing_comma { + // Parse `(pat, pat, pat, ...)` as tuple pattern. + let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| p.parse_pat(None))?; + + pat = if fields.len() == 1 && !(trailing_comma || fields[0].is_rest()) { PatKind::Paren(fields.into_iter().nth(0).unwrap()) } else { - PatKind::Tuple(fields, ddpos) + PatKind::Tuple(fields) }; } token::OpenDelim(token::Bracket) => { - // Parse [pat,pat,...] as slice pattern + // Parse `[pat, pat,...]` as a slice pattern. + let (slice, _) = self.parse_delim_comma_seq(token::Bracket, |p| p.parse_pat(None))?; + pat = PatKind::Slice(slice); + } + token::DotDot => { + // Parse `..`. self.bump(); - let (before, slice, after) = self.parse_pat_vec_elements()?; - self.expect(&token::CloseDelim(token::Bracket))?; - pat = PatKind::Slice(before, slice, after); + pat = PatKind::Rest; } // At this point, token != &, &&, (, [ _ => if self.eat_keyword(kw::Underscore) { @@ -4044,8 +3943,8 @@ impl<'a> Parser<'a> { return Err(err); } // Parse tuple struct or enum pattern - let (fields, ddpos, _) = self.parse_parenthesized_pat_list()?; - pat = PatKind::TupleStruct(path, fields, ddpos) + let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat(None))?; + pat = PatKind::TupleStruct(path, fields) } _ => pat = PatKind::Path(qself, path), } From 974413fcc5b8b6c32ad1334be05ad746fd82da99 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 03:55:13 +0200 Subject: [PATCH 28/49] Recover on '..X' / '..=X' / '...X' range patterns. --- src/libsyntax/parse/parser.rs | 52 +++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 04e4dcfcb1aed..e1bbd7631e5ea 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3730,6 +3730,13 @@ impl<'a> Parser<'a> { } } + /// Is the current token suitable as the start of a range patterns end? + fn is_pat_range_end_start(&self) -> bool { + self.token.is_path_start() // e.g. `MY_CONST`; + || self.token == token::Dot // e.g. `.5` for recovery; + || self.token.can_begin_literal_or_bool() // e.g. `42`. + } + // helper function to decide whether to parse as ident binding or to try to do // something more complex like range patterns fn parse_as_ident(&mut self) -> bool { @@ -3802,6 +3809,26 @@ impl<'a> Parser<'a> { self.parse_pat_with_range_pat(true, expected) } + /// Parse a range-to pattern, e.g. `..X` and `..=X` for recovery. + fn parse_pat_range_to(&mut self, re: RangeEnd, form: &str) -> PResult<'a, PatKind> { + let lo = self.prev_span; + let end = self.parse_pat_range_end()?; + let range_span = lo.to(end.span); + let begin = self.mk_expr(range_span, ExprKind::Err, ThinVec::new()); + + self.diagnostic() + .struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form)) + .span_suggestion( + range_span, + "try using the minimum value for the type", + format!("MIN{}{}", form, pprust::expr_to_string(&end)), + Applicability::HasPlaceholders, + ) + .emit(); + + Ok(PatKind::Range(begin, end, respan(lo, re))) + } + /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are /// allowed). fn parse_pat_with_range_pat( @@ -3843,9 +3870,24 @@ impl<'a> Parser<'a> { pat = PatKind::Slice(slice); } token::DotDot => { - // Parse `..`. self.bump(); - pat = PatKind::Rest; + pat = if self.is_pat_range_end_start() { + // Parse `..42` for recovery. + self.parse_pat_range_to(RangeEnd::Excluded, "..")? + } else { + // A rest pattern `..`. + PatKind::Rest + }; + } + token::DotDotEq => { + // Parse `..=42` for recovery. + self.bump(); + pat = self.parse_pat_range_to(RangeEnd::Included(RangeSyntax::DotDotEq), "..=")?; + } + token::DotDotDot => { + // Parse `...42` for recovery. + self.bump(); + pat = self.parse_pat_range_to(RangeEnd::Included(RangeSyntax::DotDotDot), "...")?; } // At this point, token != &, &&, (, [ _ => if self.eat_keyword(kw::Underscore) { @@ -3915,8 +3957,7 @@ impl<'a> Parser<'a> { let begin = self.mk_expr(span, ExprKind::Path(qself, path), ThinVec::new()); self.bump(); let end = self.parse_pat_range_end()?; - let op = Spanned { span: op_span, node: end_kind }; - pat = PatKind::Range(begin, end, op); + pat = PatKind::Range(begin, end, respan(op_span, end_kind)); } token::OpenDelim(token::Brace) => { if qself.is_some() { @@ -3966,8 +4007,7 @@ impl<'a> Parser<'a> { on a range-operator token") }; let end = self.parse_pat_range_end()?; - let op = Spanned { span: op_span, node: end_kind }; - pat = PatKind::Range(begin, end, op); + pat = PatKind::Range(begin, end, respan(op_span, end_kind)) } else { pat = PatKind::Lit(begin); } From 2f55354759c8b2140110a361ed43465ce5f4b785 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 06:06:41 +0200 Subject: [PATCH 29/49] Recover on 'X..' / 'X..=' / 'X...' range patterns. --- src/libsyntax/parse/parser.rs | 64 +++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e1bbd7631e5ea..34ed7f50907b1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3737,20 +3737,15 @@ impl<'a> Parser<'a> { || self.token.can_begin_literal_or_bool() // e.g. `42`. } - // helper function to decide whether to parse as ident binding or to try to do - // something more complex like range patterns + // Helper function to decide whether to parse as ident binding + // or to try to do something more complex like range patterns. fn parse_as_ident(&mut self) -> bool { self.look_ahead(1, |t| match t.kind { token::OpenDelim(token::Paren) | token::OpenDelim(token::Brace) | - token::DotDotDot | token::DotDotEq | token::ModSep | token::Not => Some(false), - // ensure slice patterns [a, b.., c] and [a, b, c..] don't go into the - // range pattern branch - token::DotDot => None, - _ => Some(true), - }).unwrap_or_else(|| self.look_ahead(2, |t| match t.kind { - token::Comma | token::CloseDelim(token::Bracket) => true, - _ => false, - })) + token::DotDotDot | token::DotDotEq | token::DotDot | + token::ModSep | token::Not => false, + _ => true, + }) } /// Parse a parentesized comma separated sequence of patterns until `delim` is reached. @@ -3829,6 +3824,33 @@ impl<'a> Parser<'a> { Ok(PatKind::Range(begin, end, respan(lo, re))) } + /// Parse the end of a `X..Y`, `X..=Y`, or `X...Y` range pattern or recover + /// if that end is missing treating it as `X..`, `X..=`, or `X...` respectively. + fn parse_pat_range_end_opt(&mut self, begin: &Expr, form: &str) -> PResult<'a, P> { + if self.is_pat_range_end_start() { + // Parsing e.g. `X..=Y`. + self.parse_pat_range_end() + } else { + // Parsing e.g. `X..`. + let range_span = begin.span.to(self.prev_span); + + self.diagnostic() + .struct_span_err( + range_span, + &format!("`X{}` range patterns are not supported", form), + ) + .span_suggestion( + range_span, + "try using the maximum value for the type", + format!("{}{}MAX", pprust::expr_to_string(&begin), form), + Applicability::HasPlaceholders, + ) + .emit(); + + Ok(self.mk_expr(range_span, ExprKind::Err, ThinVec::new())) + } + } + /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are /// allowed). fn parse_pat_with_range_pat( @@ -3944,10 +3966,10 @@ impl<'a> Parser<'a> { pat = PatKind::Mac(mac); } token::DotDotDot | token::DotDotEq | token::DotDot => { - let end_kind = match self.token.kind { - token::DotDot => RangeEnd::Excluded, - token::DotDotDot => RangeEnd::Included(RangeSyntax::DotDotDot), - token::DotDotEq => RangeEnd::Included(RangeSyntax::DotDotEq), + let (end_kind, form) = match self.token.kind { + token::DotDot => (RangeEnd::Excluded, ".."), + token::DotDotDot => (RangeEnd::Included(RangeSyntax::DotDotDot), "..."), + token::DotDotEq => (RangeEnd::Included(RangeSyntax::DotDotEq), "..="), _ => panic!("can only parse `..`/`...`/`..=` for ranges \ (checked above)"), }; @@ -3956,7 +3978,7 @@ impl<'a> Parser<'a> { let span = lo.to(self.prev_span); let begin = self.mk_expr(span, ExprKind::Path(qself, path), ThinVec::new()); self.bump(); - let end = self.parse_pat_range_end()?; + let end = self.parse_pat_range_end_opt(&begin, form)?; pat = PatKind::Range(begin, end, respan(op_span, end_kind)); } token::OpenDelim(token::Brace) => { @@ -3996,17 +4018,17 @@ impl<'a> Parser<'a> { let op_span = self.token.span; if self.check(&token::DotDot) || self.check(&token::DotDotEq) || self.check(&token::DotDotDot) { - let end_kind = if self.eat(&token::DotDotDot) { - RangeEnd::Included(RangeSyntax::DotDotDot) + let (end_kind, form) = if self.eat(&token::DotDotDot) { + (RangeEnd::Included(RangeSyntax::DotDotDot), "...") } else if self.eat(&token::DotDotEq) { - RangeEnd::Included(RangeSyntax::DotDotEq) + (RangeEnd::Included(RangeSyntax::DotDotEq), "..=") } else if self.eat(&token::DotDot) { - RangeEnd::Excluded + (RangeEnd::Excluded, "..") } else { panic!("impossible case: we already matched \ on a range-operator token") }; - let end = self.parse_pat_range_end()?; + let end = self.parse_pat_range_end_opt(&begin, form)?; pat = PatKind::Range(begin, end, respan(op_span, end_kind)) } else { pat = PatKind::Lit(begin); From 2411134c78706c1bb852da2fba4d90567ce4a5f3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 08:44:46 +0200 Subject: [PATCH 30/49] Update tests wrt. recovery of range patterns. --- .../exclusive_range_pattern_syntax_collision.rs | 5 ++++- .../exclusive_range_pattern_syntax_collision2.rs | 6 +++++- .../exclusive_range_pattern_syntax_collision3.rs | 6 +++++- src/test/ui/parser/pat-tuple-4.rs | 7 ++++++- src/test/ui/parser/pat-tuple-5.rs | 7 ++++++- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs index d95c4b0999405..a3b7a80642a72 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs @@ -2,7 +2,10 @@ fn main() { match [5..4, 99..105, 43..44] { - [_, 99.., _] => {}, //~ ERROR unexpected token: `,` + [_, 99.., _] => {}, + //~^ ERROR `X..` range patterns are not supported + //~| ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR only char and numeric types are allowed in range patterns _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs index 95677e34dd798..197953a1dc4ba 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs @@ -2,7 +2,11 @@ fn main() { match [5..4, 99..105, 43..44] { - [_, 99..] => {}, //~ ERROR unexpected token: `]` + [_, 99..] => {}, + //~^ ERROR `X..` range patterns are not supported + //~| ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR pattern requires 2 elements but array has 3 + //~| ERROR only char and numeric types are allowed in range patterns _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs index 3bf5da710ef9f..782777c10797d 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs @@ -2,7 +2,11 @@ fn main() { match [5..4, 99..105, 43..44] { - [..9, 99..100, _] => {}, //~ ERROR expected one of `,` or `]`, found `9` + [..9, 99..100, _] => {}, + //~^ ERROR `..X` range patterns are not supported + //~| ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR only char and numeric types are allowed in range patterns + //~| ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/parser/pat-tuple-4.rs b/src/test/ui/parser/pat-tuple-4.rs index 76f60d94bc86e..9eedb0f902342 100644 --- a/src/test/ui/parser/pat-tuple-4.rs +++ b/src/test/ui/parser/pat-tuple-4.rs @@ -1,5 +1,10 @@ fn main() { match 0 { - (.. pat) => {} //~ ERROR expected one of `)` or `,`, found `pat` + (.. pat) => {} + //~^ ERROR `..X` range patterns are not supported + //~| ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR cannot find value `pat` in this scope + //~| ERROR exclusive range pattern syntax is experimental + //~| ERROR only char and numeric types are allowed in range patterns } } diff --git a/src/test/ui/parser/pat-tuple-5.rs b/src/test/ui/parser/pat-tuple-5.rs index d4f05a5eb523e..5e191ca88e296 100644 --- a/src/test/ui/parser/pat-tuple-5.rs +++ b/src/test/ui/parser/pat-tuple-5.rs @@ -1,5 +1,10 @@ fn main() { match (0, 1) { - (pat ..) => {} //~ ERROR unexpected token: `)` + (pat ..) => {} + //~^ ERROR `X..` range patterns are not supported + //~| ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR cannot find value `pat` in this scope + //~| ERROR exclusive range pattern syntax is experimental + //~| ERROR only char and numeric types are allowed in range patterns } } From f6c8234f9f7495310a37c2e1dadc951d268143da Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 08:44:56 +0200 Subject: [PATCH 31/49] And also --bless those recovery tests. --- ...sive_range_pattern_syntax_collision.stderr | 24 +++++++++-- ...ive_range_pattern_syntax_collision2.stderr | 31 ++++++++++++-- ...ive_range_pattern_syntax_collision3.stderr | 36 +++++++++++++++-- src/test/ui/parser/pat-tuple-4.stderr | 38 ++++++++++++++++-- src/test/ui/parser/pat-tuple-5.stderr | 40 +++++++++++++++++-- 5 files changed, 150 insertions(+), 19 deletions(-) diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr index 359725a41c105..237b26db7c0d9 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr @@ -1,8 +1,24 @@ -error: unexpected token: `,` - --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:17 +error: `X..` range patterns are not supported + --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 | LL | [_, 99.., _] => {}, - | ^ + | ^^^^ help: try using the maximum value for the type: `99..MAX` -error: aborting due to previous error +error: arbitrary expressions aren't allowed in patterns + --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 + | +LL | [_, 99.., _] => {}, + | ^^^^ + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 + | +LL | [_, 99.., _] => {}, + | ^^^^ ranges require char or numeric types + | + = note: start type: {integer} + = note: end type: [type error] + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0029`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr index 8f849d7b3f87c..b7a64a0ba677c 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr @@ -1,8 +1,31 @@ -error: unexpected token: `]` - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:17 +error: `X..` range patterns are not supported + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 | LL | [_, 99..] => {}, - | ^ + | ^^^^ help: try using the maximum value for the type: `99..MAX` -error: aborting due to previous error +error: arbitrary expressions aren't allowed in patterns + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 + | +LL | [_, 99..] => {}, + | ^^^^ + +error[E0527]: pattern requires 2 elements but array has 3 + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:9 + | +LL | [_, 99..] => {}, + | ^^^^^^^^^ expected 3 elements + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 + | +LL | [_, 99..] => {}, + | ^^^^ ranges require char or numeric types + | + = note: start type: {integer} + = note: end type: [type error] + +error: aborting due to 4 previous errors +Some errors have detailed explanations: E0029, E0527. +For more information about an error, try `rustc --explain E0029`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr index a09ba3562e098..7cc1976def402 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr @@ -1,8 +1,36 @@ -error: expected one of `,` or `]`, found `9` - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12 +error: `..X` range patterns are not supported + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 | LL | [..9, 99..100, _] => {}, - | ^ expected one of `,` or `]` here + | ^^^ help: try using the minimum value for the type: `MIN..9` -error: aborting due to previous error +error: arbitrary expressions aren't allowed in patterns + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 + | +LL | [..9, 99..100, _] => {}, + | ^^^ + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 + | +LL | [..9, 99..100, _] => {}, + | ^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: {integer} + +error[E0308]: mismatched types + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15 + | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` +LL | [..9, 99..100, _] => {}, + | ^^^^^^^ expected struct `std::ops::Range`, found integer + | + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` + +error: aborting due to 4 previous errors +Some errors have detailed explanations: E0029, E0308. +For more information about an error, try `rustc --explain E0029`. diff --git a/src/test/ui/parser/pat-tuple-4.stderr b/src/test/ui/parser/pat-tuple-4.stderr index 26b92fae31391..2e1c167b871bd 100644 --- a/src/test/ui/parser/pat-tuple-4.stderr +++ b/src/test/ui/parser/pat-tuple-4.stderr @@ -1,8 +1,40 @@ -error: expected one of `)` or `,`, found `pat` +error: `..X` range patterns are not supported + --> $DIR/pat-tuple-4.rs:3:10 + | +LL | (.. pat) => {} + | ^^^^^^ help: try using the minimum value for the type: `MIN..pat` + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/pat-tuple-4.rs:3:10 + | +LL | (.. pat) => {} + | ^^^^^^ + +error[E0425]: cannot find value `pat` in this scope --> $DIR/pat-tuple-4.rs:3:13 | LL | (.. pat) => {} - | ^^^ expected one of `)` or `,` here + | ^^^ not found in this scope + +error[E0658]: exclusive range pattern syntax is experimental + --> $DIR/pat-tuple-4.rs:3:10 + | +LL | (.. pat) => {} + | ^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/37854 + = help: add #![feature(exclusive_range_pattern)] to the crate attributes to enable + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/pat-tuple-4.rs:3:10 + | +LL | (.. pat) => {} + | ^^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: [type error] -error: aborting due to previous error +error: aborting due to 5 previous errors +Some errors have detailed explanations: E0029, E0425, E0658. +For more information about an error, try `rustc --explain E0029`. diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr index f9832214c6800..9f0118e95736d 100644 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ b/src/test/ui/parser/pat-tuple-5.stderr @@ -1,8 +1,40 @@ -error: unexpected token: `)` - --> $DIR/pat-tuple-5.rs:3:16 +error: `X..` range patterns are not supported + --> $DIR/pat-tuple-5.rs:3:10 | LL | (pat ..) => {} - | ^ + | ^^^^^^ help: try using the maximum value for the type: `pat..MAX` -error: aborting due to previous error +error: arbitrary expressions aren't allowed in patterns + --> $DIR/pat-tuple-5.rs:3:10 + | +LL | (pat ..) => {} + | ^^^^^^ + +error[E0425]: cannot find value `pat` in this scope + --> $DIR/pat-tuple-5.rs:3:10 + | +LL | (pat ..) => {} + | ^^^ not found in this scope + +error[E0658]: exclusive range pattern syntax is experimental + --> $DIR/pat-tuple-5.rs:3:10 + | +LL | (pat ..) => {} + | ^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/37854 + = help: add #![feature(exclusive_range_pattern)] to the crate attributes to enable + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/pat-tuple-5.rs:3:10 + | +LL | (pat ..) => {} + | ^^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: [type error] + +error: aborting due to 5 previous errors +Some errors have detailed explanations: E0029, E0425, E0658. +For more information about an error, try `rustc --explain E0029`. From 891a736b0206f9646803475bed1aeb7ac9efcadd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 10 Jul 2019 01:50:54 +0200 Subject: [PATCH 32/49] Test parsing and recovery of all sorts of range patterns. --- src/test/ui/parser/recover-range-pats.rs | 159 ++++ src/test/ui/parser/recover-range-pats.stderr | 790 +++++++++++++++++++ 2 files changed, 949 insertions(+) create mode 100644 src/test/ui/parser/recover-range-pats.rs create mode 100644 src/test/ui/parser/recover-range-pats.stderr diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs new file mode 100644 index 0000000000000..ffec50c4e8314 --- /dev/null +++ b/src/test/ui/parser/recover-range-pats.rs @@ -0,0 +1,159 @@ +// Here we test all kinds of range patterns in terms of parsing / recovery. +// We want to ensure that: +// 1. Things parse as they should. +// 2. Or at least we have parser recovery if they don't. + +#![feature(exclusive_range_pattern)] +#![deny(ellipsis_inclusive_range_patterns)] + +fn main() {} + +const X: u8 = 0; +const Y: u8 = 3; + +fn exclusive_from_to() { + if let 0..3 = 0 {} // OK. + if let 0..Y = 0 {} // OK. + if let X..3 = 0 {} // OK. + if let X..Y = 0 {} // OK. + if let true..Y = 0 {} //~ ERROR only char and numeric types + if let X..true = 0 {} //~ ERROR only char and numeric types + if let .0..Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + if let X.. .0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part +} + +fn inclusive_from_to() { + if let 0..=3 = 0 {} // OK. + if let 0..=Y = 0 {} // OK. + if let X..=3 = 0 {} // OK. + if let X..=Y = 0 {} // OK. + if let true..=Y = 0 {} //~ ERROR only char and numeric types + if let X..=true = 0 {} //~ ERROR only char and numeric types + if let .0..=Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + if let X..=.0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part +} + +fn inclusive2_from_to() { + if let 0...3 = 0 {} //~ ERROR `...` range patterns are deprecated + if let 0...Y = 0 {} //~ ERROR `...` range patterns are deprecated + if let X...3 = 0 {} //~ ERROR `...` range patterns are deprecated + if let X...Y = 0 {} //~ ERROR `...` range patterns are deprecated + if let true...Y = 0 {} //~ ERROR only char and numeric types + //~^ ERROR `...` range patterns are deprecated + if let X...true = 0 {} //~ ERROR only char and numeric types + //~^ ERROR `...` range patterns are deprecated + if let .0...Y = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated + if let X... .0 = 0 {} //~ ERROR mismatched types + //~^ ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated +} + +fn exclusive_from() { + if let 0.. = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..` range patterns are not supported + if let X.. = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..` range patterns are not supported + if let true.. = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..` range patterns are not supported + if let .0.. = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..` range patterns are not supported + //~| ERROR float literals must have an integer part +} + +fn inclusive_from() { + if let 0..= = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..=` range patterns are not supported + if let X..= = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..=` range patterns are not supported + if let true..= = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..=` range patterns are not supported + if let .0..= = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X..=` range patterns are not supported + //~| ERROR float literals must have an integer part +} + +fn inclusive2_from() { + if let 0... = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X...` range patterns are not supported + //~| ERROR `...` range patterns are deprecated + if let X... = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X...` range patterns are not supported + //~| ERROR `...` range patterns are deprecated + if let true... = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X...` range patterns are not supported + //~| ERROR `...` range patterns are deprecated + if let .0... = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `X...` range patterns are not supported + //~| ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated +} + +fn exclusive_to() { + if let ..0 = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..X` range patterns are not supported + if let ..Y = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..X` range patterns are not supported + if let ..true = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..X` range patterns are not supported + if let .. .0 = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..X` range patterns are not supported + //~| ERROR float literals must have an integer part +} + +fn inclusive_to() { + if let ..=3 = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..=X` range patterns are not supported + if let ..=Y = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..=X` range patterns are not supported + if let ..=true = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..=X` range patterns are not supported + if let ..=.0 = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `..=X` range patterns are not supported + //~| ERROR float literals must have an integer part +} + +fn inclusive2_to() { + if let ...3 = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `...X` range patterns are not supported + //~| ERROR `...` range patterns are deprecated + if let ...Y = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `...X` range patterns are not supported + //~| ERROR `...` range patterns are deprecated + if let ...true = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `...X` range patterns are not supported + //~| ERROR `...` range patterns are deprecated + if let ....3 = 0 {} //~ ERROR only char and numeric types + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR `...X` range patterns are not supported + //~| ERROR float literals must have an integer part + //~| ERROR `...` range patterns are deprecated +} diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr new file mode 100644 index 0000000000000..a4d321fae8d30 --- /dev/null +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -0,0 +1,790 @@ +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:21:12 + | +LL | if let .0..Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:23:16 + | +LL | if let X.. .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:34:12 + | +LL | if let .0..=Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:36:16 + | +LL | if let X..=.0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:49:12 + | +LL | if let .0...Y = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:52:17 + | +LL | if let X... .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:58:12 + | +LL | if let 0.. = 0 {} + | ^^^ help: try using the maximum value for the type: `0..MAX` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:61:12 + | +LL | if let X.. = 0 {} + | ^^^ help: try using the maximum value for the type: `X..MAX` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:64:12 + | +LL | if let true.. = 0 {} + | ^^^^^^ help: try using the maximum value for the type: `true..MAX` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:67:12 + | +LL | if let .0.. = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X..` range patterns are not supported + --> $DIR/recover-range-pats.rs:67:12 + | +LL | if let .0.. = 0 {} + | ^^^^ help: try using the maximum value for the type: `0.0..MAX` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:74:12 + | +LL | if let 0..= = 0 {} + | ^^^^ help: try using the maximum value for the type: `0..=MAX` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:77:12 + | +LL | if let X..= = 0 {} + | ^^^^ help: try using the maximum value for the type: `X..=MAX` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:80:12 + | +LL | if let true..= = 0 {} + | ^^^^^^^ help: try using the maximum value for the type: `true..=MAX` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:83:12 + | +LL | if let .0..= = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X..=` range patterns are not supported + --> $DIR/recover-range-pats.rs:83:12 + | +LL | if let .0..= = 0 {} + | ^^^^^ help: try using the maximum value for the type: `0.0..=MAX` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:90:12 + | +LL | if let 0... = 0 {} + | ^^^^ help: try using the maximum value for the type: `0...MAX` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:94:12 + | +LL | if let X... = 0 {} + | ^^^^ help: try using the maximum value for the type: `X...MAX` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:98:12 + | +LL | if let true... = 0 {} + | ^^^^^^^ help: try using the maximum value for the type: `true...MAX` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:102:12 + | +LL | if let .0... = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `X...` range patterns are not supported + --> $DIR/recover-range-pats.rs:102:12 + | +LL | if let .0... = 0 {} + | ^^^^^ help: try using the maximum value for the type: `0.0...MAX` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:110:12 + | +LL | if let ..0 = 0 {} + | ^^^ help: try using the minimum value for the type: `MIN..0` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:113:12 + | +LL | if let ..Y = 0 {} + | ^^^ help: try using the minimum value for the type: `MIN..Y` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:116:12 + | +LL | if let ..true = 0 {} + | ^^^^^^ help: try using the minimum value for the type: `MIN..true` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:119:15 + | +LL | if let .. .0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `..X` range patterns are not supported + --> $DIR/recover-range-pats.rs:119:12 + | +LL | if let .. .0 = 0 {} + | ^^^^^ help: try using the minimum value for the type: `MIN..0.0` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:126:12 + | +LL | if let ..=3 = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN..=3` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:129:12 + | +LL | if let ..=Y = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN..=Y` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:132:12 + | +LL | if let ..=true = 0 {} + | ^^^^^^^ help: try using the minimum value for the type: `MIN..=true` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:135:15 + | +LL | if let ..=.0 = 0 {} + | ^^ help: must have an integer part: `0.0` + +error: `..=X` range patterns are not supported + --> $DIR/recover-range-pats.rs:135:12 + | +LL | if let ..=.0 = 0 {} + | ^^^^^ help: try using the minimum value for the type: `MIN..=0.0` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:142:12 + | +LL | if let ...3 = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN...3` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:146:12 + | +LL | if let ...Y = 0 {} + | ^^^^ help: try using the minimum value for the type: `MIN...Y` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:150:12 + | +LL | if let ...true = 0 {} + | ^^^^^^^ help: try using the minimum value for the type: `MIN...true` + +error: float literals must have an integer part + --> $DIR/recover-range-pats.rs:154:15 + | +LL | if let ....3 = 0 {} + | ^^ help: must have an integer part: `0.3` + +error: `...X` range patterns are not supported + --> $DIR/recover-range-pats.rs:154:12 + | +LL | if let ....3 = 0 {} + | ^^^^^ help: try using the minimum value for the type: `MIN...0.3` + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:58:12 + | +LL | if let 0.. = 0 {} + | ^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:61:12 + | +LL | if let X.. = 0 {} + | ^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:64:12 + | +LL | if let true.. = 0 {} + | ^^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:67:12 + | +LL | if let .0.. = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:74:12 + | +LL | if let 0..= = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:77:12 + | +LL | if let X..= = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:80:12 + | +LL | if let true..= = 0 {} + | ^^^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:83:12 + | +LL | if let .0..= = 0 {} + | ^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:90:12 + | +LL | if let 0... = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:94:12 + | +LL | if let X... = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:98:12 + | +LL | if let true... = 0 {} + | ^^^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:102:12 + | +LL | if let .0... = 0 {} + | ^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:110:12 + | +LL | if let ..0 = 0 {} + | ^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:113:12 + | +LL | if let ..Y = 0 {} + | ^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:116:12 + | +LL | if let ..true = 0 {} + | ^^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:119:12 + | +LL | if let .. .0 = 0 {} + | ^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:126:12 + | +LL | if let ..=3 = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:129:12 + | +LL | if let ..=Y = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:132:12 + | +LL | if let ..=true = 0 {} + | ^^^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:135:12 + | +LL | if let ..=.0 = 0 {} + | ^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:142:12 + | +LL | if let ...3 = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:146:12 + | +LL | if let ...Y = 0 {} + | ^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:150:12 + | +LL | if let ...true = 0 {} + | ^^^^^^^ + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/recover-range-pats.rs:154:12 + | +LL | if let ....3 = 0 {} + | ^^^^^ + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:41:13 + | +LL | if let 0...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + | +note: lint level defined here + --> $DIR/recover-range-pats.rs:7:9 + | +LL | #![deny(ellipsis_inclusive_range_patterns)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:42:13 + | +LL | if let 0...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:43:13 + | +LL | if let X...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:44:13 + | +LL | if let X...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:45:16 + | +LL | if let true...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:47:13 + | +LL | if let X...true = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:49:14 + | +LL | if let .0...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:52:13 + | +LL | if let X... .0 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:90:13 + | +LL | if let 0... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:94:13 + | +LL | if let X... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:98:16 + | +LL | if let true... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:102:14 + | +LL | if let .0... = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:142:12 + | +LL | if let ...3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:146:12 + | +LL | if let ...Y = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:150:12 + | +LL | if let ...true = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error: `...` range patterns are deprecated + --> $DIR/recover-range-pats.rs:154:12 + | +LL | if let ....3 = 0 {} + | ^^^ help: use `..=` for an inclusive range + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:19:12 + | +LL | if let true..Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:20:15 + | +LL | if let X..true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:21:12 + | +LL | if let .0..Y = 0 {} + | ^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:23:12 + | +LL | if let X.. .0 = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:32:12 + | +LL | if let true..=Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:33:16 + | +LL | if let X..=true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:34:12 + | +LL | if let .0..=Y = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:36:12 + | +LL | if let X..=.0 = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:45:12 + | +LL | if let true...Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:47:16 + | +LL | if let X...true = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: bool + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:49:12 + | +LL | if let .0...Y = 0 {} + | ^^^^^^ expected integer, found floating-point number + | + = note: expected type `{integer}` + found type `{float}` + +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:52:12 + | +LL | if let X... .0 = 0 {} + | ^^^^^^^ expected integer, found floating-point number + | + = note: expected type `u8` + found type `{float}` + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:58:12 + | +LL | if let 0.. = 0 {} + | ^^^ ranges require char or numeric types + | + = note: start type: {integer} + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:61:12 + | +LL | if let X.. = 0 {} + | ^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:64:12 + | +LL | if let true.. = 0 {} + | ^^^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:67:12 + | +LL | if let .0.. = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: {float} + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:74:12 + | +LL | if let 0..= = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: {integer} + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:77:12 + | +LL | if let X..= = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:80:12 + | +LL | if let true..= = 0 {} + | ^^^^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:83:12 + | +LL | if let .0..= = 0 {} + | ^^^^^ ranges require char or numeric types + | + = note: start type: {float} + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:90:12 + | +LL | if let 0... = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: {integer} + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:94:12 + | +LL | if let X... = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: u8 + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:98:12 + | +LL | if let true... = 0 {} + | ^^^^^^^ ranges require char or numeric types + | + = note: start type: bool + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:102:12 + | +LL | if let .0... = 0 {} + | ^^^^^ ranges require char or numeric types + | + = note: start type: {float} + = note: end type: [type error] + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:110:12 + | +LL | if let ..0 = 0 {} + | ^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: {integer} + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:113:12 + | +LL | if let ..Y = 0 {} + | ^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:116:12 + | +LL | if let ..true = 0 {} + | ^^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: bool + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:119:12 + | +LL | if let .. .0 = 0 {} + | ^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: {float} + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:126:12 + | +LL | if let ..=3 = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: {integer} + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:129:12 + | +LL | if let ..=Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:132:12 + | +LL | if let ..=true = 0 {} + | ^^^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: bool + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:135:12 + | +LL | if let ..=.0 = 0 {} + | ^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: {float} + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:142:12 + | +LL | if let ...3 = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: {integer} + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:146:12 + | +LL | if let ...Y = 0 {} + | ^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: u8 + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:150:12 + | +LL | if let ...true = 0 {} + | ^^^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: bool + +error[E0029]: only char and numeric types are allowed in range patterns + --> $DIR/recover-range-pats.rs:154:12 + | +LL | if let ....3 = 0 {} + | ^^^^^ ranges require char or numeric types + | + = note: start type: [type error] + = note: end type: {float} + +error: aborting due to 112 previous errors + +Some errors have detailed explanations: E0029, E0308. +For more information about an error, try `rustc --explain E0029`. From 75da43dc87a9fee3fc1ef5cffb4a6721ef4bd2ba Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 8 Jul 2019 01:47:46 +0200 Subject: [PATCH 33/49] Use new 'p @ ..' syntax in tests. --- src/test/mir-opt/uniform_array_move_out.rs | 2 +- .../ui/array-slice-vec/vec-matching-fold.rs | 4 +-- .../vec-matching-legal-tail-element-borrow.rs | 2 +- src/test/ui/array-slice-vec/vec-matching.rs | 27 +++++-------------- .../ui/array-slice-vec/vec-tail-matching.rs | 4 +-- .../ui/binding/irrefutable-slice-patterns.rs | 2 +- .../ui/binding/zero_sized_subslice_match.rs | 2 +- .../ui/borrowck/borrowck-describe-lvalue.rs | 8 +++--- .../borrowck/borrowck-move-out-from-array.rs | 2 +- .../borrowck/borrowck-move-out-of-vec-tail.rs | 2 +- ...rrowck-slice-pattern-element-loan-rpass.rs | 2 +- .../borrowck-slice-pattern-element-loan.rs | 12 ++++----- .../borrowck-vec-pattern-element-loan.rs | 6 ++--- .../borrowck-vec-pattern-loan-from-mut.rs | 2 +- .../borrowck-vec-pattern-move-tail.rs | 2 +- .../borrowck/borrowck-vec-pattern-nesting.rs | 2 +- .../borrowck-vec-pattern-tail-element-loan.rs | 2 +- src/test/ui/drop/dynamic-drop-async.rs | 4 +-- src/test/ui/drop/dynamic-drop.rs | 6 ++--- src/test/ui/error-codes/E0528.rs | 2 +- .../feature-gate-slice-patterns.rs | 6 ++--- src/test/ui/issues/issue-12369.rs | 4 +-- src/test/ui/issues/issue-15080.rs | 4 +-- src/test/ui/issues/issue-15104.rs | 2 +- src/test/ui/issues/issue-17877.rs | 4 +-- src/test/ui/issues/issue-26158.rs | 2 +- src/test/ui/issues/issue-37598.rs | 5 ++-- src/test/ui/issues/issue-7784.rs | 2 +- src/test/ui/match/match-vec-mismatch.rs | 4 +-- src/test/ui/match/match-vec-unreachable.rs | 2 +- .../ui/non-exhaustive/non-exhaustive-match.rs | 14 +++++----- .../non-exhaustive-pattern-witness.rs | 2 +- src/test/ui/parser/match-vec-invalid.rs | 2 +- .../ui/rfc-2005-default-binding-mode/slice.rs | 2 +- .../rfc-2005-default-binding-mode/slice.rs | 2 +- src/test/ui/trailing-comma.rs | 2 +- 36 files changed, 69 insertions(+), 85 deletions(-) diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs index fac5ef3b03ce1..c249154c71e23 100644 --- a/src/test/mir-opt/uniform_array_move_out.rs +++ b/src/test/mir-opt/uniform_array_move_out.rs @@ -8,7 +8,7 @@ fn move_out_from_end() { fn move_out_by_subslice() { let a = [box 1, box 2]; - let [_y..] = a; + let [_y @ ..] = a; } fn main() { diff --git a/src/test/ui/array-slice-vec/vec-matching-fold.rs b/src/test/ui/array-slice-vec/vec-matching-fold.rs index 2b19c49c42700..f416160db2422 100644 --- a/src/test/ui/array-slice-vec/vec-matching-fold.rs +++ b/src/test/ui/array-slice-vec/vec-matching-fold.rs @@ -11,7 +11,7 @@ fn foldl(values: &[T], U: Clone+Debug, T:Debug, F: FnMut(U, &T) -> U, { match values { - &[ref head, ref tail..] => + &[ref head, ref tail @ ..] => foldl(tail, function(initial, head), function), &[] => { // FIXME: call guards @@ -28,7 +28,7 @@ fn foldr(values: &[T], F: FnMut(&T, U) -> U, { match values { - &[ref head.., ref tail] => + &[ref head @ .., ref tail] => foldr(head, function(tail, initial), function), &[] => { // FIXME: call guards diff --git a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs index bce03b3375e51..f0602c328b071 100644 --- a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs +++ b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs @@ -8,7 +8,7 @@ pub fn main() { let x: &[isize] = &[1, 2, 3, 4, 5]; if !x.is_empty() { let el = match x { - &[1, ref tail..] => &tail[0], + &[1, ref tail @ ..] => &tail[0], _ => unreachable!() }; println!("{}", *el); diff --git a/src/test/ui/array-slice-vec/vec-matching.rs b/src/test/ui/array-slice-vec/vec-matching.rs index a37c25160fa76..49c736bd72847 100644 --- a/src/test/ui/array-slice-vec/vec-matching.rs +++ b/src/test/ui/array-slice-vec/vec-matching.rs @@ -14,7 +14,7 @@ fn a() { fn b() { let x = [1, 2, 3]; match x { - [a, b, c..] => { + [a, b, c @ ..] => { assert_eq!(a, 1); assert_eq!(b, 2); let expected: &[_] = &[3]; @@ -22,7 +22,7 @@ fn b() { } } match x { - [a.., b, c] => { + [a @ .., b, c] => { let expected: &[_] = &[1]; assert_eq!(a, expected); assert_eq!(b, 2); @@ -30,7 +30,7 @@ fn b() { } } match x { - [a, b.., c] => { + [a, b @ .., c] => { assert_eq!(a, 1); let expected: &[_] = &[2]; assert_eq!(b, expected); @@ -50,7 +50,7 @@ fn b() { fn b_slice() { let x : &[_] = &[1, 2, 3]; match x { - &[a, b, ref c..] => { + &[a, b, ref c @ ..] => { assert_eq!(a, 1); assert_eq!(b, 2); let expected: &[_] = &[3]; @@ -59,7 +59,7 @@ fn b_slice() { _ => unreachable!() } match x { - &[ref a.., b, c] => { + &[ref a @ .., b, c] => { let expected: &[_] = &[1]; assert_eq!(a, expected); assert_eq!(b, 2); @@ -68,7 +68,7 @@ fn b_slice() { _ => unreachable!() } match x { - &[a, ref b.., c] => { + &[a, ref b @ .., c] => { assert_eq!(a, 1); let expected: &[_] = &[2]; assert_eq!(b, expected); @@ -134,20 +134,6 @@ fn e() { assert_eq!(c, 1); } -fn f() { - let x = &[1, 2, 3, 4, 5]; - let [a, [b, [c, ..].., d].., e] = *x; - assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5)); - - let x: &[isize] = x; - let (a, b, c, d, e) = match *x { - [a, [b, [c, ..].., d].., e] => (a, b, c, d, e), - _ => unimplemented!() - }; - - assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5)); -} - pub fn main() { a(); b(); @@ -155,5 +141,4 @@ pub fn main() { c(); d(); e(); - f(); } diff --git a/src/test/ui/array-slice-vec/vec-tail-matching.rs b/src/test/ui/array-slice-vec/vec-tail-matching.rs index 84d246dff825c..3c7b160dcc540 100644 --- a/src/test/ui/array-slice-vec/vec-tail-matching.rs +++ b/src/test/ui/array-slice-vec/vec-tail-matching.rs @@ -13,14 +13,14 @@ pub fn main() { Foo { string: "baz" } ]; match x { - [ref first, ref tail..] => { + [ref first, ref tail @ ..] => { assert_eq!(first.string, "foo"); assert_eq!(tail.len(), 2); assert_eq!(tail[0].string, "bar"); assert_eq!(tail[1].string, "baz"); match *(tail as &[_]) { - [Foo { .. }, _, Foo { .. }, ref _tail..] => { + [Foo { .. }, _, Foo { .. }, ref _tail @ ..] => { unreachable!(); } [Foo { string: ref a }, Foo { string: ref b }] => { diff --git a/src/test/ui/binding/irrefutable-slice-patterns.rs b/src/test/ui/binding/irrefutable-slice-patterns.rs index 733e6b7b57f72..ac733ef6e9c86 100644 --- a/src/test/ui/binding/irrefutable-slice-patterns.rs +++ b/src/test/ui/binding/irrefutable-slice-patterns.rs @@ -4,7 +4,7 @@ #![feature(slice_patterns)] fn foo(s: &[i32]) -> &[i32] { - let &[ref xs..] = s; + let &[ref xs @ ..] = s; xs } diff --git a/src/test/ui/binding/zero_sized_subslice_match.rs b/src/test/ui/binding/zero_sized_subslice_match.rs index 51e1c024bffff..5326fa612a87b 100644 --- a/src/test/ui/binding/zero_sized_subslice_match.rs +++ b/src/test/ui/binding/zero_sized_subslice_match.rs @@ -7,6 +7,6 @@ fn main() { // The subslice used to go out of bounds for zero-sized array items, check that this doesn't // happen anymore match x { - [_, ref y..] => assert_eq!(&x[1] as *const (), &y[0] as *const ()) + [_, ref y @ ..] => assert_eq!(&x[1] as *const (), &y[0] as *const ()) } } diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.rs b/src/test/ui/borrowck/borrowck-describe-lvalue.rs index c8dbf4e691816..c27d9519dc798 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.rs @@ -140,22 +140,22 @@ fn main() { let mut v = &[1, 2, 3, 4, 5]; let x = &mut v; match v { - &[x..] => println!("{:?}", x), + &[x @ ..] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } match v { - &[_, x..] => println!("{:?}", x), + &[_, x @ ..] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } match v { - &[x.., _] => println!("{:?}", x), + &[x @ .., _] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } match v { - &[_, x.., _] => println!("{:?}", x), + &[_, x @ .., _] => println!("{:?}", x), //~^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.rs b/src/test/ui/borrowck/borrowck-move-out-from-array.rs index 856b03edd2d72..ee6abf407a304 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.rs @@ -10,7 +10,7 @@ fn move_out_from_begin_and_end() { fn move_out_by_const_index_and_subslice() { let a = [box 1, box 2]; let [_x, _] = a; - let [_y..] = a; //~ ERROR [E0382] + let [_y @ ..] = a; //~ ERROR [E0382] } fn main() {} diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs index cc524c1ac3e6e..fa9a3c217db77 100644 --- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs +++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs @@ -15,7 +15,7 @@ pub fn main() { ]; let x: &[Foo] = &x; match *x { - [_, ref tail..] => { + [_, ref tail @ ..] => { match tail { //~^ ERROR cannot move out of type `[Foo]` &[Foo { string: a }, diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs index 7675147c8ec2a..048813b2b93e6 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs @@ -5,7 +5,7 @@ fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> { match *v { - [ref mut head, ref mut tail..] => { + [ref mut head, ref mut tail @ ..] => { Some((head, tail)) } [] => None diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs index 5de8dd3305e37..a6b54f9537ddc 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs @@ -70,7 +70,7 @@ fn const_index_mixed(s: &mut [i32]) { fn const_index_and_subslice_ok(s: &mut [i32]) { if let [ref first, ref second, ..] = *s { - if let [_, _, ref mut tail..] = *s { + if let [_, _, ref mut tail @ ..] = *s { nop(&[first, second]); nop_subslice(tail); } @@ -79,7 +79,7 @@ fn const_index_and_subslice_ok(s: &mut [i32]) { fn const_index_and_subslice_err(s: &mut [i32]) { if let [ref first, ref second, ..] = *s { - if let [_, ref mut tail..] = *s { //~ERROR + if let [_, ref mut tail @ ..] = *s { //~ERROR nop(&[first, second]); nop_subslice(tail); } @@ -88,7 +88,7 @@ fn const_index_and_subslice_err(s: &mut [i32]) { fn const_index_and_subslice_from_end_ok(s: &mut [i32]) { if let [.., ref second, ref first] = *s { - if let [ref mut tail.., _, _] = *s { + if let [ref mut tail @ .., _, _] = *s { nop(&[first, second]); nop_subslice(tail); } @@ -97,7 +97,7 @@ fn const_index_and_subslice_from_end_ok(s: &mut [i32]) { fn const_index_and_subslice_from_end_err(s: &mut [i32]) { if let [.., ref second, ref first] = *s { - if let [ref mut tail.., _] = *s { //~ERROR + if let [ref mut tail @ .., _] = *s { //~ERROR nop(&[first, second]); nop_subslice(tail); } @@ -105,8 +105,8 @@ fn const_index_and_subslice_from_end_err(s: &mut [i32]) { } fn subslices(s: &mut [i32]) { - if let [_, _, _, ref s1..] = *s { - if let [ref mut s2.., _, _, _] = *s { //~ERROR + if let [_, _, _, ref s1 @ ..] = *s { + if let [ref mut s2 @ .., _, _, _] = *s { //~ERROR nop_subslice(s1); nop_subslice(s2); } diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs index 100384d78c8ea..53a9bcef74a22 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs @@ -4,7 +4,7 @@ fn a<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let tail = match vec { - &[_, ref tail..] => tail, + &[_, ref tail @ ..] => tail, _ => panic!("a") }; tail //~ ERROR cannot return value referencing local variable `vec` @@ -14,7 +14,7 @@ fn b<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let init = match vec { - &[ref init.., _] => init, + &[ref init @ .., _] => init, _ => panic!("b") }; init //~ ERROR cannot return value referencing local variable `vec` @@ -24,7 +24,7 @@ fn c<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let slice = match vec { - &[_, ref slice.., _] => slice, + &[_, ref slice @ .., _] => slice, _ => panic!("c") }; slice //~ ERROR cannot return value referencing local variable `vec` diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs index 4d99a92b18ba8..dd9023f6d9f79 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs @@ -4,7 +4,7 @@ fn a() { let mut v = vec![1, 2, 3]; let vb: &mut [isize] = &mut v; match vb { - &mut [_a, ref tail..] => { + &mut [_a, ref tail @ ..] => { v.push(tail[0] + tail[1]); //~ ERROR cannot borrow } _ => {} diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs index efc52530716c8..420223009a45b 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs @@ -5,7 +5,7 @@ fn main() { let mut a = [1, 2, 3, 4]; let t = match a { - [1, 2, ref tail..] => tail, + [1, 2, ref tail @ ..] => tail, _ => unreachable!() }; println!("t[0]: {}", t[0]); diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs index 6448149391def..a215305f684dd 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs @@ -19,7 +19,7 @@ fn b() { let mut vec = vec![box 1, box 2, box 3]; let vec: &mut [Box] = &mut vec; match vec { - &mut [ref _b..] => { + &mut [ref _b @ ..] => { //~^ borrow of `vec[_]` occurs here vec[0] = box 4; //~ ERROR cannot assign //~^ NOTE assignment to borrowed `vec[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs index e602e75886d95..c35be2f6be62c 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs @@ -4,7 +4,7 @@ fn a<'a>() -> &'a isize { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; let tail = match vec { - &[_a, ref tail..] => &tail[0], + &[_a, ref tail @ ..] => &tail[0], _ => panic!("foo") }; tail //~ ERROR cannot return value referencing local variable `vec` diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index 9226145d9354d..f3f5c382275fe 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -217,7 +217,7 @@ async fn subslice_pattern_from_end_with_drop(a: Rc, arg: bool, arg2: if arg { let [.., _x, _] = arr; } else { - let [_, _y..] = arr; + let [_, _y @ ..] = arr; } a.alloc().await; } @@ -226,7 +226,7 @@ async fn subslice_pattern_reassign(a: Rc) { let mut ar = [a.alloc().await, a.alloc().await, a.alloc().await]; let [_, _, _x] = ar; ar = [a.alloc().await, a.alloc().await, a.alloc().await]; - let [_, _y..] = ar; + let [_, _y @ ..] = ar; a.alloc().await; } diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index eb1a3f3a9f9cb..8516bc3d96424 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -237,7 +237,7 @@ fn subslice_pattern_from_end(a: &Allocator, arg: bool) { if arg { let[.., _x, _] = a; } else { - let[_, _y..] = a; + let[_, _y @ ..] = a; } } @@ -251,7 +251,7 @@ fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) { if arg { let[.., _x, _] = a; } else { - let[_, _y..] = a; + let[_, _y @ ..] = a; } } @@ -266,7 +266,7 @@ fn subslice_pattern_reassign(a: &Allocator) { let mut ar = [a.alloc(), a.alloc(), a.alloc()]; let[_, _, _x] = ar; ar = [a.alloc(), a.alloc(), a.alloc()]; - let[_, _y..] = ar; + let[_, _y @ ..] = ar; } fn panic_after_return(a: &Allocator) -> Ptr<'_> { diff --git a/src/test/ui/error-codes/E0528.rs b/src/test/ui/error-codes/E0528.rs index f2681fa043dab..17d03b14fc6e1 100644 --- a/src/test/ui/error-codes/E0528.rs +++ b/src/test/ui/error-codes/E0528.rs @@ -3,7 +3,7 @@ fn main() { let r = &[1, 2]; match r { - &[a, b, c, rest..] => { + &[a, b, c, rest @ ..] => { //~^ ERROR E0528 } } diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs index 0165321debe6b..ad46c6fd3c2e0 100644 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs +++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs @@ -10,8 +10,8 @@ fn main() { let x = [ 1, 2, 3, 4, 5 ]; match x { - [ xs.., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [ 1, xs.., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [ 1, 2, xs.. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [ xs @ .., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [ 1, xs @ .., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [ 1, 2, xs @ .. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized } } diff --git a/src/test/ui/issues/issue-12369.rs b/src/test/ui/issues/issue-12369.rs index 8df8efefd05ed..0866131807463 100644 --- a/src/test/ui/issues/issue-12369.rs +++ b/src/test/ui/issues/issue-12369.rs @@ -6,7 +6,7 @@ fn main() { let v: isize = match &*sl { &[] => 0, &[a,b,c] => 3, - &[a, ref rest..] => a, - &[10,a, ref rest..] => 10 //~ ERROR: unreachable pattern + &[a, ref rest @ ..] => a, + &[10,a, ref rest @ ..] => 10 //~ ERROR: unreachable pattern }; } diff --git a/src/test/ui/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs index 4558118a8091c..b11b1cda38ae1 100644 --- a/src/test/ui/issues/issue-15080.rs +++ b/src/test/ui/issues/issue-15080.rs @@ -7,11 +7,11 @@ fn main() { let mut result = vec![]; loop { x = match *x { - [1, n, 3, ref rest..] => { + [1, n, 3, ref rest @ ..] => { result.push(n); rest } - [n, ref rest..] => { + [n, ref rest @ ..] => { result.push(n); rest } diff --git a/src/test/ui/issues/issue-15104.rs b/src/test/ui/issues/issue-15104.rs index 3a03a52c32485..ee977541137db 100644 --- a/src/test/ui/issues/issue-15104.rs +++ b/src/test/ui/issues/issue-15104.rs @@ -9,6 +9,6 @@ fn count_members(v: &[usize]) -> usize { match *v { [] => 0, [_] => 1, - [_, ref xs..] => 1 + count_members(xs) + [_, ref xs @ ..] => 1 + count_members(xs) } } diff --git a/src/test/ui/issues/issue-17877.rs b/src/test/ui/issues/issue-17877.rs index af22b1ad8f0bc..fefa3f2f87304 100644 --- a/src/test/ui/issues/issue-17877.rs +++ b/src/test/ui/issues/issue-17877.rs @@ -7,8 +7,8 @@ fn main() { }, 42_usize); assert_eq!(match [0u8; 1024] { - [1, _..] => 0_usize, - [0, _..] => 1_usize, + [1, ..] => 0_usize, + [0, ..] => 1_usize, _ => 2_usize }, 1_usize); } diff --git a/src/test/ui/issues/issue-26158.rs b/src/test/ui/issues/issue-26158.rs index 11f47b6d02a73..f21a4766768ee 100644 --- a/src/test/ui/issues/issue-26158.rs +++ b/src/test/ui/issues/issue-26158.rs @@ -2,5 +2,5 @@ fn main() { let x: &[u32] = &[]; - let &[[ref _a, ref _b..]..] = x; //~ ERROR refutable pattern + let &[[ref _a, ref _b @ ..] @ ..] = x; //~ ERROR refutable pattern } diff --git a/src/test/ui/issues/issue-37598.rs b/src/test/ui/issues/issue-37598.rs index 1bec3d340d665..31b3aba6bc204 100644 --- a/src/test/ui/issues/issue-37598.rs +++ b/src/test/ui/issues/issue-37598.rs @@ -1,11 +1,10 @@ -// build-pass (FIXME(62277): could be check-pass?) -#![allow(dead_code)] +// check-pass #![feature(slice_patterns)] fn check(list: &[u8]) { match list { &[] => {}, - &[_u1, _u2, ref _next..] => {}, + &[_u1, _u2, ref _next @ ..] => {}, &[_u1] => {}, } } diff --git a/src/test/ui/issues/issue-7784.rs b/src/test/ui/issues/issue-7784.rs index b75e547079ef5..5b70bd6e5ff54 100644 --- a/src/test/ui/issues/issue-7784.rs +++ b/src/test/ui/issues/issue-7784.rs @@ -24,7 +24,7 @@ fn main() { assert_eq!(d, "baz"); let out = bar("baz", "foo"); - let [a, xs.., d] = out; + let [a, xs @ .., d] = out; assert_eq!(a, "baz"); assert_eq!(xs, ["foo", "foo"]); assert_eq!(d, "baz"); diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/match/match-vec-mismatch.rs index 5e61c1b22a085..a0ef92743ac5a 100644 --- a/src/test/ui/match/match-vec-mismatch.rs +++ b/src/test/ui/match/match-vec-mismatch.rs @@ -19,10 +19,10 @@ fn main() { match [0, 1, 2] { [0] => {}, //~ ERROR pattern requires - [0, 1, x..] => { + [0, 1, x @ ..] => { let a: [_; 1] = x; } - [0, 1, 2, 3, x..] => {} //~ ERROR pattern requires + [0, 1, 2, 3, x @ ..] => {} //~ ERROR pattern requires }; match does_not_exist { //~ ERROR cannot find value `does_not_exist` in this scope diff --git a/src/test/ui/match/match-vec-unreachable.rs b/src/test/ui/match/match-vec-unreachable.rs index 9e167f37ba9d9..78810525bad0f 100644 --- a/src/test/ui/match/match-vec-unreachable.rs +++ b/src/test/ui/match/match-vec-unreachable.rs @@ -23,7 +23,7 @@ fn main() { let x: Vec = vec!['a', 'b', 'c']; let x: &[char] = &x; match *x { - ['a', 'b', 'c', ref _tail..] => {} + ['a', 'b', 'c', ref _tail @ ..] => {} ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern _ => {} } diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.rs b/src/test/ui/non-exhaustive/non-exhaustive-match.rs index e888bcf516891..8cc5f4042cccb 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-match.rs +++ b/src/test/ui/non-exhaustive/non-exhaustive-match.rs @@ -32,14 +32,14 @@ fn main() { let vec = vec![Some(42), None, Some(21)]; let vec: &[Option] = &vec; match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered - [Some(..), None, ref tail..] => {} - [Some(..), Some(..), ref tail..] => {} + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} [None] => {} } let vec = vec![1]; let vec: &[isize] = &vec; match *vec { - [_, ref tail..] => (), + [_, ref tail @ ..] => (), [] => () } let vec = vec![0.5f32]; @@ -53,10 +53,10 @@ fn main() { let vec = vec![Some(42), None, Some(21)]; let vec: &[Option] = &vec; match *vec { - [Some(..), None, ref tail..] => {} - [Some(..), Some(..), ref tail..] => {} - [None, None, ref tail..] => {} - [None, Some(..), ref tail..] => {} + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} + [None, None, ref tail @ ..] => {} + [None, Some(..), ref tail @ ..] => {} [Some(_)] => {} [None] => {} [] => {} diff --git a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs index 9fcd4bdad7264..4ca1cbcebccf5 100644 --- a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs +++ b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs @@ -77,7 +77,7 @@ fn vectors_with_nested_enums() { [Enum::Second(true), Enum::First] => (), [Enum::Second(true), Enum::Second(true)] => (), [Enum::Second(false), _] => (), - [_, _, ref tail.., _] => () + [_, _, ref tail @ .., _] => () } } diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/parser/match-vec-invalid.rs index e5e85ba8ca602..269f2ce85a349 100644 --- a/src/test/ui/parser/match-vec-invalid.rs +++ b/src/test/ui/parser/match-vec-invalid.rs @@ -1,7 +1,7 @@ fn main() { let a = Vec::new(); match a { - [1, tail.., tail..] => {}, //~ ERROR: expected one of `,` or `@`, found `..` + [1, tail @ .., tail @ ..] => {}, //~ ERROR: expected one of `,` or `@`, found `..` _ => () } } diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs index fd85bf7f16007..1484b8c4a1f13 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs @@ -4,6 +4,6 @@ pub fn main() { let sl: &[u8] = b"foo"; match sl { //~ ERROR non-exhaustive patterns - [first, remainder..] => {}, + [first, remainder @ ..] => {}, }; } diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs index 939a3c4a1fd7a..38b0941aad0a6 100644 --- a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs @@ -5,7 +5,7 @@ fn slice_pat() { let sl: &[u8] = b"foo"; match sl { - [first, remainder..] => { + [first, remainder @ ..] => { let _: &u8 = first; assert_eq!(first, &b'f'); assert_eq!(remainder, b"oo"); diff --git a/src/test/ui/trailing-comma.rs b/src/test/ui/trailing-comma.rs index f34e6b7606dd7..929c35a9e1122 100644 --- a/src/test/ui/trailing-comma.rs +++ b/src/test/ui/trailing-comma.rs @@ -25,7 +25,7 @@ pub fn main() { let (_, _,) = (1, 1,); let [_, _,] = [1, 1,]; let [_, _, .., _,] = [1, 1, 1, 1,]; - let [_, _, _.., _,] = [1, 1, 1, 1,]; + let [_, _, _, ..,] = [1, 1, 1, 1,]; let x: Foo = Foo::(1); From 91c8b53f458ef6efb3640a359dba4015848fd9d1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 8 Jul 2019 01:58:28 +0200 Subject: [PATCH 34/49] --bless tests due to new subslice syntax. --- .../borrowck/borrowck-describe-lvalue.stderr | 16 +++---- .../borrowck-move-out-from-array.stderr | 4 +- ...borrowck-slice-pattern-element-loan.stderr | 16 +++---- .../borrowck-vec-pattern-move-tail.stderr | 4 +- .../borrowck-vec-pattern-nesting.stderr | 4 +- src/test/ui/error-codes/E0528.stderr | 4 +- .../feature-gate-slice-patterns.rs | 12 ++--- .../feature-gate-slice-patterns.stderr | 24 +++++----- src/test/ui/issues/issue-12369.stderr | 4 +- src/test/ui/match/match-vec-mismatch.stderr | 4 +- src/test/ui/parser/match-vec-invalid.rs | 7 ++- src/test/ui/parser/match-vec-invalid.stderr | 44 ++++++++++++++++--- src/test/ui/parser/pat-tuple-3.rs | 2 +- src/test/ui/parser/pat-tuple-3.stderr | 6 +-- 14 files changed, 95 insertions(+), 56 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr index 14b9b50f0c32a..38d847a90ff95 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr @@ -192,8 +192,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here LL | match v { -LL | &[x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -204,8 +204,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -216,8 +216,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -228,8 +228,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr index 16722a456defa..b34c03e6deff8 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr @@ -13,8 +13,8 @@ error[E0382]: use of moved value: `a[..]` | LL | let [_x, _] = a; | -- value moved here -LL | let [_y..] = a; - | ^^ value used here after move +LL | let [_y @ ..] = a; + | ^^^^^^^ value used here after move | = note: move occurs because `a[..]` has type `std::boxed::Box`, which does not implement the `Copy` trait diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr index f716ee68b0002..2c019f4461182 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr @@ -89,8 +89,8 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im | LL | if let [ref first, ref second, ..] = *s { | ---------- immutable borrow occurs here -LL | if let [_, ref mut tail..] = *s { - | ^^^^^^^^^^^^ mutable borrow occurs here +LL | if let [_, ref mut tail @ ..] = *s { + | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here @@ -99,18 +99,18 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im | LL | if let [.., ref second, ref first] = *s { | ---------- immutable borrow occurs here -LL | if let [ref mut tail.., _] = *s { - | ^^^^^^^^^^^^ mutable borrow occurs here +LL | if let [ref mut tail @ .., _] = *s { + | ^^^^^^^^^^^^^^^^^ mutable borrow occurs here LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable --> $DIR/borrowck-slice-pattern-element-loan.rs:109:17 | -LL | if let [_, _, _, ref s1..] = *s { - | ------ immutable borrow occurs here -LL | if let [ref mut s2.., _, _, _] = *s { - | ^^^^^^^^^^ mutable borrow occurs here +LL | if let [_, _, _, ref s1 @ ..] = *s { + | ----------- immutable borrow occurs here +LL | if let [ref mut s2 @ .., _, _, _] = *s { + | ^^^^^^^^^^^^^^^ mutable borrow occurs here LL | nop_subslice(s1); | -- immutable borrow later used here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr index b2f553ba49f70..9f8e6fe3b6898 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr @@ -1,8 +1,8 @@ error[E0506]: cannot assign to `a[_]` because it is borrowed --> $DIR/borrowck-vec-pattern-move-tail.rs:12:5 | -LL | [1, 2, ref tail..] => tail, - | -------- borrow of `a[_]` occurs here +LL | [1, 2, ref tail @ ..] => tail, + | ------------- borrow of `a[_]` occurs here ... LL | a[2] = 0; | ^^^^^^^^ assignment to borrowed `a[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr index 072501f23ff84..f54a3a4072cd2 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -13,8 +13,8 @@ LL | _a.use_ref(); error[E0506]: cannot assign to `vec[_]` because it is borrowed --> $DIR/borrowck-vec-pattern-nesting.rs:24:13 | -LL | &mut [ref _b..] => { - | ------ borrow of `vec[_]` occurs here +LL | &mut [ref _b @ ..] => { + | ----------- borrow of `vec[_]` occurs here LL | LL | vec[0] = box 4; | ^^^^^^ assignment to borrowed `vec[_]` occurs here diff --git a/src/test/ui/error-codes/E0528.stderr b/src/test/ui/error-codes/E0528.stderr index a7205af50542a..0f566091145bf 100644 --- a/src/test/ui/error-codes/E0528.stderr +++ b/src/test/ui/error-codes/E0528.stderr @@ -1,8 +1,8 @@ error[E0528]: pattern requires at least 3 elements but array has 2 --> $DIR/E0528.rs:6:10 | -LL | &[a, b, c, rest..] => { - | ^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements +LL | &[a, b, c, rest @ ..] => { + | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs index ad46c6fd3c2e0..f2a1b135b69cb 100644 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs +++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs @@ -3,15 +3,15 @@ fn main() { let x = [1, 2, 3, 4, 5]; match x { - [1, 2, ..] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [1, .., 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [.., 4, 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [1, 2, ..] => {} //~ ERROR subslice patterns are unstable + [1, .., 5] => {} //~ ERROR subslice patterns are unstable + [.., 4, 5] => {} //~ ERROR subslice patterns are unstable } let x = [ 1, 2, 3, 4, 5 ]; match x { - [ xs @ .., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [ 1, xs @ .., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized - [ 1, 2, xs @ .. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [ xs @ .., 4, 5 ] => {} //~ ERROR subslice patterns are unstable + [ 1, xs @ .., 5 ] => {} //~ ERROR subslice patterns are unstable + [ 1, 2, xs @ .. ] => {} //~ ERROR subslice patterns are unstable } } diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr index e88fddaa81fbe..d4946a42b8f3d 100644 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr @@ -1,4 +1,4 @@ -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:6:16 | LL | [1, 2, ..] => {} @@ -7,7 +7,7 @@ LL | [1, 2, ..] => {} = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:7:13 | LL | [1, .., 5] => {} @@ -16,7 +16,7 @@ LL | [1, .., 5] => {} = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:8:10 | LL | [.., 4, 5] => {} @@ -25,29 +25,29 @@ LL | [.., 4, 5] => {} = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:13:11 | -LL | [ xs.., 4, 5 ] => {} - | ^^ +LL | [ xs @ .., 4, 5 ] => {} + | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:14:14 | -LL | [ 1, xs.., 5 ] => {} - | ^^ +LL | [ 1, xs @ .., 5 ] => {} + | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error[E0658]: syntax for subslices in slice patterns is not yet stabilized +error[E0658]: subslice patterns are unstable --> $DIR/feature-gate-slice-patterns.rs:15:17 | -LL | [ 1, 2, xs.. ] => {} - | ^^ +LL | [ 1, 2, xs @ .. ] => {} + | ^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add `#![feature(slice_patterns)]` to the crate attributes to enable diff --git a/src/test/ui/issues/issue-12369.stderr b/src/test/ui/issues/issue-12369.stderr index fec9078dc4090..f27425e28c61d 100644 --- a/src/test/ui/issues/issue-12369.stderr +++ b/src/test/ui/issues/issue-12369.stderr @@ -1,8 +1,8 @@ error: unreachable pattern --> $DIR/issue-12369.rs:10:9 | -LL | &[10,a, ref rest..] => 10 - | ^^^^^^^^^^^^^^^^^^^ +LL | &[10,a, ref rest @ ..] => 10 + | ^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here --> $DIR/issue-12369.rs:2:9 diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/match/match-vec-mismatch.stderr index 47f9d48e26290..2f1bbb7621659 100644 --- a/src/test/ui/match/match-vec-mismatch.stderr +++ b/src/test/ui/match/match-vec-mismatch.stderr @@ -19,8 +19,8 @@ LL | [0] => {}, error[E0528]: pattern requires at least 4 elements but array has 3 --> $DIR/match-vec-mismatch.rs:25:9 | -LL | [0, 1, 2, 3, x..] => {} - | ^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements +LL | [0, 1, 2, 3, x @ ..] => {} + | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements error[E0282]: type annotations needed --> $DIR/match-vec-mismatch.rs:36:9 diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/parser/match-vec-invalid.rs index 269f2ce85a349..d14fdc4e22e31 100644 --- a/src/test/ui/parser/match-vec-invalid.rs +++ b/src/test/ui/parser/match-vec-invalid.rs @@ -1,7 +1,12 @@ fn main() { let a = Vec::new(); match a { - [1, tail @ .., tail @ ..] => {}, //~ ERROR: expected one of `,` or `@`, found `..` + [1, tail @ .., tail @ ..] => {}, + //~^ ERROR identifier `tail` is bound more than once in the same pattern + //~| ERROR subslice patterns are unstable + //~| ERROR subslice patterns are unstable + //~| ERROR `..` can only be used once per slice pattern + //~| ERROR expected an array or slice, found `std::vec::Vec<_>` _ => () } } diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr index fee8d248dcf07..0de9a75234758 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/parser/match-vec-invalid.stderr @@ -1,8 +1,42 @@ -error: expected one of `,` or `@`, found `..` - --> $DIR/match-vec-invalid.rs:4:25 +error[E0416]: identifier `tail` is bound more than once in the same pattern + --> $DIR/match-vec-invalid.rs:4:24 | -LL | [1, tail.., tail..] => {}, - | ^^ expected one of `,` or `@` here +LL | [1, tail @ .., tail @ ..] => {}, + | ^^^^ used in a pattern more than once -error: aborting due to previous error +error[E0658]: subslice patterns are unstable + --> $DIR/match-vec-invalid.rs:4:13 + | +LL | [1, tail @ .., tail @ ..] => {}, + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error[E0658]: subslice patterns are unstable + --> $DIR/match-vec-invalid.rs:4:24 + | +LL | [1, tail @ .., tail @ ..] => {}, + | ^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error: `..` can only be used once per slice pattern + --> $DIR/match-vec-invalid.rs:4:31 + | +LL | [1, tail @ .., tail @ ..] => {}, + | -- ^^ can only be used once per slice pattern + | | + | previously used here + +error[E0529]: expected an array or slice, found `std::vec::Vec<_>` + --> $DIR/match-vec-invalid.rs:4:9 + | +LL | [1, tail @ .., tail @ ..] => {}, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `std::vec::Vec<_>` + +error: aborting due to 5 previous errors +Some errors have detailed explanations: E0416, E0529, E0658. +For more information about an error, try `rustc --explain E0416`. diff --git a/src/test/ui/parser/pat-tuple-3.rs b/src/test/ui/parser/pat-tuple-3.rs index e1e975d3c3ea0..1486ab231aab4 100644 --- a/src/test/ui/parser/pat-tuple-3.rs +++ b/src/test/ui/parser/pat-tuple-3.rs @@ -1,6 +1,6 @@ fn main() { match (0, 1, 2) { (.., pat, ..) => {} - //~^ ERROR `..` can only be used once per tuple or tuple struct pattern + //~^ ERROR `..` can only be used once per tuple pattern } } diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr index c9f14bb90429b..9ac0611c5c933 100644 --- a/src/test/ui/parser/pat-tuple-3.stderr +++ b/src/test/ui/parser/pat-tuple-3.stderr @@ -1,10 +1,10 @@ -error: `..` can only be used once per tuple or tuple struct pattern +error: `..` can only be used once per tuple pattern --> $DIR/pat-tuple-3.rs:3:19 | LL | (.., pat, ..) => {} - | -- ^^ can only be used once per pattern + | -- ^^ can only be used once per tuple pattern | | - | previously present here + | previously used here error: aborting due to previous error From e725ea221564753efb5b8695ed2e4bf99e6ac1e9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 8 Jul 2019 02:06:49 +0200 Subject: [PATCH 35/49] Intersection patterns 'p1 @ p2' are not supported. --- src/test/ui/issues/issue-26158.rs | 6 ------ src/test/ui/issues/issue-26158.stderr | 9 --------- 2 files changed, 15 deletions(-) delete mode 100644 src/test/ui/issues/issue-26158.rs delete mode 100644 src/test/ui/issues/issue-26158.stderr diff --git a/src/test/ui/issues/issue-26158.rs b/src/test/ui/issues/issue-26158.rs deleted file mode 100644 index f21a4766768ee..0000000000000 --- a/src/test/ui/issues/issue-26158.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(slice_patterns)] - -fn main() { - let x: &[u32] = &[]; - let &[[ref _a, ref _b @ ..] @ ..] = x; //~ ERROR refutable pattern -} diff --git a/src/test/ui/issues/issue-26158.stderr b/src/test/ui/issues/issue-26158.stderr deleted file mode 100644 index 3a4dd79e81053..0000000000000 --- a/src/test/ui/issues/issue-26158.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0005]: refutable pattern in local binding: `&[]` not covered - --> $DIR/issue-26158.rs:5:9 - | -LL | let &[[ref _a, ref _b..]..] = x; - | ^^^^^^^^^^^^^^^^^^^^^^^ pattern `&[]` not covered - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0005`. From 06e5ae5c825f79c4f0fa7c0cbcf43f74751fc7d4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 9 Jul 2019 06:30:03 +0200 Subject: [PATCH 36/49] Account for better recovery in two cases. --- src/test/ui/parser/pat-lt-bracket-6.rs | 3 +++ src/test/ui/parser/pat-lt-bracket-6.stderr | 25 +++++++++++++++++++++- src/test/ui/parser/pat-lt-bracket-7.rs | 2 ++ src/test/ui/parser/pat-lt-bracket-7.stderr | 15 ++++++++++++- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs index 9bad0cb25c1e4..69c4bfb23c2f9 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.rs +++ b/src/test/ui/parser/pat-lt-bracket-6.rs @@ -1,3 +1,6 @@ fn main() { let Test(&desc[..]) = x; //~ ERROR: expected one of `)`, `,`, or `@`, found `[` + //~^ ERROR cannot find value `x` in this scope + //~| ERROR cannot find tuple struct/variant `Test` in this scope + //~| ERROR subslice patterns are unstable } diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr index 2ee4bdb20fe88..d526addeb796d 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.stderr +++ b/src/test/ui/parser/pat-lt-bracket-6.stderr @@ -4,5 +4,28 @@ error: expected one of `)`, `,`, or `@`, found `[` LL | let Test(&desc[..]) = x; | ^ expected one of `)`, `,`, or `@` here -error: aborting due to previous error +error[E0425]: cannot find value `x` in this scope + --> $DIR/pat-lt-bracket-6.rs:2:27 + | +LL | let Test(&desc[..]) = x; + | ^ not found in this scope + +error[E0531]: cannot find tuple struct/variant `Test` in this scope + --> $DIR/pat-lt-bracket-6.rs:2:9 + | +LL | let Test(&desc[..]) = x; + | ^^^^ not found in this scope + +error[E0658]: subslice patterns are unstable + --> $DIR/pat-lt-bracket-6.rs:2:20 + | +LL | let Test(&desc[..]) = x; + | ^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62254 + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error: aborting due to 4 previous errors +Some errors have detailed explanations: E0425, E0658. +For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/parser/pat-lt-bracket-7.rs b/src/test/ui/parser/pat-lt-bracket-7.rs index 36c0d7733733a..1060d705e6e31 100644 --- a/src/test/ui/parser/pat-lt-bracket-7.rs +++ b/src/test/ui/parser/pat-lt-bracket-7.rs @@ -1,3 +1,5 @@ fn main() { for thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[` + //~^ ERROR cannot find value `foo` in this scope + //~| ERROR cannot find tuple struct/variant `thing` in this scope } diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr index 5552ea46d9b9d..3e4bff7cbd759 100644 --- a/src/test/ui/parser/pat-lt-bracket-7.stderr +++ b/src/test/ui/parser/pat-lt-bracket-7.stderr @@ -4,5 +4,18 @@ error: expected one of `)`, `,`, or `@`, found `[` LL | for thing(x[]) in foo {} | ^ expected one of `)`, `,`, or `@` here -error: aborting due to previous error +error[E0425]: cannot find value `foo` in this scope + --> $DIR/pat-lt-bracket-7.rs:2:23 + | +LL | for thing(x[]) in foo {} + | ^^^ not found in this scope + +error[E0531]: cannot find tuple struct/variant `thing` in this scope + --> $DIR/pat-lt-bracket-7.rs:2:9 + | +LL | for thing(x[]) in foo {} + | ^^^^^ not found in this scope + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0425`. From e3cdadd73f8ce792d274e7204eef51de8d39493f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 8 Jul 2019 03:03:12 +0200 Subject: [PATCH 37/49] (pat, ..,) is now syntactically legal. --- src/test/ui/parser/pat-tuple-2.rs | 3 ++- src/test/ui/parser/pat-tuple-2.stderr | 8 -------- 2 files changed, 2 insertions(+), 9 deletions(-) delete mode 100644 src/test/ui/parser/pat-tuple-2.stderr diff --git a/src/test/ui/parser/pat-tuple-2.rs b/src/test/ui/parser/pat-tuple-2.rs index fd25499381a28..a8f3debd3d634 100644 --- a/src/test/ui/parser/pat-tuple-2.rs +++ b/src/test/ui/parser/pat-tuple-2.rs @@ -1,6 +1,7 @@ +// check-pass + fn main() { match (0, 1, 2) { (pat, ..,) => {} - //~^ ERROR trailing comma is not permitted after `..` } } diff --git a/src/test/ui/parser/pat-tuple-2.stderr b/src/test/ui/parser/pat-tuple-2.stderr deleted file mode 100644 index c3a5c39a8e32a..0000000000000 --- a/src/test/ui/parser/pat-tuple-2.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: trailing comma is not permitted after `..` - --> $DIR/pat-tuple-2.rs:3:17 - | -LL | (pat, ..,) => {} - | ^ trailing comma is not permitted after `..` - -error: aborting due to previous error - From 7c0b1da2c1f2a758a2762e4cd2039794ab8243a7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 8 Jul 2019 15:35:56 +0200 Subject: [PATCH 38/49] Win some lose some; Unfortunately we lost recovery in one case. --- src/test/ui/parser/recover-tuple-pat.rs | 4 ++-- src/test/ui/parser/recover-tuple-pat.stderr | 20 ++------------------ 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/test/ui/parser/recover-tuple-pat.rs b/src/test/ui/parser/recover-tuple-pat.rs index 488e8db6b8789..7fded752d675e 100644 --- a/src/test/ui/parser/recover-tuple-pat.rs +++ b/src/test/ui/parser/recover-tuple-pat.rs @@ -1,12 +1,12 @@ +// NOTE: This doesn't recover anymore. + fn main() { let x = (1, 2, 3, 4); match x { (1, .., 4) => {} (1, .=., 4) => { let _: usize = ""; } //~^ ERROR expected pattern, found `.` - //~| ERROR mismatched types (.=., 4) => {} - //~^ ERROR expected pattern, found `.` (1, 2, 3, 4) => {} } } diff --git a/src/test/ui/parser/recover-tuple-pat.stderr b/src/test/ui/parser/recover-tuple-pat.stderr index 5919aa72355ac..93a6a66a63082 100644 --- a/src/test/ui/parser/recover-tuple-pat.stderr +++ b/src/test/ui/parser/recover-tuple-pat.stderr @@ -1,24 +1,8 @@ error: expected pattern, found `.` - --> $DIR/recover-tuple-pat.rs:5:13 + --> $DIR/recover-tuple-pat.rs:7:13 | LL | (1, .=., 4) => { let _: usize = ""; } | ^ expected pattern -error: expected pattern, found `.` - --> $DIR/recover-tuple-pat.rs:8:10 - | -LL | (.=., 4) => {} - | ^ expected pattern - -error[E0308]: mismatched types - --> $DIR/recover-tuple-pat.rs:5:41 - | -LL | (1, .=., 4) => { let _: usize = ""; } - | ^^ expected usize, found reference - | - = note: expected type `usize` - found type `&'static str` - -error: aborting due to 3 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. From cec8649933ef90f345b44c067670ff772c905937 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 10 Jul 2019 05:16:47 +0200 Subject: [PATCH 39/49] Update unstable book wrt. subslice patterns. --- src/doc/unstable-book/src/language-features/slice-patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md index 00c81f03ba173..cdb74495884a8 100644 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/slice-patterns.md @@ -17,7 +17,7 @@ matched against that pattern. For example: fn is_symmetric(list: &[u32]) -> bool { match list { &[] | &[_] => true, - &[x, ref inside.., y] if x == y => is_symmetric(inside), + &[x, ref inside @ .., y] if x == y => is_symmetric(inside), &[..] => false, } } From 984f9db94674d50a20ef21046fc142ebec259102 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 10 Jul 2019 05:17:26 +0200 Subject: [PATCH 40/49] Adjust documentation in HAIR. --- src/librustc_mir/hair/pattern/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 1baeda41498ed..f759ec7f219d1 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -162,7 +162,7 @@ pub enum PatternKind<'tcx> { /// Matches against a slice, checking the length and extracting elements. /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty. - /// e.g., `&[ref xs..]`. + /// e.g., `&[ref xs @ ..]`. Slice { prefix: Vec>, slice: Option>, From 1060513ddc9a8689730a993c8a91e574c4879607 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 10 Jul 2019 05:18:01 +0200 Subject: [PATCH 41/49] Get out of bootstrapping pickle. --- src/librustc_target/abi/mod.rs | 29 ++++++++++++++++++++++------- src/librustc_typeck/check/mod.rs | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 4a4c6799c005e..80fcb45d0b9bc 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -105,20 +105,34 @@ impl TargetDataLayout { let mut dl = TargetDataLayout::default(); let mut i128_align_src = 64; for spec in target.data_layout.split('-') { - match spec.split(':').collect::>()[..] { + let spec_parts = spec.split(':').collect::>(); + + match &*spec_parts { ["e"] => dl.endian = Endian::Little, ["E"] => dl.endian = Endian::Big, [p] if p.starts_with("P") => { dl.instruction_address_space = parse_address_space(&p[1..], "P")? } - ["a", ref a..] => dl.aggregate_align = align(a, "a")?, - ["f32", ref a..] => dl.f32_align = align(a, "f32")?, - ["f64", ref a..] => dl.f64_align = align(a, "f64")?, - [p @ "p", s, ref a..] | [p @ "p0", s, ref a..] => { + // FIXME: Ping cfg(bootstrap) -- Use `ref a @ ..` with new bootstrap compiler. + ["a", ..] => { + let a = &spec_parts[1..]; // FIXME inline into pattern. + dl.aggregate_align = align(a, "a")? + } + ["f32", ..] => { + let a = &spec_parts[1..]; // FIXME inline into pattern. + dl.f32_align = align(a, "f32")? + } + ["f64", ..] => { + let a = &spec_parts[1..]; // FIXME inline into pattern. + dl.f64_align = align(a, "f64")? + } + [p @ "p", s, ..] | [p @ "p0", s, ..] => { + let a = &spec_parts[2..]; // FIXME inline into pattern. dl.pointer_size = size(s, p)?; dl.pointer_align = align(a, p)?; } - [s, ref a..] if s.starts_with("i") => { + [s, ..] if s.starts_with("i") => { + let a = &spec_parts[1..]; // FIXME inline into pattern. let bits = match s[1..].parse::() { Ok(bits) => bits, Err(_) => { @@ -142,7 +156,8 @@ impl TargetDataLayout { dl.i128_align = a; } } - [s, ref a..] if s.starts_with("v") => { + [s, ..] if s.starts_with("v") => { + let a = &spec_parts[1..]; // FIXME inline into pattern. let v_size = size(&s[1..], "v")?; let a = align(a, s)?; if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 36977b878dd7e..66c726b2485d1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1818,7 +1818,9 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, d ); let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg); err.span_label(sp, &msg); - if let &[ref start.., ref end] = &variant_spans[..] { + if let &[.., ref end] = &variant_spans[..] { + // FIXME: Ping cfg(bootstrap) -- Use `ref start @ ..` with new bootstrap compiler. + let start = &variant_spans[..variant_spans.len() - 1]; for variant_span in start { err.span_label(*variant_span, ""); } From acc6a6d8cb7f2d05cacb230d712e7a150fc68bb9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 10 Jul 2019 16:18:01 +0200 Subject: [PATCH 42/49] --bless tests after rebase. --- src/test/ui/parser/match-vec-invalid.stderr | 4 ++-- src/test/ui/parser/pat-lt-bracket-6.stderr | 2 +- src/test/ui/parser/pat-tuple-4.stderr | 2 +- src/test/ui/parser/pat-tuple-5.stderr | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr index 0de9a75234758..49d5a83c5a9f9 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/parser/match-vec-invalid.stderr @@ -11,7 +11,7 @@ LL | [1, tail @ .., tail @ ..] => {}, | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable error[E0658]: subslice patterns are unstable --> $DIR/match-vec-invalid.rs:4:24 @@ -20,7 +20,7 @@ LL | [1, tail @ .., tail @ ..] => {}, | ^^^^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable error: `..` can only be used once per slice pattern --> $DIR/match-vec-invalid.rs:4:31 diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr index d526addeb796d..45270b314a9b7 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.stderr +++ b/src/test/ui/parser/pat-lt-bracket-6.stderr @@ -23,7 +23,7 @@ LL | let Test(&desc[..]) = x; | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add #![feature(slice_patterns)] to the crate attributes to enable + = help: add `#![feature(slice_patterns)]` to the crate attributes to enable error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/pat-tuple-4.stderr b/src/test/ui/parser/pat-tuple-4.stderr index 2e1c167b871bd..d126163476c9b 100644 --- a/src/test/ui/parser/pat-tuple-4.stderr +++ b/src/test/ui/parser/pat-tuple-4.stderr @@ -23,7 +23,7 @@ LL | (.. pat) => {} | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/37854 - = help: add #![feature(exclusive_range_pattern)] to the crate attributes to enable + = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/pat-tuple-4.rs:3:10 diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr index 9f0118e95736d..06f2a59d90906 100644 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ b/src/test/ui/parser/pat-tuple-5.stderr @@ -23,7 +23,7 @@ LL | (pat ..) => {} | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/37854 - = help: add #![feature(exclusive_range_pattern)] to the crate attributes to enable + = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/pat-tuple-5.rs:3:10 From 59b5dae918ed4a10a569176a88d040477a1487c6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 10 Jul 2019 18:53:39 +0200 Subject: [PATCH 43/49] Update error_codes.rs with new subslice syntax. --- src/librustc_typeck/error_codes.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 19d5e8b3e8447..b4c856921198e 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -3497,8 +3497,8 @@ Example of erroneous code: let r = &[1, 2]; match r { - &[a, b, c, rest..] => { // error: pattern requires at least 3 - // elements but array has 2 + &[a, b, c, rest @ ..] => { // error: pattern requires at least 3 + // elements but array has 2 println!("a={}, b={}, c={} rest={:?}", a, b, c, rest); } } @@ -3512,7 +3512,7 @@ requires. You can match an arbitrary number of remaining elements with `..`: let r = &[1, 2, 3, 4, 5]; match r { - &[a, b, c, rest..] => { // ok! + &[a, b, c, rest @ ..] => { // ok! // prints `a=1, b=2, c=3 rest=[4, 5]` println!("a={}, b={}, c={} rest={:?}", a, b, c, rest); } From 397a027aa76cc3a615858d05efe34857fe4fc8dc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 11 Jul 2019 16:11:09 +0200 Subject: [PATCH 44/49] Use AstP more in lowering. --- src/librustc/hir/lowering.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 094a509a18d69..78596a5b40573 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1158,7 +1158,7 @@ impl<'a> LoweringContext<'a> { &mut self, capture_clause: CaptureBy, closure_node_id: NodeId, - ret_ty: Option>, + ret_ty: Option>, span: Span, body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr, ) -> hir::ExprKind { From becdba80ea777afb8ebcd482fc657728b1661dbf Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 24 Jul 2019 02:00:46 +0200 Subject: [PATCH 45/49] Address comments in lowering + parsing. --- src/librustc/hir/lowering.rs | 20 ++++++++++---------- src/libsyntax/parse/parser.rs | 11 +++++++---- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 78596a5b40573..bc2c835e21050 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4185,7 +4185,7 @@ impl<'a> LoweringContext<'a> { ParamMode::Optional, ImplTraitContext::disallowed(), ); - let (pats, ddpos) = self.lower_pat_tuple(&*pats, "tuple struct"); + let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); hir::PatKind::TupleStruct(qpath, pats, ddpos) } PatKind::Path(ref qself, ref path) => { @@ -4224,7 +4224,7 @@ impl<'a> LoweringContext<'a> { hir::PatKind::Struct(qpath, fs, etc) } PatKind::Tuple(ref pats) => { - let (pats, ddpos) = self.lower_pat_tuple(&*pats, "tuple"); + let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple"); hir::PatKind::Tuple(pats, ddpos) } PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), @@ -4245,7 +4245,7 @@ impl<'a> LoweringContext<'a> { PatKind::Mac(_) => panic!("Shouldn't exist here"), }; - self.pat_bound(p, node) + self.pat_with_node_id_of(p, node) } fn lower_pat_tuple( @@ -4291,14 +4291,14 @@ impl<'a> LoweringContext<'a> { match pat.node { PatKind::Rest => { prev_rest_span = Some(pat.span); - slice = Some(self.pat_bound_wild(pat)); + slice = Some(self.pat_wild_with_node_id_of(pat)); break; }, PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { prev_rest_span = Some(sub.span); - let lower_sub = |this: &mut Self| Some(this.pat_bound_wild(sub)); + let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); let node = self.lower_pat_ident(pat, bm, ident, lower_sub); - slice = Some(self.pat_bound(pat, node)); + slice = Some(self.pat_with_node_id_of(pat, node)); break; }, _ => {} @@ -4314,7 +4314,7 @@ impl<'a> LoweringContext<'a> { PatKind::Rest => Some(pat.span), PatKind::Ident(.., Some(ref sub)) if sub.is_rest() => { // The `HirValidator` is merciless; add a `_` pattern to avoid ICEs. - after.push(self.pat_bound_wild(pat)); + after.push(self.pat_wild_with_node_id_of(pat)); Some(sub.span) }, _ => None, @@ -4362,12 +4362,12 @@ impl<'a> LoweringContext<'a> { } } - fn pat_bound_wild(&mut self, p: &Pat) -> P { - self.pat_bound(p, hir::PatKind::Wild) + fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> P { + self.pat_with_node_id_of(p, hir::PatKind::Wild) } /// Construct a `Pat` with the `HirId` of `p.id` lowered. - fn pat_bound(&mut self, p: &Pat, node: hir::PatKind) -> P { + fn pat_with_node_id_of(&mut self, p: &Pat, node: hir::PatKind) -> P { P(hir::Pat { hir_id: self.lower_node_id(p.id), node, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 34ed7f50907b1..8f8ed4111808d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3748,8 +3748,9 @@ impl<'a> Parser<'a> { }) } - /// Parse a parentesized comma separated sequence of patterns until `delim` is reached. - fn parse_recover_pat_list(&mut self) -> PResult<'a, ()> { + /// Parse and throw away a parentesized comma separated + /// sequence of patterns until `)` is reached. + fn skip_pat_list(&mut self) -> PResult<'a, ()> { while !self.check(&token::CloseDelim(token::Paren)) { self.parse_pat(None)?; if !self.eat(&token::Comma) { @@ -3772,7 +3773,7 @@ impl<'a> Parser<'a> { // later. let comma_span = self.token.span; self.bump(); - if let Err(mut err) = self.parse_recover_pat_list() { + if let Err(mut err) = self.skip_pat_list() { // We didn't expect this to work anyway; we just wanted // to advance to the end of the comma-sequence so we know // the span to suggest parenthesizing @@ -3877,9 +3878,11 @@ impl<'a> Parser<'a> { pat = PatKind::Ref(subpat, mutbl); } token::OpenDelim(token::Paren) => { - // Parse `(pat, pat, pat, ...)` as tuple pattern. + // Parse a tuple or parenthesis pattern. let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| p.parse_pat(None))?; + // Here, `(pat,)` is a tuple pattern. + // For backward compatibility, `(..)` is a tuple pattern as well. pat = if fields.len() == 1 && !(trailing_comma || fields[0].is_rest()) { PatKind::Paren(fields.into_iter().nth(0).unwrap()) } else { From 5f4dd1d19a6851389c7e27902cd1fb6ebbb46dcc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 24 Jul 2019 02:30:37 +0200 Subject: [PATCH 46/49] Address comments re. off-topic errors. --- src/test/ui/parser/match-vec-invalid.rs | 5 ++-- src/test/ui/parser/match-vec-invalid.stderr | 15 ++++++---- src/test/ui/parser/pat-lt-bracket-6.rs | 9 ++++-- src/test/ui/parser/pat-lt-bracket-6.stderr | 31 ++++++++++----------- src/test/ui/parser/pat-lt-bracket-7.rs | 9 ++++-- src/test/ui/parser/pat-lt-bracket-7.stderr | 23 +++++++-------- 6 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/parser/match-vec-invalid.rs index d14fdc4e22e31..00f4374b256d2 100644 --- a/src/test/ui/parser/match-vec-invalid.rs +++ b/src/test/ui/parser/match-vec-invalid.rs @@ -1,12 +1,13 @@ fn main() { - let a = Vec::new(); + let a: &[u8] = &[]; match a { [1, tail @ .., tail @ ..] => {}, //~^ ERROR identifier `tail` is bound more than once in the same pattern //~| ERROR subslice patterns are unstable //~| ERROR subslice patterns are unstable //~| ERROR `..` can only be used once per slice pattern - //~| ERROR expected an array or slice, found `std::vec::Vec<_>` _ => () } } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr index 49d5a83c5a9f9..0956ac21b7f1e 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/parser/match-vec-invalid.stderr @@ -30,13 +30,16 @@ LL | [1, tail @ .., tail @ ..] => {}, | | | previously used here -error[E0529]: expected an array or slice, found `std::vec::Vec<_>` - --> $DIR/match-vec-invalid.rs:4:9 +error[E0308]: mismatched types + --> $DIR/match-vec-invalid.rs:13:30 | -LL | [1, tail @ .., tail @ ..] => {}, - | ^^^^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `std::vec::Vec<_>` +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer + | + = note: expected type `()` + found type `{integer}` error: aborting due to 5 previous errors -Some errors have detailed explanations: E0416, E0529, E0658. -For more information about an error, try `rustc --explain E0416`. +Some errors have detailed explanations: E0308, E0416, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs index 69c4bfb23c2f9..7b9721830993e 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.rs +++ b/src/test/ui/parser/pat-lt-bracket-6.rs @@ -1,6 +1,9 @@ fn main() { + struct Test(&'static u8, [u8; 0]); + let x = Test(&0, []); + let Test(&desc[..]) = x; //~ ERROR: expected one of `)`, `,`, or `@`, found `[` - //~^ ERROR cannot find value `x` in this scope - //~| ERROR cannot find tuple struct/variant `Test` in this scope - //~| ERROR subslice patterns are unstable + //~^ ERROR subslice patterns are unstable } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr index 45270b314a9b7..201465b2c850c 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.stderr +++ b/src/test/ui/parser/pat-lt-bracket-6.stderr @@ -1,23 +1,11 @@ error: expected one of `)`, `,`, or `@`, found `[` - --> $DIR/pat-lt-bracket-6.rs:2:19 + --> $DIR/pat-lt-bracket-6.rs:5:19 | LL | let Test(&desc[..]) = x; | ^ expected one of `)`, `,`, or `@` here -error[E0425]: cannot find value `x` in this scope - --> $DIR/pat-lt-bracket-6.rs:2:27 - | -LL | let Test(&desc[..]) = x; - | ^ not found in this scope - -error[E0531]: cannot find tuple struct/variant `Test` in this scope - --> $DIR/pat-lt-bracket-6.rs:2:9 - | -LL | let Test(&desc[..]) = x; - | ^^^^ not found in this scope - error[E0658]: subslice patterns are unstable - --> $DIR/pat-lt-bracket-6.rs:2:20 + --> $DIR/pat-lt-bracket-6.rs:5:20 | LL | let Test(&desc[..]) = x; | ^^ @@ -25,7 +13,16 @@ LL | let Test(&desc[..]) = x; = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add `#![feature(slice_patterns)]` to the crate attributes to enable -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/pat-lt-bracket-6.rs:9:30 + | +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer + | + = note: expected type `()` + found type `{integer}` + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0425, E0658. -For more information about an error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-lt-bracket-7.rs b/src/test/ui/parser/pat-lt-bracket-7.rs index 1060d705e6e31..020fdb845e8b5 100644 --- a/src/test/ui/parser/pat-lt-bracket-7.rs +++ b/src/test/ui/parser/pat-lt-bracket-7.rs @@ -1,5 +1,8 @@ fn main() { - for thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[` - //~^ ERROR cannot find value `foo` in this scope - //~| ERROR cannot find tuple struct/variant `thing` in this scope + struct Thing(u8, [u8; 0]); + let foo = core::iter::empty(); + + for Thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[` } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr index 3e4bff7cbd759..17557efa49e80 100644 --- a/src/test/ui/parser/pat-lt-bracket-7.stderr +++ b/src/test/ui/parser/pat-lt-bracket-7.stderr @@ -1,21 +1,18 @@ error: expected one of `)`, `,`, or `@`, found `[` - --> $DIR/pat-lt-bracket-7.rs:2:16 + --> $DIR/pat-lt-bracket-7.rs:5:16 | -LL | for thing(x[]) in foo {} +LL | for Thing(x[]) in foo {} | ^ expected one of `)`, `,`, or `@` here -error[E0425]: cannot find value `foo` in this scope - --> $DIR/pat-lt-bracket-7.rs:2:23 +error[E0308]: mismatched types + --> $DIR/pat-lt-bracket-7.rs:8:30 | -LL | for thing(x[]) in foo {} - | ^^^ not found in this scope - -error[E0531]: cannot find tuple struct/variant `thing` in this scope - --> $DIR/pat-lt-bracket-7.rs:2:9 +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer | -LL | for thing(x[]) in foo {} - | ^^^^^ not found in this scope + = note: expected type `()` + found type `{integer}` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0308`. From 18ccd6a33c9601ec68d87cf28f4a7e97a2623c95 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 24 Jul 2019 04:01:12 +0200 Subject: [PATCH 47/49] Add exceptions for ExprKind::Err/TyKind::Error. --- src/librustc_passes/ast_validation.rs | 2 +- src/librustc_typeck/check/_match.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index b550029d9786d..473ba21c77b6d 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -287,7 +287,7 @@ impl<'a> AstValidator<'a> { // ``` fn check_expr_within_pat(&self, expr: &Expr, allow_paths: bool) { match expr.node { - ExprKind::Lit(..) => {} + ExprKind::Lit(..) | ExprKind::Err => {} ExprKind::Path(..) if allow_paths => {} ExprKind::Unary(UnOp::Neg, ref inner) if match inner.node { ExprKind::Lit(_) => true, _ => false } => {} diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 3f0604b84b7d7..defa6fe4ce15e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -196,7 +196,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let rhs_ty = self.check_expr(end); // Check that both end-points are of numeric or char type. - let numeric_or_char = |ty: Ty<'_>| ty.is_numeric() || ty.is_char(); + let numeric_or_char = |ty: Ty<'_>| { + ty.is_numeric() + || ty.is_char() + || ty.references_error() + }; let lhs_compat = numeric_or_char(lhs_ty); let rhs_compat = numeric_or_char(rhs_ty); From 87742073a0bb2571805f91487a129bc53d16dc88 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 24 Jul 2019 04:01:38 +0200 Subject: [PATCH 48/49] And --bless tests accordingly for those exceptions. --- src/test/ui/associated-path-shl.rs | 1 - src/test/ui/associated-path-shl.stderr | 16 +- ...xclusive_range_pattern_syntax_collision.rs | 3 +- ...sive_range_pattern_syntax_collision.stderr | 20 +- ...clusive_range_pattern_syntax_collision2.rs | 3 +- ...ive_range_pattern_syntax_collision2.stderr | 22 +- ...clusive_range_pattern_syntax_collision3.rs | 3 +- ...ive_range_pattern_syntax_collision3.stderr | 21 +- src/test/ui/parser/pat-tuple-4.rs | 9 +- src/test/ui/parser/pat-tuple-4.stderr | 40 +- src/test/ui/parser/pat-tuple-5.rs | 8 +- src/test/ui/parser/pat-tuple-5.stderr | 42 +- src/test/ui/parser/recover-range-pats.rs | 132 ++---- src/test/ui/parser/recover-range-pats.stderr | 412 ++++-------------- 14 files changed, 198 insertions(+), 534 deletions(-) diff --git a/src/test/ui/associated-path-shl.rs b/src/test/ui/associated-path-shl.rs index d159082ab7ad5..20a6fd83faa32 100644 --- a/src/test/ui/associated-path-shl.rs +++ b/src/test/ui/associated-path-shl.rs @@ -5,6 +5,5 @@ fn main() { let _ = <::B>::C; //~ ERROR cannot find type `A` in this scope let <::B>::C; //~ ERROR cannot find type `A` in this scope let 0 ..= <::B>::C; //~ ERROR cannot find type `A` in this scope - //~^ ERROR only char and numeric types are allowed in range patterns <::B>::C; //~ ERROR cannot find type `A` in this scope } diff --git a/src/test/ui/associated-path-shl.stderr b/src/test/ui/associated-path-shl.stderr index 23918ed2e3912..71ee93f4835fb 100644 --- a/src/test/ui/associated-path-shl.stderr +++ b/src/test/ui/associated-path-shl.stderr @@ -23,21 +23,11 @@ LL | let 0 ..= <::B>::C; | ^ not found in this scope error[E0412]: cannot find type `A` in this scope - --> $DIR/associated-path-shl.rs:9:7 + --> $DIR/associated-path-shl.rs:8:7 | LL | <::B>::C; | ^ not found in this scope -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/associated-path-shl.rs:7:15 - | -LL | let 0 ..= <::B>::C; - | ^^^^^^^^^^^ ranges require char or numeric types - | - = note: start type: {integer} - = note: end type: [type error] - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0029, E0412. -For more information about an error, try `rustc --explain E0029`. +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs index a3b7a80642a72..d97b693f52098 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs @@ -4,8 +4,7 @@ fn main() { match [5..4, 99..105, 43..44] { [_, 99.., _] => {}, //~^ ERROR `X..` range patterns are not supported - //~| ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR only char and numeric types are allowed in range patterns + //~| ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr index 237b26db7c0d9..4ecd8515ee164 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr @@ -4,21 +4,17 @@ error: `X..` range patterns are not supported LL | [_, 99.., _] => {}, | ^^^^ help: try using the maximum value for the type: `99..MAX` -error: arbitrary expressions aren't allowed in patterns +error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` LL | [_, 99.., _] => {}, - | ^^^^ - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 - | -LL | [_, 99.., _] => {}, - | ^^^^ ranges require char or numeric types + | ^^^^ expected struct `std::ops::Range`, found integer | - = note: start type: {integer} - = note: end type: [type error] + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0029`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs index 197953a1dc4ba..09f459c9862ee 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs @@ -4,9 +4,8 @@ fn main() { match [5..4, 99..105, 43..44] { [_, 99..] => {}, //~^ ERROR `X..` range patterns are not supported - //~| ERROR arbitrary expressions aren't allowed in patterns //~| ERROR pattern requires 2 elements but array has 3 - //~| ERROR only char and numeric types are allowed in range patterns + //~| ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr index b7a64a0ba677c..922d26923158b 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr @@ -4,28 +4,24 @@ error: `X..` range patterns are not supported LL | [_, 99..] => {}, | ^^^^ help: try using the maximum value for the type: `99..MAX` -error: arbitrary expressions aren't allowed in patterns - --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 - | -LL | [_, 99..] => {}, - | ^^^^ - error[E0527]: pattern requires 2 elements but array has 3 --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:9 | LL | [_, 99..] => {}, | ^^^^^^^^^ expected 3 elements -error[E0029]: only char and numeric types are allowed in range patterns +error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` LL | [_, 99..] => {}, - | ^^^^ ranges require char or numeric types + | ^^^^ expected struct `std::ops::Range`, found integer | - = note: start type: {integer} - = note: end type: [type error] + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0029, E0527. -For more information about an error, try `rustc --explain E0029`. +Some errors have detailed explanations: E0308, E0527. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs index 782777c10797d..95e58b1d48c88 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs @@ -4,8 +4,7 @@ fn main() { match [5..4, 99..105, 43..44] { [..9, 99..100, _] => {}, //~^ ERROR `..X` range patterns are not supported - //~| ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR only char and numeric types are allowed in range patterns + //~| ERROR mismatched types //~| ERROR mismatched types _ => {}, } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr index 7cc1976def402..8907b875f8e11 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr @@ -4,20 +4,16 @@ error: `..X` range patterns are not supported LL | [..9, 99..100, _] => {}, | ^^^ help: try using the minimum value for the type: `MIN..9` -error: arbitrary expressions aren't allowed in patterns - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 - | -LL | [..9, 99..100, _] => {}, - | ^^^ - -error[E0029]: only char and numeric types are allowed in range patterns +error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` LL | [..9, 99..100, _] => {}, - | ^^^ ranges require char or numeric types + | ^^^ expected struct `std::ops::Range`, found integer | - = note: start type: [type error] - = note: end type: {integer} + = note: expected type `std::ops::Range<{integer}>` + found type `{integer}` error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15 @@ -30,7 +26,6 @@ LL | [..9, 99..100, _] => {}, = note: expected type `std::ops::Range<{integer}>` found type `{integer}` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0029, E0308. -For more information about an error, try `rustc --explain E0029`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-tuple-4.rs b/src/test/ui/parser/pat-tuple-4.rs index 9eedb0f902342..2f03160430a22 100644 --- a/src/test/ui/parser/pat-tuple-4.rs +++ b/src/test/ui/parser/pat-tuple-4.rs @@ -1,10 +1,11 @@ fn main() { + const PAT: u8 = 0; + match 0 { - (.. pat) => {} + (.. PAT) => {} //~^ ERROR `..X` range patterns are not supported - //~| ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR cannot find value `pat` in this scope //~| ERROR exclusive range pattern syntax is experimental - //~| ERROR only char and numeric types are allowed in range patterns } } + +const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-tuple-4.stderr b/src/test/ui/parser/pat-tuple-4.stderr index d126163476c9b..af3ecce184649 100644 --- a/src/test/ui/parser/pat-tuple-4.stderr +++ b/src/test/ui/parser/pat-tuple-4.stderr @@ -1,40 +1,28 @@ error: `..X` range patterns are not supported - --> $DIR/pat-tuple-4.rs:3:10 + --> $DIR/pat-tuple-4.rs:5:10 | -LL | (.. pat) => {} - | ^^^^^^ help: try using the minimum value for the type: `MIN..pat` - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/pat-tuple-4.rs:3:10 - | -LL | (.. pat) => {} - | ^^^^^^ - -error[E0425]: cannot find value `pat` in this scope - --> $DIR/pat-tuple-4.rs:3:13 - | -LL | (.. pat) => {} - | ^^^ not found in this scope +LL | (.. PAT) => {} + | ^^^^^^ help: try using the minimum value for the type: `MIN..PAT` error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/pat-tuple-4.rs:3:10 + --> $DIR/pat-tuple-4.rs:5:10 | -LL | (.. pat) => {} +LL | (.. PAT) => {} | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/37854 = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/pat-tuple-4.rs:3:10 +error[E0308]: mismatched types + --> $DIR/pat-tuple-4.rs:11:30 | -LL | (.. pat) => {} - | ^^^^^^ ranges require char or numeric types +LL | const RECOVERY_WITNESS: () = 0; + | ^ expected (), found integer | - = note: start type: [type error] - = note: end type: [type error] + = note: expected type `()` + found type `{integer}` -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0029, E0425, E0658. -For more information about an error, try `rustc --explain E0029`. +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-tuple-5.rs b/src/test/ui/parser/pat-tuple-5.rs index 5e191ca88e296..5334ef93bb3bd 100644 --- a/src/test/ui/parser/pat-tuple-5.rs +++ b/src/test/ui/parser/pat-tuple-5.rs @@ -1,10 +1,10 @@ fn main() { + const PAT: u8 = 0; + match (0, 1) { - (pat ..) => {} + (PAT ..) => {} //~^ ERROR `X..` range patterns are not supported - //~| ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR cannot find value `pat` in this scope //~| ERROR exclusive range pattern syntax is experimental - //~| ERROR only char and numeric types are allowed in range patterns + //~| ERROR mismatched types } } diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr index 06f2a59d90906..09ebdc29a2161 100644 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ b/src/test/ui/parser/pat-tuple-5.stderr @@ -1,40 +1,30 @@ error: `X..` range patterns are not supported - --> $DIR/pat-tuple-5.rs:3:10 + --> $DIR/pat-tuple-5.rs:5:10 | -LL | (pat ..) => {} - | ^^^^^^ help: try using the maximum value for the type: `pat..MAX` - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/pat-tuple-5.rs:3:10 - | -LL | (pat ..) => {} - | ^^^^^^ - -error[E0425]: cannot find value `pat` in this scope - --> $DIR/pat-tuple-5.rs:3:10 - | -LL | (pat ..) => {} - | ^^^ not found in this scope +LL | (PAT ..) => {} + | ^^^^^^ help: try using the maximum value for the type: `PAT..MAX` error[E0658]: exclusive range pattern syntax is experimental - --> $DIR/pat-tuple-5.rs:3:10 + --> $DIR/pat-tuple-5.rs:5:10 | -LL | (pat ..) => {} +LL | (PAT ..) => {} | ^^^^^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/37854 = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/pat-tuple-5.rs:3:10 +error[E0308]: mismatched types + --> $DIR/pat-tuple-5.rs:5:10 | -LL | (pat ..) => {} - | ^^^^^^ ranges require char or numeric types +LL | match (0, 1) { + | ------ this match expression has type `({integer}, {integer})` +LL | (PAT ..) => {} + | ^^^^^^ expected tuple, found u8 | - = note: start type: [type error] - = note: end type: [type error] + = note: expected type `({integer}, {integer})` + found type `u8` -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0029, E0425, E0658. -For more information about an error, try `rustc --explain E0029`. +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs index ffec50c4e8314..c66652ff4fa01 100644 --- a/src/test/ui/parser/recover-range-pats.rs +++ b/src/test/ui/parser/recover-range-pats.rs @@ -55,105 +55,69 @@ fn inclusive2_from_to() { } fn exclusive_from() { - if let 0.. = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..` range patterns are not supported - if let X.. = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..` range patterns are not supported - if let true.. = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..` range patterns are not supported - if let .0.. = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..` range patterns are not supported - //~| ERROR float literals must have an integer part + if let 0.. = 0 {} //~ ERROR `X..` range patterns are not supported + if let X.. = 0 {} //~ ERROR `X..` range patterns are not supported + if let true.. = 0 {} //~ ERROR `X..` range patterns are not supported + //~^ ERROR only char and numeric types + if let .0.. = 0 {} //~ ERROR `X..` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types } fn inclusive_from() { - if let 0..= = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..=` range patterns are not supported - if let X..= = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..=` range patterns are not supported - if let true..= = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..=` range patterns are not supported - if let .0..= = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X..=` range patterns are not supported - //~| ERROR float literals must have an integer part + if let 0..= = 0 {} //~ ERROR `X..=` range patterns are not supported + if let X..= = 0 {} //~ ERROR `X..=` range patterns are not supported + if let true..= = 0 {} //~ ERROR `X..=` range patterns are not supported + //~| ERROR only char and numeric types + if let .0..= = 0 {} //~ ERROR `X..=` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types } fn inclusive2_from() { - if let 0... = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X...` range patterns are not supported - //~| ERROR `...` range patterns are deprecated - if let X... = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X...` range patterns are not supported - //~| ERROR `...` range patterns are deprecated - if let true... = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X...` range patterns are not supported - //~| ERROR `...` range patterns are deprecated - if let .0... = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `X...` range patterns are not supported - //~| ERROR float literals must have an integer part + if let 0... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let X... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let true... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + //~| ERROR only char and numeric types + if let .0... = 0 {} //~ ERROR `X...` range patterns are not supported + //~^ ERROR float literals must have an integer part //~| ERROR `...` range patterns are deprecated + //~| ERROR mismatched types } fn exclusive_to() { - if let ..0 = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..X` range patterns are not supported - if let ..Y = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..X` range patterns are not supported - if let ..true = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..X` range patterns are not supported - if let .. .0 = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..X` range patterns are not supported - //~| ERROR float literals must have an integer part + if let ..0 = 0 {} //~ ERROR `..X` range patterns are not supported + if let ..Y = 0 {} //~ ERROR `..X` range patterns are not supported + if let ..true = 0 {} //~ ERROR `..X` range patterns are not supported + //~| ERROR only char and numeric types + if let .. .0 = 0 {} //~ ERROR `..X` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types } fn inclusive_to() { - if let ..=3 = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..=X` range patterns are not supported - if let ..=Y = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..=X` range patterns are not supported - if let ..=true = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..=X` range patterns are not supported - if let ..=.0 = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `..=X` range patterns are not supported - //~| ERROR float literals must have an integer part + if let ..=3 = 0 {} //~ ERROR `..=X` range patterns are not supported + if let ..=Y = 0 {} //~ ERROR `..=X` range patterns are not supported + if let ..=true = 0 {} //~ ERROR `..=X` range patterns are not supported + //~| ERROR only char and numeric types + if let ..=.0 = 0 {} //~ ERROR `..=X` range patterns are not supported + //~^ ERROR float literals must have an integer part + //~| ERROR mismatched types } fn inclusive2_to() { - if let ...3 = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `...X` range patterns are not supported - //~| ERROR `...` range patterns are deprecated - if let ...Y = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `...X` range patterns are not supported - //~| ERROR `...` range patterns are deprecated - if let ...true = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `...X` range patterns are not supported - //~| ERROR `...` range patterns are deprecated - if let ....3 = 0 {} //~ ERROR only char and numeric types - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR `...X` range patterns are not supported - //~| ERROR float literals must have an integer part + if let ...3 = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let ...Y = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + if let ...true = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR `...` range patterns are deprecated + //~| ERROR only char and numeric types + if let ....3 = 0 {} //~ ERROR `...X` range patterns are not supported + //~^ ERROR float literals must have an integer part //~| ERROR `...` range patterns are deprecated + //~| ERROR mismatched types } diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index a4d321fae8d30..c50d5e6eb6153 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -41,322 +41,178 @@ LL | if let 0.. = 0 {} | ^^^ help: try using the maximum value for the type: `0..MAX` error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:61:12 + --> $DIR/recover-range-pats.rs:59:12 | LL | if let X.. = 0 {} | ^^^ help: try using the maximum value for the type: `X..MAX` error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:64:12 + --> $DIR/recover-range-pats.rs:60:12 | LL | if let true.. = 0 {} | ^^^^^^ help: try using the maximum value for the type: `true..MAX` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:67:12 + --> $DIR/recover-range-pats.rs:62:12 | LL | if let .0.. = 0 {} | ^^ help: must have an integer part: `0.0` error: `X..` range patterns are not supported - --> $DIR/recover-range-pats.rs:67:12 + --> $DIR/recover-range-pats.rs:62:12 | LL | if let .0.. = 0 {} | ^^^^ help: try using the maximum value for the type: `0.0..MAX` error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:74:12 + --> $DIR/recover-range-pats.rs:68:12 | LL | if let 0..= = 0 {} | ^^^^ help: try using the maximum value for the type: `0..=MAX` error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:77:12 + --> $DIR/recover-range-pats.rs:69:12 | LL | if let X..= = 0 {} | ^^^^ help: try using the maximum value for the type: `X..=MAX` error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:80:12 + --> $DIR/recover-range-pats.rs:70:12 | LL | if let true..= = 0 {} | ^^^^^^^ help: try using the maximum value for the type: `true..=MAX` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:83:12 + --> $DIR/recover-range-pats.rs:72:12 | LL | if let .0..= = 0 {} | ^^ help: must have an integer part: `0.0` error: `X..=` range patterns are not supported - --> $DIR/recover-range-pats.rs:83:12 + --> $DIR/recover-range-pats.rs:72:12 | LL | if let .0..= = 0 {} | ^^^^^ help: try using the maximum value for the type: `0.0..=MAX` error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:90:12 + --> $DIR/recover-range-pats.rs:78:12 | LL | if let 0... = 0 {} | ^^^^ help: try using the maximum value for the type: `0...MAX` error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:94:12 + --> $DIR/recover-range-pats.rs:80:12 | LL | if let X... = 0 {} | ^^^^ help: try using the maximum value for the type: `X...MAX` error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:98:12 + --> $DIR/recover-range-pats.rs:82:12 | LL | if let true... = 0 {} | ^^^^^^^ help: try using the maximum value for the type: `true...MAX` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:102:12 + --> $DIR/recover-range-pats.rs:85:12 | LL | if let .0... = 0 {} | ^^ help: must have an integer part: `0.0` error: `X...` range patterns are not supported - --> $DIR/recover-range-pats.rs:102:12 + --> $DIR/recover-range-pats.rs:85:12 | LL | if let .0... = 0 {} | ^^^^^ help: try using the maximum value for the type: `0.0...MAX` error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:110:12 + --> $DIR/recover-range-pats.rs:92:12 | LL | if let ..0 = 0 {} | ^^^ help: try using the minimum value for the type: `MIN..0` error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:113:12 + --> $DIR/recover-range-pats.rs:93:12 | LL | if let ..Y = 0 {} | ^^^ help: try using the minimum value for the type: `MIN..Y` error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:116:12 + --> $DIR/recover-range-pats.rs:94:12 | LL | if let ..true = 0 {} | ^^^^^^ help: try using the minimum value for the type: `MIN..true` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:119:15 + --> $DIR/recover-range-pats.rs:96:15 | LL | if let .. .0 = 0 {} | ^^ help: must have an integer part: `0.0` error: `..X` range patterns are not supported - --> $DIR/recover-range-pats.rs:119:12 + --> $DIR/recover-range-pats.rs:96:12 | LL | if let .. .0 = 0 {} | ^^^^^ help: try using the minimum value for the type: `MIN..0.0` error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:126:12 + --> $DIR/recover-range-pats.rs:102:12 | LL | if let ..=3 = 0 {} | ^^^^ help: try using the minimum value for the type: `MIN..=3` error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:129:12 + --> $DIR/recover-range-pats.rs:103:12 | LL | if let ..=Y = 0 {} | ^^^^ help: try using the minimum value for the type: `MIN..=Y` error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:132:12 + --> $DIR/recover-range-pats.rs:104:12 | LL | if let ..=true = 0 {} | ^^^^^^^ help: try using the minimum value for the type: `MIN..=true` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:135:15 + --> $DIR/recover-range-pats.rs:106:15 | LL | if let ..=.0 = 0 {} | ^^ help: must have an integer part: `0.0` error: `..=X` range patterns are not supported - --> $DIR/recover-range-pats.rs:135:12 + --> $DIR/recover-range-pats.rs:106:12 | LL | if let ..=.0 = 0 {} | ^^^^^ help: try using the minimum value for the type: `MIN..=0.0` error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:142:12 + --> $DIR/recover-range-pats.rs:112:12 | LL | if let ...3 = 0 {} | ^^^^ help: try using the minimum value for the type: `MIN...3` error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:146:12 + --> $DIR/recover-range-pats.rs:114:12 | LL | if let ...Y = 0 {} | ^^^^ help: try using the minimum value for the type: `MIN...Y` error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:150:12 + --> $DIR/recover-range-pats.rs:116:12 | LL | if let ...true = 0 {} | ^^^^^^^ help: try using the minimum value for the type: `MIN...true` error: float literals must have an integer part - --> $DIR/recover-range-pats.rs:154:15 + --> $DIR/recover-range-pats.rs:119:15 | LL | if let ....3 = 0 {} | ^^ help: must have an integer part: `0.3` error: `...X` range patterns are not supported - --> $DIR/recover-range-pats.rs:154:12 - | -LL | if let ....3 = 0 {} - | ^^^^^ help: try using the minimum value for the type: `MIN...0.3` - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:58:12 - | -LL | if let 0.. = 0 {} - | ^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:61:12 - | -LL | if let X.. = 0 {} - | ^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:64:12 - | -LL | if let true.. = 0 {} - | ^^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:67:12 - | -LL | if let .0.. = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:74:12 - | -LL | if let 0..= = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:77:12 - | -LL | if let X..= = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:80:12 - | -LL | if let true..= = 0 {} - | ^^^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:83:12 - | -LL | if let .0..= = 0 {} - | ^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:90:12 - | -LL | if let 0... = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:94:12 - | -LL | if let X... = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:98:12 - | -LL | if let true... = 0 {} - | ^^^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:102:12 - | -LL | if let .0... = 0 {} - | ^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:110:12 - | -LL | if let ..0 = 0 {} - | ^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:113:12 - | -LL | if let ..Y = 0 {} - | ^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:116:12 - | -LL | if let ..true = 0 {} - | ^^^^^^ - -error: arbitrary expressions aren't allowed in patterns --> $DIR/recover-range-pats.rs:119:12 | -LL | if let .. .0 = 0 {} - | ^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:126:12 - | -LL | if let ..=3 = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:129:12 - | -LL | if let ..=Y = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:132:12 - | -LL | if let ..=true = 0 {} - | ^^^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:135:12 - | -LL | if let ..=.0 = 0 {} - | ^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:142:12 - | -LL | if let ...3 = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:146:12 - | -LL | if let ...Y = 0 {} - | ^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:150:12 - | -LL | if let ...true = 0 {} - | ^^^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/recover-range-pats.rs:154:12 - | LL | if let ....3 = 0 {} - | ^^^^^ + | ^^^^^ help: try using the minimum value for the type: `MIN...0.3` error: `...` range patterns are deprecated --> $DIR/recover-range-pats.rs:41:13 @@ -413,49 +269,49 @@ LL | if let X... .0 = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:90:13 + --> $DIR/recover-range-pats.rs:78:13 | LL | if let 0... = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:94:13 + --> $DIR/recover-range-pats.rs:80:13 | LL | if let X... = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:98:16 + --> $DIR/recover-range-pats.rs:82:16 | LL | if let true... = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:102:14 + --> $DIR/recover-range-pats.rs:85:14 | LL | if let .0... = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:142:12 + --> $DIR/recover-range-pats.rs:112:12 | LL | if let ...3 = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:146:12 + --> $DIR/recover-range-pats.rs:114:12 | LL | if let ...Y = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:150:12 + --> $DIR/recover-range-pats.rs:116:12 | LL | if let ...true = 0 {} | ^^^ help: use `..=` for an inclusive range error: `...` range patterns are deprecated - --> $DIR/recover-range-pats.rs:154:12 + --> $DIR/recover-range-pats.rs:119:12 | LL | if let ....3 = 0 {} | ^^^ help: use `..=` for an inclusive range @@ -569,222 +425,114 @@ LL | if let X... .0 = 0 {} found type `{float}` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:58:12 - | -LL | if let 0.. = 0 {} - | ^^^ ranges require char or numeric types - | - = note: start type: {integer} - = note: end type: [type error] - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:61:12 - | -LL | if let X.. = 0 {} - | ^^^ ranges require char or numeric types - | - = note: start type: u8 - = note: end type: [type error] - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:64:12 + --> $DIR/recover-range-pats.rs:60:12 | LL | if let true.. = 0 {} - | ^^^^^^ ranges require char or numeric types + | ^^^^ ranges require char or numeric types | = note: start type: bool = note: end type: [type error] -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:67:12 +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:62:12 | LL | if let .0.. = 0 {} - | ^^^^ ranges require char or numeric types + | ^^^^ expected integer, found floating-point number | - = note: start type: {float} - = note: end type: [type error] - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:74:12 - | -LL | if let 0..= = 0 {} - | ^^^^ ranges require char or numeric types - | - = note: start type: {integer} - = note: end type: [type error] + = note: expected type `{integer}` + found type `{float}` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:77:12 - | -LL | if let X..= = 0 {} - | ^^^^ ranges require char or numeric types - | - = note: start type: u8 - = note: end type: [type error] - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:80:12 + --> $DIR/recover-range-pats.rs:70:12 | LL | if let true..= = 0 {} - | ^^^^^^^ ranges require char or numeric types + | ^^^^ ranges require char or numeric types | = note: start type: bool = note: end type: [type error] -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:83:12 +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:72:12 | LL | if let .0..= = 0 {} - | ^^^^^ ranges require char or numeric types - | - = note: start type: {float} - = note: end type: [type error] - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:90:12 - | -LL | if let 0... = 0 {} - | ^^^^ ranges require char or numeric types - | - = note: start type: {integer} - = note: end type: [type error] - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:94:12 - | -LL | if let X... = 0 {} - | ^^^^ ranges require char or numeric types + | ^^^^^ expected integer, found floating-point number | - = note: start type: u8 - = note: end type: [type error] + = note: expected type `{integer}` + found type `{float}` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:98:12 + --> $DIR/recover-range-pats.rs:82:12 | LL | if let true... = 0 {} - | ^^^^^^^ ranges require char or numeric types + | ^^^^ ranges require char or numeric types | = note: start type: bool = note: end type: [type error] -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:102:12 +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:85:12 | LL | if let .0... = 0 {} - | ^^^^^ ranges require char or numeric types - | - = note: start type: {float} - = note: end type: [type error] - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:110:12 - | -LL | if let ..0 = 0 {} - | ^^^ ranges require char or numeric types - | - = note: start type: [type error] - = note: end type: {integer} - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:113:12 - | -LL | if let ..Y = 0 {} - | ^^^ ranges require char or numeric types + | ^^^^^ expected integer, found floating-point number | - = note: start type: [type error] - = note: end type: u8 + = note: expected type `{integer}` + found type `{float}` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:116:12 + --> $DIR/recover-range-pats.rs:94:14 | LL | if let ..true = 0 {} - | ^^^^^^ ranges require char or numeric types + | ^^^^ ranges require char or numeric types | = note: start type: [type error] = note: end type: bool -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:119:12 +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:96:12 | LL | if let .. .0 = 0 {} - | ^^^^^ ranges require char or numeric types - | - = note: start type: [type error] - = note: end type: {float} - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:126:12 - | -LL | if let ..=3 = 0 {} - | ^^^^ ranges require char or numeric types - | - = note: start type: [type error] - = note: end type: {integer} - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:129:12 - | -LL | if let ..=Y = 0 {} - | ^^^^ ranges require char or numeric types + | ^^^^^ expected integer, found floating-point number | - = note: start type: [type error] - = note: end type: u8 + = note: expected type `{integer}` + found type `{float}` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:132:12 + --> $DIR/recover-range-pats.rs:104:15 | LL | if let ..=true = 0 {} - | ^^^^^^^ ranges require char or numeric types + | ^^^^ ranges require char or numeric types | = note: start type: [type error] = note: end type: bool -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:135:12 +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:106:12 | LL | if let ..=.0 = 0 {} - | ^^^^^ ranges require char or numeric types - | - = note: start type: [type error] - = note: end type: {float} - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:142:12 - | -LL | if let ...3 = 0 {} - | ^^^^ ranges require char or numeric types - | - = note: start type: [type error] - = note: end type: {integer} - -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:146:12 - | -LL | if let ...Y = 0 {} - | ^^^^ ranges require char or numeric types + | ^^^^^ expected integer, found floating-point number | - = note: start type: [type error] - = note: end type: u8 + = note: expected type `{integer}` + found type `{float}` error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:150:12 + --> $DIR/recover-range-pats.rs:116:15 | LL | if let ...true = 0 {} - | ^^^^^^^ ranges require char or numeric types + | ^^^^ ranges require char or numeric types | = note: start type: [type error] = note: end type: bool -error[E0029]: only char and numeric types are allowed in range patterns - --> $DIR/recover-range-pats.rs:154:12 +error[E0308]: mismatched types + --> $DIR/recover-range-pats.rs:119:12 | LL | if let ....3 = 0 {} - | ^^^^^ ranges require char or numeric types + | ^^^^^ expected integer, found floating-point number | - = note: start type: [type error] - = note: end type: {float} + = note: expected type `{integer}` + found type `{float}` -error: aborting due to 112 previous errors +error: aborting due to 76 previous errors Some errors have detailed explanations: E0029, E0308. For more information about an error, try `rustc --explain E0029`. From d33696fcb413e6768443626e78c5c4f23e413fc2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 28 Jul 2019 07:04:16 +0200 Subject: [PATCH 49/49] borrowck-describe-lvalue: --bless --compare-mode=nll. --- .../borrowck/borrowck-describe-lvalue.nll.stderr | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr index f1e1ae18839c4..20f05353d4633 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr @@ -192,8 +192,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here LL | match v { -LL | &[x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -204,8 +204,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x..] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ ..] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -216,8 +216,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here @@ -228,8 +228,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed LL | let x = &mut v; | ------ borrow of `v` occurs here ... -LL | &[_, x.., _] => println!("{:?}", x), - | ^ use of borrowed `v` +LL | &[_, x @ .., _] => println!("{:?}", x), + | ^^^^^^ use of borrowed `v` ... LL | drop(x); | - borrow later used here