Skip to content

Commit

Permalink
Improve error message when failing to parse a block
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Aatch committed Aug 23, 2016
1 parent 3c5a0fa commit 72d629c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -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)
Expand Down
20 changes: 20 additions & 0 deletions src/test/compile-fail/missing-block-hint.rs
@@ -0,0 +1,20 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
{
if (foo) => {} //~ ERROR expected `{`, found `=>`
}
{
if (foo)
bar; //~ ERROR expected `{`, found `bar`
//^ HELP try placing this code inside a block
}
}

0 comments on commit 72d629c

Please sign in to comment.