diff options
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b51b7fd1ef5..a5adb37f745 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -851,8 +851,34 @@ impl<'a> Parser<'a> { } } + let is_semi_suggestable = expected.iter().any(|t| match t { + TokenType::Token(token::Semi) => true, // we expect a `;` here + _ => false, + }) && ( // a `;` would be expected before the current keyword + self.token.is_keyword(keywords::Break) || + self.token.is_keyword(keywords::Continue) || + self.token.is_keyword(keywords::For) || + self.token.is_keyword(keywords::If) || + self.token.is_keyword(keywords::Let) || + self.token.is_keyword(keywords::Loop) || + self.token.is_keyword(keywords::Match) || + self.token.is_keyword(keywords::Return) || + self.token.is_keyword(keywords::While) + ); let cm = self.sess.source_map(); match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) { + (Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => { + // The spans are in different lines, expected `;` and found `let` or `return`. + // High likelihood that it is only a missing `;`. + err.span_suggestion_short( + label_sp, + "a semicolon may be missing here", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + err.emit(); + return Ok(true); + } (Ok(ref a), Ok(ref b)) if a.line == b.line => { // When the spans are in the same line, it means that the only content between // them is whitespace, point at the found token in that case: @@ -4091,7 +4117,15 @@ impl<'a> Parser<'a> { { let (iattrs, body) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs); - Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs)) + if self.eat_keyword(keywords::Catch) { + let mut error = self.struct_span_err(self.prev_span, + "keyword `catch` cannot follow a `try` block"); + error.help("try using `match` on the result of the `try` block instead"); + error.emit(); + Err(error) + } else { + Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs)) + } } // `match` token already eaten |
