about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-04-13 07:48:01 +0000
committerbors <bors@rust-lang.org>2019-04-13 07:48:01 +0000
commitaa35e73b258789d93b080e361542d7aa99e7fcd6 (patch)
tree35016b7e8e0758d8c516c47be108c62eb3ede473 /src/libsyntax/parse
parent99da733f7f38ce8fe68453e859b7ac96bf7caa0f (diff)
parentba173135becd5681baa67551cafa20ce9a3017e2 (diff)
downloadrust-aa35e73b258789d93b080e361542d7aa99e7fcd6.tar.gz
rust-aa35e73b258789d93b080e361542d7aa99e7fcd6.zip
Auto merge of #59922 - Centril:rollup-0qmx4jg, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #59781 (Remove check_match from const_eval)
 - #59820 (proc_macro: stop using LEB128 for RPC.)
 - #59846 (clarify what the item is in "not a module" error)
 - #59847 (Error when using `catch` after `try`)
 - #59859 (Suggest removing `?` to resolve type errors.)
 - #59862 (Tweak unstable diagnostic output)
 - #59866 (Recover from missing semicolon based on the found token)
 - #59892 (Impl RawFd conversion traits for WASI TcpListener, TcpStream and UdpSocket)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs36
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