diff options
| author | James Miller <james@aatch.net> | 2016-08-23 18:23:31 +1200 |
|---|---|---|
| committer | James Miller <james@aatch.net> | 2016-08-23 18:23:31 +1200 |
| commit | 72d629caa50fa482dd4165cb43b9fb02ac24c8d8 (patch) | |
| tree | 1c140a34db4fa49bd2d6a59150a8cb5faa18e884 /src/libsyntax/parse | |
| parent | 3c5a0fa45b5e2786b6e64e27f48cd129e7aefdbd (diff) | |
| download | rust-72d629caa50fa482dd4165cb43b9fb02ac24c8d8.tar.gz rust-72d629caa50fa482dd4165cb43b9fb02ac24c8d8.zip | |
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
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9443df6321b..1646246069e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4087,9 +4087,30 @@ impl<'a> Parser<'a> { if !self.eat(&token::OpenDelim(token::Brace)) { let sp = self.span; let tok = self.this_token_to_string(); - return Err(self.span_fatal_help(sp, - &format!("expected `{{`, found `{}`", tok), - "place this code inside a block")); + let mut e = self.span_fatal(sp, &format!("expected `{{`, found `{}`", tok)); + + // Check to see if the user has written something like + // + // if (cond) + // bar; + // + // Which is valid in other languages, but not Rust. + match self.parse_stmt_without_recovery(false) { + Ok(Some(stmt)) => { + let mut stmt_span = stmt.span; + // expand the span to include the semicolon, if it exists + if self.eat(&token::Semi) { + stmt_span.hi = self.last_span.hi; + } + e.span_help(stmt_span, "try placing this code inside a block"); + } + Err(mut e) => { + self.recover_stmt_(SemiColonMode::Break); + e.cancel(); + } + _ => () + } + return Err(e); } self.parse_block_tail(lo, BlockCheckMode::Default) |
