@@ -1757,9 +1757,17 @@ impl<'a> Parser<'a> {
1757
1757
1758
1758
let parser_snapshot_before_pat = self . clone ( ) ;
1759
1759
1760
+ // Once we can use edition 2018 in the compiler,
1761
+ // replace this with real try blocks.
1762
+ macro_rules! try_block {
1763
+ ( $( $inside: tt) * ) => (
1764
+ ( ||{ :: std:: ops:: Try :: from_ok( { $( $inside) * } ) } ) ( )
1765
+ )
1766
+ }
1767
+
1760
1768
// We're going to try parsing the argument as a pattern (even though it's not
1761
1769
// allowed). This way we can provide better errors to the user.
1762
- let pat_arg: PResult < ' a , _ > = do catch {
1770
+ let pat_arg: PResult < ' a , _ > = try_block ! {
1763
1771
let pat = self . parse_pat( ) ?;
1764
1772
self . expect( & token:: Colon ) ?;
1765
1773
( pat, self . parse_ty( ) ?)
@@ -2387,11 +2395,15 @@ impl<'a> Parser<'a> {
2387
2395
BlockCheckMode :: Unsafe ( ast:: UserProvided ) ,
2388
2396
attrs) ;
2389
2397
}
2390
- if self . is_catch_expr ( ) {
2398
+ if self . is_do_catch_block ( ) {
2399
+ let mut db = self . fatal ( "found removed `do catch` syntax" ) ;
2400
+ db. help ( "Following RFC #2388, the new non-placeholder syntax is `try`" ) ;
2401
+ return Err ( db) ;
2402
+ }
2403
+ if self . is_try_block ( ) {
2391
2404
let lo = self . span ;
2392
- assert ! ( self . eat_keyword( keywords:: Do ) ) ;
2393
- assert ! ( self . eat_keyword( keywords:: Catch ) ) ;
2394
- return self . parse_catch_expr ( lo, attrs) ;
2405
+ assert ! ( self . eat_keyword( keywords:: Try ) ) ;
2406
+ return self . parse_try_block ( lo, attrs) ;
2395
2407
}
2396
2408
if self . eat_keyword ( keywords:: Return ) {
2397
2409
if self . token . can_begin_expr ( ) {
@@ -3453,13 +3465,13 @@ impl<'a> Parser<'a> {
3453
3465
ExprKind :: Async ( capture_clause, ast:: DUMMY_NODE_ID , body) , attrs) )
3454
3466
}
3455
3467
3456
- /// Parse a `do catch {...}` expression (`do catch ` token already eaten)
3457
- fn parse_catch_expr ( & mut self , span_lo : Span , mut attrs : ThinVec < Attribute > )
3468
+ /// Parse a `try {...}` expression (`try ` token already eaten)
3469
+ fn parse_try_block ( & mut self , span_lo : Span , mut attrs : ThinVec < Attribute > )
3458
3470
-> PResult < ' a , P < Expr > >
3459
3471
{
3460
3472
let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) ?;
3461
3473
attrs. extend ( iattrs) ;
3462
- Ok ( self . mk_expr ( span_lo. to ( body. span ) , ExprKind :: Catch ( body) , attrs) )
3474
+ Ok ( self . mk_expr ( span_lo. to ( body. span ) , ExprKind :: TryBlock ( body) , attrs) )
3463
3475
}
3464
3476
3465
3477
// `match` token already eaten
@@ -4408,12 +4420,20 @@ impl<'a> Parser<'a> {
4408
4420
)
4409
4421
}
4410
4422
4411
- fn is_catch_expr ( & mut self ) -> bool {
4423
+ fn is_do_catch_block ( & mut self ) -> bool {
4412
4424
self . token . is_keyword ( keywords:: Do ) &&
4413
4425
self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Catch ) ) &&
4414
4426
self . look_ahead ( 2 , |t| * t == token:: OpenDelim ( token:: Brace ) ) &&
4427
+ !self . restrictions . contains ( Restrictions :: NO_STRUCT_LITERAL )
4428
+ }
4429
+
4430
+ fn is_try_block ( & mut self ) -> bool {
4431
+ self . token . is_keyword ( keywords:: Try ) &&
4432
+ self . look_ahead ( 1 , |t| * t == token:: OpenDelim ( token:: Brace ) ) &&
4433
+
4434
+ self . span . edition ( ) >= Edition :: Edition2018 &&
4415
4435
4416
- // prevent `while catch {} {}`, `if catch {} {} else {}`, etc.
4436
+ // prevent `while try {} {}`, `if try {} {} else {}`, etc.
4417
4437
!self . restrictions . contains ( Restrictions :: NO_STRUCT_LITERAL )
4418
4438
}
4419
4439
0 commit comments