about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaio <c410.f3r@gmail.com>2022-01-22 17:45:45 -0300
committerCaio <c410.f3r@gmail.com>2022-01-22 17:45:45 -0300
commitcbb0fffe59ff17e322b0b29d73381975abe039c1 (patch)
tree2c41f60a81ecd445c26cf6f03f37bdf90c20d43e
parentecf72996eda4f8af19b0ca7235c6f62e0245a313 (diff)
downloadrust-cbb0fffe59ff17e322b0b29d73381975abe039c1.tar.gz
rust-cbb0fffe59ff17e322b0b29d73381975abe039c1.zip
Fix let_chains and if_let_guard feature flags
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs20
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.rs13
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr72
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/issue-93150.rs8
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr22
5 files changed, 112 insertions, 23 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 192e87b4c01..26284728ff2 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2383,6 +2383,17 @@ impl<'a> Parser<'a> {
     }
 
     pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
+        fn check_let_expr(expr: &Expr) -> (bool, bool) {
+            match expr.kind {
+                ExprKind::Binary(_, ref lhs, ref rhs) => {
+                    let lhs_rslt = check_let_expr(lhs);
+                    let rhs_rslt = check_let_expr(rhs);
+                    (lhs_rslt.0 || rhs_rslt.0, false)
+                }
+                ExprKind::Let(..) => (true, true),
+                _ => (false, true),
+            }
+        }
         let attrs = self.parse_outer_attributes()?;
         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
             let lo = this.token.span;
