about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2019-08-01 16:00:26 +0200
committerGitHub <noreply@github.com>2019-08-01 16:00:26 +0200
commit810ffe2ba07320cac7b89af0c2a68048bfb779c9 (patch)
tree41f7ef742d5d0a7cb4bbed18d3b566c7ee497981
parente2934bab3ea0e1cdcd15e215629ba0ea17507449 (diff)
parent6551285ccaf1562eb73ca1013730165b4d415d8e (diff)
downloadrust-810ffe2ba07320cac7b89af0c2a68048bfb779c9.tar.gz
rust-810ffe2ba07320cac7b89af0c2a68048bfb779c9.zip
Rollup merge of #63122 - Centril:fix-63115, r=petrochenkov
Account for `maybe_whole_expr` in range patterns

Fixes https://github.com/rust-lang/rust/issues/63115 (fallout from https://github.com/rust-lang/rust/pull/62550).

r? @petrochenkov
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/libsyntax/parse/token.rs13
-rw-r--r--src/test/ui/parser/issue-63115-range-pat-interpolated.rs16
-rw-r--r--src/test/ui/parser/recover-range-pats.rs28
-rw-r--r--src/test/ui/parser/recover-range-pats.stderr83
5 files changed, 142 insertions, 7 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 7fda9158b4b..7096d6799e2 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -143,6 +143,7 @@ macro_rules! maybe_whole_expr {
                         $p.token.span, ExprKind::Block(block, None), ThinVec::new()
                     ));
                 }
+                // N.B: `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
                 _ => {},
             };
         }
