@@ -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.
0 commit comments