@@ -2390,9 +2401,12 @@ impl<'a> Parser<'a> {
             let guard = if this.eat_keyword(kw::If) {
                 let if_span = this.prev_token.span;
                 let cond = this.parse_expr()?;
-                if let ExprKind::Let(..) = cond.kind {
-                    // Remove the last feature gating of a `let` expression since it's stable.
-                    this.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
+                let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond);
+                if has_let_expr {
+                    if does_not_have_bin_op {
+                        // Remove the last feature gating of a `let` expression since it's stable.
+                        this.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
+                    }
                     let span = if_span.to(cond.span);
                     this.sess.gated_spans.gate(sym::if_let_guard, span);
                 }
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
index 34d2d84da93..4a36515b991 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
@@ -14,10 +14,12 @@ fn _if_let_guard() {
         //~^ ERROR `let` expressions in this position are unstable
 
         () if true && let 0 = 1 => {}
-        //~^ ERROR `let` expressions in this position are unstable
+        //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
 
         () if let 0 = 1 && true => {}
-        //~^ ERROR `let` expressions in this position are unstable
+        //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
 
         () if (let 0 = 1) && true => {}
         //~^ ERROR `let` expressions in this position are unstable
@@ -30,14 +32,17 @@ fn _if_let_guard() {
         //~| ERROR `let` expressions in this position are unstable
 
         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
-        //~^ ERROR `let` expressions in this position are unstable
+        //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
         //~| ERROR `let` expressions in this position are unstable
         //~| ERROR `let` expressions in this position are unstable
         //~| ERROR `let` expressions in this position are unstable
         //~| ERROR `let` expressions in this position are unstable
 
         () if let Range { start: _, end: _ } = (true..true) && false => {}
-        //~^ ERROR `let` expressions in this position are unstable
+        //~^ ERROR `if let` guards are experimental
+        //~| ERROR `let` expressions in this position are unstable
+
         _ => {}
     }
 }
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
index 0cda6ba9a99..8d93fb87f7a 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
@@ -1,5 +1,5 @@
 error: no rules expected the token `let`
-  --> $DIR/feature-gate.rs:64:15
+  --> $DIR/feature-gate.rs:69:15
    |
 LL |     macro_rules! use_expr {
    |     --------------------- when calling this macro
@@ -18,7 +18,47 @@ LL |         () if let 0 = 1 => {}
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:60:12
+  --> $DIR/feature-gate.rs:16:12
+   |
+LL |         () if true && let 0 = 1 => {}
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
+   = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
+   = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
+
+error[E0658]: `if let` guards are experimental
+  --> $DIR/feature-gate.rs:20:12
+   |
+LL |         () if let 0 = 1 && true => {}
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
+   = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
+   = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
+
+error[E0658]: `if let` guards are experimental
+  --> $DIR/feature-gate.rs:34:12
+   |
+LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
+   = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
+   = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
+
+error[E0658]: `if let` guards are experimental
+  --> $DIR/feature-gate.rs:42:12
+   |
+LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
+   = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
+   = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
+
+error[E0658]: `if let` guards are experimental
+  --> $DIR/feature-gate.rs:65:12
    |
 LL |         () if let 0 = 1 => {}
    |            ^^^^^^^^^^^^
@@ -55,7 +95,7 @@ LL |         () if true && let 0 = 1 => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:19:15
+  --> $DIR/feature-gate.rs:20:15
    |
 LL |         () if let 0 = 1 && true => {}
    |               ^^^^^^^^^
@@ -64,7 +104,7 @@ LL |         () if let 0 = 1 && true => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:22:16
+  --> $DIR/feature-gate.rs:24:16
    |
 LL |         () if (let 0 = 1) && true => {}
    |                ^^^^^^^^^
@@ -73,7 +113,7 @@ LL |         () if (let 0 = 1) && true => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:25:24
+  --> $DIR/feature-gate.rs:27:24
    |
 LL |         () if true && (let 0 = 1) => {}
    |                        ^^^^^^^^^
@@ -82,7 +122,7 @@ LL |         () if true && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:28:16
+  --> $DIR/feature-gate.rs:30:16
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -91,7 +131,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:28:31
+  --> $DIR/feature-gate.rs:30:31
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                               ^^^^^^^^^
@@ -100,7 +140,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:32:15
+  --> $DIR/feature-gate.rs:34:15
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |               ^^^^^^^^^
@@ -109,7 +149,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:32:28
+  --> $DIR/feature-gate.rs:34:28
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                            ^^^^^^^^^
@@ -118,7 +158,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:32:42
+  --> $DIR/feature-gate.rs:34:42
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                          ^^^^^^^^^
@@ -127,7 +167,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:32:55
+  --> $DIR/feature-gate.rs:34:55
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                       ^^^^^^^^^
@@ -136,7 +176,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:32:68
+  --> $DIR/feature-gate.rs:34:68
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                                    ^^^^^^^^^
@@ -145,7 +185,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:39:15
+  --> $DIR/feature-gate.rs:42:15
    |
 LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,7 +194,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:54:16
+  --> $DIR/feature-gate.rs:59:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^^^^^^^
@@ -163,7 +203,7 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:56:16
+  --> $DIR/feature-gate.rs:61:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
@@ -171,6 +211,6 @@ LL |     use_expr!((let 0 = 1));
    = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
-error: aborting due to 19 previous errors
+error: aborting due to 23 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs b/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs
new file mode 100644
index 00000000000..f90b9ab0d40
--- /dev/null
+++ b/src/test/ui/rfc-2497-if-let-chains/issue-93150.rs
@@ -0,0 +1,8 @@
+fn main() {
+    match true {
+        _ if let true = true && true => {}
+        //~^ ERROR `if let` guards are
+        //~| ERROR `let` expressions in this
+        _ => {}
+    }
+}
diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr b/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr
new file mode 100644
index 00000000000..b25f299a219
--- /dev/null
+++ b/src/test/ui/rfc-2497-if-let-chains/issue-93150.stderr
@@ -0,0 +1,22 @@
+error[E0658]: `if let` guards are experimental
+  --> $DIR/issue-93150.rs:3:11
+   |
+LL |         _ if let true = true && true => {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
+   = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
+   = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/issue-93150.rs:3:14
+   |
+LL |         _ if let true = true && true => {}
+   |              ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
+   = help: add `#![feature(let_chains)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.