Skip to content

Commit 1385feb

Browse files
authored
Rollup merge of #35953 - Aatch:better-missing-block-error, r=nrc
Improve error message when failing to parse a block We want to catch this error: ``` if (foo) bar; ``` as it's valid syntax in other languages, and say how to fix it. Unfortunately it didn't care if the suggestion made sense and just highlighted the unexpected token. Now it attempts to parse a statement, and if it succeeds, it shows the help message. Fixes #35907
2 parents b5969ca + 72d629c commit 1385feb

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/libsyntax/parse/parser.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -4087,9 +4087,30 @@ impl<'a> Parser<'a> {
40874087
if !self.eat(&token::OpenDelim(token::Brace)) {
40884088
let sp = self.span;
40894089
let tok = self.this_token_to_string();
4090-
return Err(self.span_fatal_help(sp,
4091-
&format!("expected `{{`, found `{}`", tok),
4092-
"place this code inside a block"));
4090+
let mut e = self.span_fatal(sp, &format!("expected `{{`, found `{}`", tok));
4091+
4092+
// Check to see if the user has written something like
4093+
//
4094+
// if (cond)
4095+
// bar;
4096+
//
4097+
// Which is valid in other languages, but not Rust.
4098+
match self.parse_stmt_without_recovery(false) {
4099+
Ok(Some(stmt)) => {
4100+
let mut stmt_span = stmt.span;
4101+
// expand the span to include the semicolon, if it exists
4102+
if self.eat(&token::Semi) {
4103+
stmt_span.hi = self.last_span.hi;
4104+
}
4105+
e.span_help(stmt_span, "try placing this code inside a block");
4106+
}
4107+
Err(mut e) => {
4108+
self.recover_stmt_(SemiColonMode::Break);
4109+
e.cancel();
4110+
}
4111+
_ => ()
4112+
}
4113+
return Err(e);
40934114
}
40944115

40954116
self.parse_block_tail(lo, BlockCheckMode::Default)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
{
13+
if (foo) => {} //~ ERROR expected `{`, found `=>`
14+
}
15+
{
16+
if (foo)
17+
bar; //~ ERROR expected `{`, found `bar`
18+
//^ HELP try placing this code inside a block
19+
}
20+
}

0 commit comments

Comments
 (0)