]> git.lizzy.rs Git - rust.git/commitdiff
recover on 'do catch { .. }'
authorMazdak Farrokhzad <twingoow@gmail.com>
Tue, 3 Dec 2019 12:35:05 +0000 (13:35 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Fri, 20 Dec 2019 21:41:29 +0000 (22:41 +0100)
src/librustc_parse/parser/expr.rs
src/test/ui/parser/do-catch-suggests-try.rs
src/test/ui/parser/do-catch-suggests-try.stderr

index b4d828ff849204ccf35c7f8cfcb5480dbcba1747..292d277a6786316935153516ea544afc9db33fb5 100644 (file)
@@ -876,14 +876,11 @@ macro_rules! parse_lit {
                     return self.parse_labeled_expr(label, attrs);
                 }
                 if self.eat_keyword(kw::Loop) {
-                    let lo = self.prev_span;
-                    return self.parse_loop_expr(None, lo, attrs);
+                    return self.parse_loop_expr(None, self.prev_span, attrs);
                 }
                 if self.eat_keyword(kw::Continue) {
-                    let label = self.eat_label();
-                    let ex = ExprKind::Continue(label);
-                    let hi = self.prev_span;
-                    return Ok(self.mk_expr(lo.to(hi), ex, attrs));
+                    let kind = ExprKind::Continue(self.eat_label());
+                    return Ok(self.mk_expr(lo.to(self.prev_span), kind, attrs));
                 }
                 if self.eat_keyword(kw::Match) {
                     let match_sp = self.prev_span;
@@ -893,20 +890,14 @@ macro_rules! parse_lit {
                     });
                 }
                 if self.eat_keyword(kw::Unsafe) {
-                    return self.parse_block_expr(
-                        None,
-                        lo,
-                        BlockCheckMode::Unsafe(ast::UserProvided),
-                        attrs);
+                    let mode = BlockCheckMode::Unsafe(ast::UserProvided);
+                    return self.parse_block_expr(None, lo, mode, attrs);
                 }
                 if self.is_do_catch_block() {
-                    let mut db = self.fatal("found removed `do catch` syntax");
-                    db.help("following RFC #2388, the new non-placeholder syntax is `try`");
-                    return Err(db);
+                    return self.recover_do_catch(attrs);
                 }
                 if self.is_try_block() {
-                    let lo = self.token.span;
-                    assert!(self.eat_keyword(kw::Try));
+                    self.expect_keyword(kw::Try)?;
                     return self.parse_try_block(lo, attrs);
                 }
 
@@ -1104,6 +1095,27 @@ fn parse_labeled_expr(
         self.parse_expr()
     }
 
+    /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
+    fn recover_do_catch(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+        let lo = self.token.span;
+
+        self.bump(); // `do`
+        self.bump(); // `catch`
+
+        let span_dc = lo.to(self.prev_span);
+        self.struct_span_err(span_dc, "found removed `do catch` syntax")
+            .span_suggestion(
+                span_dc,
+                "replace with the new syntax",
+                "try".to_string(),
+                Applicability::MachineApplicable,
+            )
+            .note("following RFC #2388, the new non-placeholder syntax is `try`")
+            .emit();
+
+        self.parse_try_block(lo, attrs)
+    }
+
     /// Returns a string literal if the next token is a string literal.
     /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
     /// and returns `None` if the next token is not literal at all.
index d805ab75882dd7fda66a35a87d6f23d42d985302..f64568d06e96d00e3d7e6fe05e99d5b8e127ccb9 100644 (file)
@@ -1,5 +1,10 @@
+#![feature(try_blocks)]
+
 fn main() {
     let _: Option<()> = do catch {};
     //~^ ERROR found removed `do catch` syntax
-    //~^^ HELP following RFC #2388, the new non-placeholder syntax is `try`
+    //~| replace with the new syntax
+    //~| following RFC #2388, the new non-placeholder syntax is `try`
+
+    let _recovery_witness: () = 1; //~ ERROR mismatched types
 }
index e151d4cf8a6aa0999c7b883a952101f9cdc1a2bc..cd8907b7eac9a6f1e8dd1060e2e589c3ae341566 100644 (file)
@@ -1,10 +1,19 @@
 error: found removed `do catch` syntax
-  --> $DIR/do-catch-suggests-try.rs:2:25
+  --> $DIR/do-catch-suggests-try.rs:4:25
    |
 LL |     let _: Option<()> = do catch {};
-   |                         ^^
+   |                         ^^^^^^^^ help: replace with the new syntax: `try`
    |
-   = help: following RFC #2388, the new non-placeholder syntax is `try`
+   = note: following RFC #2388, the new non-placeholder syntax is `try`
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/do-catch-suggests-try.rs:9:33
+   |
+LL |     let _recovery_witness: () = 1;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0308`.