@@ -2756,12 +2757,7 @@ impl<'a> Parser<'a> {
                     // can't continue an expression after an ident
                     token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
                     token::Literal(..) | token::Pound => true,
-                    token::Interpolated(ref nt) => match **nt {
-                        token::NtIdent(..) | token::NtExpr(..) |
-                        token::NtBlock(..) | token::NtPath(..) => true,
-                        _ => false,
-                    },
-                    _ => false
+                    _ => t.is_whole_expr(),
                 };
                 let cannot_continue_expr = self.look_ahead(1, token_cannot_continue_expr);
                 if cannot_continue_expr {
@@ -3728,6 +3724,7 @@ impl<'a> Parser<'a> {
         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`.
+            || self.token.is_whole_expr()
     }
 
     // Helper function to decide whether to parse as ident binding
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 472e4b474d6..73adb5c947c 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -476,6 +476,19 @@ impl Token {
         false
     }
 
+    /// Would `maybe_whole_expr` in `parser.rs` return `Ok(..)`?
+    /// That is, is this a pre-parsed expression dropped into the token stream
+    /// (which happens while parsing the result of macro expansion)?
+    crate fn is_whole_expr(&self) -> bool {
+        if let Interpolated(ref nt) = self.kind {
+            if let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt {
+                return true;
+            }
+        }
+
+        false
+    }
+
     /// Returns `true` if the token is either the `mut` or `const` keyword.
     crate fn is_mutability(&self) -> bool {
         self.is_keyword(kw::Mut) ||
diff --git a/src/test/ui/parser/issue-63115-range-pat-interpolated.rs b/src/test/ui/parser/issue-63115-range-pat-interpolated.rs
new file mode 100644
index 00000000000..a7d10ca9320
--- /dev/null
+++ b/src/test/ui/parser/issue-63115-range-pat-interpolated.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(exclusive_range_pattern)]
+
+#![allow(ellipsis_inclusive_range_patterns)]
+
+fn main() {
+    macro_rules! mac_expr {
+        ($e:expr) => {
+            if let 2...$e = 3 {}
+            if let 2..=$e = 3 {}
+            if let 2..$e = 3 {}
+        }
+    }
+    mac_expr!(4);
+}
diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs
index c66652ff4fa..260e1083159 100644
--- a/src/test/ui/parser/recover-range-pats.rs
+++ b/src/test/ui/parser/recover-range-pats.rs
@@ -121,3 +121,31 @@ fn inclusive2_to() {
     //~| ERROR `...` range patterns are deprecated
     //~| ERROR mismatched types
 }
+
+fn with_macro_expr_var() {
+    macro_rules! mac2 {
+        ($e1:expr, $e2:expr) => {
+            let $e1..$e2;
+            let $e1...$e2;
+            //~^ ERROR `...` range patterns are deprecated
+            let $e1..=$e2;
+        }
+    }
+
+    mac2!(0, 1);
+
+    macro_rules! mac {
+        ($e:expr) => {
+            let ..$e; //~ ERROR `..X` range patterns are not supported
+            let ...$e; //~ ERROR `...X` range patterns are not supported
+            //~^ ERROR `...` range patterns are deprecated
+            let ..=$e; //~ ERROR `..=X` range patterns are not supported
+            let $e..; //~ ERROR `X..` range patterns are not supported
+            let $e...; //~ ERROR `X...` range patterns are not supported
+            //~^ ERROR `...` range patterns are deprecated
+            let $e..=; //~ ERROR `X..=` range patterns are not supported
+        }
+    }
+
+    mac!(0);
+}
diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr
index c50d5e6eb61..89ec059cb82 100644
--- a/src/test/ui/parser/recover-range-pats.stderr
+++ b/src/test/ui/parser/recover-range-pats.stderr
@@ -214,6 +214,60 @@ error: `...X` range patterns are not supported
 LL |     if let ....3 = 0 {}
    |            ^^^^^ help: try using the minimum value for the type: `MIN...0.3`
 
+error: `..X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:139:17
+   |
+LL |             let ..$e;
+   |                 ^^ help: try using the minimum value for the type: `MIN..0`
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
+error: `...X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:140:17
+   |
+LL |             let ...$e;
+   |                 ^^^ help: try using the minimum value for the type: `MIN...0`
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
+error: `..=X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:142:17
+   |
+LL |             let ..=$e;
+   |                 ^^^ help: try using the minimum value for the type: `MIN..=0`
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
+error: `X..` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:143:19
+   |
+LL |             let $e..;
+   |                   ^^ help: try using the maximum value for the type: `0..MAX`
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
+error: `X...` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:144:19
+   |
+LL |             let $e...;
+   |                   ^^^ help: try using the maximum value for the type: `0...MAX`
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
+error: `X..=` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:146:19
+   |
+LL |             let $e..=;
+   |                   ^^^ help: try using the maximum value for the type: `0..=MAX`
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
 error: `...` range patterns are deprecated
   --> $DIR/recover-range-pats.rs:41:13
    |
@@ -316,6 +370,33 @@ error: `...` range patterns are deprecated
 LL |     if let ....3 = 0 {}
    |            ^^^ help: use `..=` for an inclusive range
 
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:129:20
+   |
+LL |             let $e1...$e2;
+   |                    ^^^ help: use `..=` for an inclusive range
+...
+LL |     mac2!(0, 1);
+   |     ------------ in this macro invocation
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:140:17
+   |
+LL |             let ...$e;
+   |                 ^^^ help: use `..=` for an inclusive range
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:144:19
+   |
+LL |             let $e...;
+   |                   ^^^ help: use `..=` for an inclusive range
+...
+LL |     mac!(0);
+   |     -------- in this macro invocation
+
 error[E0029]: only char and numeric types are allowed in range patterns
   --> $DIR/recover-range-pats.rs:19:12
    |
@@ -532,7 +613,7 @@ LL |     if let ....3 = 0 {}
    = note: expected type `{integer}`
               found type `{float}`
 
-error: aborting due to 76 previous errors
+error: aborting due to 85 previous errors
 
 Some errors have detailed explanations: E0029, E0308.
 For more information about an error, try `rustc --explain E0029`.