about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs21
-rw-r--r--src/test/ui/let-else/let-else-if.rs10
-rw-r--r--src/test/ui/let-else/let-else-if.stderr18
3 files changed, 44 insertions, 5 deletions
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index c4569c07db4..01e751ea8b5 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -16,7 +16,7 @@ use rustc_ast::{
 };
 use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt};
 use rustc_ast::{StmtKind, DUMMY_NODE_ID};
-use rustc_errors::{Applicability, PResult};
+use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
 use rustc_span::source_map::{BytePos, Span};
 use rustc_span::symbol::{kw, sym};
 
@@ -300,6 +300,12 @@ impl<'a> Parser<'a> {
             None => LocalKind::Decl,
             Some(init) => {
                 if self.eat_keyword(kw::Else) {
+                    if self.token.is_keyword(kw::If) {
+                        // `let...else if`. Emit the same error that `parse_block()` would,
+                        // but explicitly point out that this pattern is not allowed.
+                        let msg = "conditional `else if` is not supported for `let...else`";
+                        return Err(self.error_block_no_opening_brace_msg(msg));
+                    }
                     let els = self.parse_block()?;
                     self.check_let_else_init_bool_expr(&init);
                     self.check_let_else_init_trailing_brace(&init);
@@ -392,10 +398,9 @@ impl<'a> Parser<'a> {
         Ok(block)
     }
 
-    fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
+    fn error_block_no_opening_brace_msg(&mut self, msg: &str) -> DiagnosticBuilder<'a> {
         let sp = self.token.span;
-        let tok = super::token_descr(&self.token);
-        let mut e = self.struct_span_err(sp, &format!("expected `{{`, found {}", tok));
+        let mut e = self.struct_span_err(sp, msg);
         let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
 
         // Check to see if the user has written something like
@@ -435,7 +440,13 @@ impl<'a> Parser<'a> {
             _ => {}
         }
         e.span_label(sp, "expected `{`");
-        Err(e)
+        e
+    }
+
+    fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
+        let tok = super::token_descr(&self.token);
+        let msg = format!("expected `{{`, found {}", tok);
+        Err(self.error_block_no_opening_brace_msg(&msg))
     }
 
     /// Parses a block. Inner attributes are allowed.
diff --git a/src/test/ui/let-else/let-else-if.rs b/src/test/ui/let-else/let-else-if.rs
new file mode 100644
index 00000000000..c3a17330d6e
--- /dev/null
+++ b/src/test/ui/let-else/let-else-if.rs
@@ -0,0 +1,10 @@
+#![feature(let_else)]
+
+fn main() {
+    let Some(_) = Some(()) else if true {
+        //~^ ERROR conditional `else if` is not supported for `let...else`
+        return;
+    } else {
+        return;
+    };
+}
diff --git a/src/test/ui/let-else/let-else-if.stderr b/src/test/ui/let-else/let-else-if.stderr
new file mode 100644
index 00000000000..38c739fd850
--- /dev/null
+++ b/src/test/ui/let-else/let-else-if.stderr
@@ -0,0 +1,18 @@
+error: conditional `else if` is not supported for `let...else`
+  --> $DIR/let-else-if.rs:4:33
+   |
+LL |     let Some(_) = Some(()) else if true {
+   |                                 ^^ expected `{`
+   |
+help: try placing this code inside a block
+   |
+LL ~     let Some(_) = Some(()) else { if true {
+LL +
+LL +         return;
+LL +     } else {
+LL +         return;
+LL ~     } };
+   |
+
+error: aborting due to previous error
+