Skip to content

Commit 8565419

Browse files
committed
Nicer error message if the user attempts to do let...else if
1 parent c102653 commit 8565419

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

compiler/rustc_parse/src/parser/stmt.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_ast::{
1616
};
1717
use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt};
1818
use rustc_ast::{StmtKind, DUMMY_NODE_ID};
19-
use rustc_errors::{Applicability, PResult};
19+
use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
2020
use rustc_span::source_map::{BytePos, Span};
2121
use rustc_span::symbol::{kw, sym};
2222

@@ -300,6 +300,12 @@ impl<'a> Parser<'a> {
300300
None => LocalKind::Decl,
301301
Some(init) => {
302302
if self.eat_keyword(kw::Else) {
303+
if self.token.is_keyword(kw::If) {
304+
// `let...else if`. Emit the same error that `parse_block()` would,
305+
// but explicitly point out that this pattern is not allowed.
306+
let msg = "conditional `else if` is not supported for `let...else`";
307+
return Err(self.error_block_no_opening_brace_msg(msg));
308+
}
303309
let els = self.parse_block()?;
304310
self.check_let_else_init_bool_expr(&init);
305311
self.check_let_else_init_trailing_brace(&init);
@@ -392,10 +398,9 @@ impl<'a> Parser<'a> {
392398
Ok(block)
393399
}
394400

395-
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
401+
fn error_block_no_opening_brace_msg(&mut self, msg: &str) -> DiagnosticBuilder<'a> {
396402
let sp = self.token.span;
397-
let tok = super::token_descr(&self.token);
398-
let mut e = self.struct_span_err(sp, &format!("expected `{{`, found {}", tok));
403+
let mut e = self.struct_span_err(sp, msg);
399404
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
400405

401406
// Check to see if the user has written something like
@@ -435,7 +440,13 @@ impl<'a> Parser<'a> {
435440
_ => {}
436441
}
437442
e.span_label(sp, "expected `{`");
438-
Err(e)
443+
e
444+
}
445+
446+
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
447+
let tok = super::token_descr(&self.token);
448+
let msg = format!("expected `{{`, found {}", tok);
449+
Err(self.error_block_no_opening_brace_msg(&msg))
439450
}
440451

441452
/// Parses a block. Inner attributes are allowed.

src/test/ui/let-else/let-else-if.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(let_else)]
2+
3+
fn main() {
4+
let Some(_) = Some(()) else if true {
5+
//~^ ERROR conditional `else if` is not supported for `let...else`
6+
return;
7+
} else {
8+
return;
9+
};
10+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error: conditional `else if` is not supported for `let...else`
2+
--> $DIR/let-else-if.rs:4:33
3+
|
4+
LL | let Some(_) = Some(()) else if true {
5+
| ^^ expected `{`
6+
|
7+
help: try placing this code inside a block
8+
|
9+
LL ~ let Some(_) = Some(()) else { if true {
10+
LL +
11+
LL + return;
12+
LL + } else {
13+
LL + return;
14+
LL ~ } };
15+
|
16+
17+
error: aborting due to previous error
18+

0 commit comments

Comments
 (0)