about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsjwang05 <63834813+sjwang05@users.noreply.github.com>2023-11-10 12:13:53 -0800
committersjwang05 <63834813+sjwang05@users.noreply.github.com>2023-11-10 12:13:53 -0800
commita49368f00b66409ae9fcf42d52e4f8246c73c266 (patch)
treef8beed04dd8913947502276fa91bbf726fd8ac64
parent9455259450f0186df991a14d960bb3759e7eac43 (diff)
downloadrust-a49368f00b66409ae9fcf42d52e4f8246c73c266.tar.gz
rust-a49368f00b66409ae9fcf42d52e4f8246c73c266.zip
Correctly handle while-let-chains
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--tests/ui/parser/brace-in-let-chain.rs21
-rw-r--r--tests/ui/parser/brace-in-let-chain.stderr30
4 files changed, 51 insertions, 4 deletions
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index e7d2c678824..41f4d0055aa 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -129,7 +129,7 @@ impl<'a> TokenTreesReader<'a> {
             while parser.token != token::Eof {
                 if let Err(diff_err) = parser.err_diff_marker() {
                     diff_errs.push(diff_err);
-                } else if parser.token.is_keyword(kw::If) {
+                } else if parser.is_keyword_ahead(0, &[kw::If, kw::While]) {
                     in_cond = true;
                 } else if matches!(
                     parser.token.kind,
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 1a7ae406911..6eab140117e 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1115,7 +1115,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Returns whether any of the given keywords are `dist` tokens ahead of the current one.
-    fn is_keyword_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {
+    pub fn is_keyword_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {
         self.look_ahead(dist, |t| kws.iter().any(|&kw| t.is_keyword(kw)))
     }
 
diff --git a/tests/ui/parser/brace-in-let-chain.rs b/tests/ui/parser/brace-in-let-chain.rs
index 78060e238d4..1f34c73a2c3 100644
--- a/tests/ui/parser/brace-in-let-chain.rs
+++ b/tests/ui/parser/brace-in-let-chain.rs
@@ -9,6 +9,27 @@ fn main() {
     }
 }
 
+fn quux() {
+    while let () = ()
+        && let () = () { //~ERROR: found a `{` in the middle of a let-chain
+        && let () = ()
+    {
+    }
+}
+
+fn foobar() {
+    while false {}
+    {
+        && let () = ()
+}
+
+fn fubar() {
+    while false {
+        {
+            && let () = ()
+    }
+}
+
 fn qux() {
     let foo = false;
     match foo {
diff --git a/tests/ui/parser/brace-in-let-chain.stderr b/tests/ui/parser/brace-in-let-chain.stderr
index 8e20cc43421..c43310f4736 100644
--- a/tests/ui/parser/brace-in-let-chain.stderr
+++ b/tests/ui/parser/brace-in-let-chain.stderr
@@ -1,9 +1,18 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/brace-in-let-chain.rs:37:54
+  --> $DIR/brace-in-let-chain.rs:58:54
    |
 LL | fn main() {
    |           - unclosed delimiter
 ...
+LL | fn quux() {
+   |           - unclosed delimiter
+...
+LL | fn foobar() {
+   |             - unclosed delimiter
+...
+LL | fn fubar() {
+   |            - unclosed delimiter
+...
 LL | fn qux() {
    |          - unclosed delimiter
 ...
@@ -25,6 +34,23 @@ LL | }
    |                                                      ^
 
 error: found a `{` in the middle of a let-chain
+  --> $DIR/brace-in-let-chain.rs:14:24
+   |
+LL |         && let () = () {
+   |                        ^
+   |
+note: you might have meant to continue the let-chain here
+  --> $DIR/brace-in-let-chain.rs:15:9
+   |
+LL |         && let () = ()
+   |         ^^^^^^
+help: consider removing this brace to parse the `let` as part of the same chain
+   |
+LL -         && let () = () {
+LL +         && let () = ()
+   |
+
+error: found a `{` in the middle of a let-chain
   --> $DIR/brace-in-let-chain.rs:6:24
    |
 LL |         && let () = () {
@@ -41,5 +67,5 @@ LL -         && let () = () {
 LL +         && let () = ()
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors