Skip to content

Commit 327641e

Browse files
committed
recover on 'do catch { .. }'
1 parent 32ac9d0 commit 327641e

File tree

3 files changed

+47
-21
lines changed

3 files changed

+47
-21
lines changed

src/librustc_parse/parser/expr.rs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -876,14 +876,11 @@ impl<'a> Parser<'a> {
876876
return self.parse_labeled_expr(label, attrs);
877877
}
878878
if self.eat_keyword(kw::Loop) {
879-
let lo = self.prev_span;
880-
return self.parse_loop_expr(None, lo, attrs);
879+
return self.parse_loop_expr(None, self.prev_span, attrs);
881880
}
882881
if self.eat_keyword(kw::Continue) {
883-
let label = self.eat_label();
884-
let ex = ExprKind::Continue(label);
885-
let hi = self.prev_span;
886-
return Ok(self.mk_expr(lo.to(hi), ex, attrs));
882+
let kind = ExprKind::Continue(self.eat_label());
883+
return Ok(self.mk_expr(lo.to(self.prev_span), kind, attrs));
887884
}
888885
if self.eat_keyword(kw::Match) {
889886
let match_sp = self.prev_span;
@@ -893,20 +890,14 @@ impl<'a> Parser<'a> {
893890
});
894891
}
895892
if self.eat_keyword(kw::Unsafe) {
896-
return self.parse_block_expr(
897-
None,
898-
lo,
899-
BlockCheckMode::Unsafe(ast::UserProvided),
900-
attrs);
893+
let mode = BlockCheckMode::Unsafe(ast::UserProvided);
894+
return self.parse_block_expr(None, lo, mode, attrs);
901895
}
902896
if self.is_do_catch_block() {
903-
let mut db = self.fatal("found removed `do catch` syntax");
904-
db.help("following RFC #2388, the new non-placeholder syntax is `try`");
905-
return Err(db);
897+
return self.recover_do_catch(attrs);
906898
}
907899
if self.is_try_block() {
908-
let lo = self.token.span;
909-
assert!(self.eat_keyword(kw::Try));
900+
self.expect_keyword(kw::Try)?;
910901
return self.parse_try_block(lo, attrs);
911902
}
912903

@@ -1104,6 +1095,27 @@ impl<'a> Parser<'a> {
11041095
self.parse_expr()
11051096
}
11061097

1098+
/// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
1099+
fn recover_do_catch(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
1100+
let lo = self.token.span;
1101+
1102+
self.bump(); // `do`
1103+
self.bump(); // `catch`
1104+
1105+
let span_dc = lo.to(self.prev_span);
1106+
self.struct_span_err(span_dc, "found removed `do catch` syntax")
1107+
.span_suggestion(
1108+
span_dc,
1109+
"replace with the new syntax",
1110+
"try".to_string(),
1111+
Applicability::MachineApplicable,
1112+
)
1113+
.note("following RFC #2388, the new non-placeholder syntax is `try`")
1114+
.emit();
1115+
1116+
self.parse_try_block(lo, attrs)
1117+
}
1118+
11071119
/// Returns a string literal if the next token is a string literal.
11081120
/// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
11091121
/// and returns `None` if the next token is not literal at all.
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
#![feature(try_blocks)]
2+
13
fn main() {
24
let _: Option<()> = do catch {};
35
//~^ ERROR found removed `do catch` syntax
4-
//~^^ HELP following RFC #2388, the new non-placeholder syntax is `try`
6+
//~| replace with the new syntax
7+
//~| following RFC #2388, the new non-placeholder syntax is `try`
8+
9+
let _recovery_witness: () = 1; //~ ERROR mismatched types
510
}
Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
error: found removed `do catch` syntax
2-
--> $DIR/do-catch-suggests-try.rs:2:25
2+
--> $DIR/do-catch-suggests-try.rs:4:25
33
|
44
LL | let _: Option<()> = do catch {};
5-
| ^^
5+
| ^^^^^^^^ help: replace with the new syntax: `try`
66
|
7-
= help: following RFC #2388, the new non-placeholder syntax is `try`
7+
= note: following RFC #2388, the new non-placeholder syntax is `try`
88

9-
error: aborting due to previous error
9+
error[E0308]: mismatched types
10+
--> $DIR/do-catch-suggests-try.rs:9:33
11+
|
12+
LL | let _recovery_witness: () = 1;
13+
| -- ^ expected `()`, found integer
14+
| |
15+
| expected due to this
16+
17+
error: aborting due to 2 previous errors
1018

19+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)