@@ -13,7 +13,7 @@ use crate::symbol::kw;
13
13
use crate :: ThinVec ;
14
14
use errors:: { Applicability , DiagnosticBuilder } ;
15
15
use log:: debug;
16
- use syntax_pos:: Span ;
16
+ use syntax_pos:: { Span , DUMMY_SP } ;
17
17
18
18
pub trait RecoverQPath : Sized + ' static {
19
19
const PATH_STYLE : PathStyle = PathStyle :: Expr ;
@@ -201,7 +201,7 @@ impl<'a> Parser<'a> {
201
201
202
202
let mut path = ast:: Path {
203
203
segments : Vec :: new ( ) ,
204
- span : syntax_pos :: DUMMY_SP ,
204
+ span : DUMMY_SP ,
205
205
} ;
206
206
self . parse_path_segments ( & mut path. segments , T :: PATH_STYLE ) ?;
207
207
path. span = ty_span. to ( self . prev_span ) ;
@@ -267,6 +267,58 @@ impl<'a> Parser<'a> {
267
267
}
268
268
}
269
269
270
+ /// Create a `DiagnosticBuilder` for an unexpected token `t` and try to recover if it is a
271
+ /// closing delimiter.
272
+ pub fn unexpected_try_recover (
273
+ & mut self ,
274
+ t : & token:: Token ,
275
+ ) -> PResult < ' a , bool /* recovered */ > {
276
+ let token_str = pprust:: token_to_string ( t) ;
277
+ let this_token_str = self . this_token_descr ( ) ;
278
+ let ( prev_sp, sp) = match ( & self . token , self . subparser_name ) {
279
+ // Point at the end of the macro call when reaching end of macro arguments.
280
+ ( token:: Token :: Eof , Some ( _) ) => {
281
+ let sp = self . sess . source_map ( ) . next_point ( self . span ) ;
282
+ ( sp, sp)
283
+ }
284
+ // We don't want to point at the following span after DUMMY_SP.
285
+ // This happens when the parser finds an empty TokenStream.
286
+ _ if self . prev_span == DUMMY_SP => ( self . span , self . span ) ,
287
+ // EOF, don't want to point at the following char, but rather the last token.
288
+ ( token:: Token :: Eof , None ) => ( self . prev_span , self . span ) ,
289
+ _ => ( self . sess . source_map ( ) . next_point ( self . prev_span ) , self . span ) ,
290
+ } ;
291
+ let msg = format ! (
292
+ "expected `{}`, found {}" ,
293
+ token_str,
294
+ match ( & self . token, self . subparser_name) {
295
+ ( token:: Token :: Eof , Some ( origin) ) => format!( "end of {}" , origin) ,
296
+ _ => this_token_str,
297
+ } ,
298
+ ) ;
299
+ let mut err = self . struct_span_err ( sp, & msg) ;
300
+ let label_exp = format ! ( "expected `{}`" , token_str) ;
301
+ match self . recover_closing_delimiter ( & [ t. clone ( ) ] , err) {
302
+ Err ( e) => err = e,
303
+ Ok ( recovered) => {
304
+ return Ok ( recovered) ;
305
+ }
306
+ }
307
+ let cm = self . sess . source_map ( ) ;
308
+ match ( cm. lookup_line ( prev_sp. lo ( ) ) , cm. lookup_line ( sp. lo ( ) ) ) {
309
+ ( Ok ( ref a) , Ok ( ref b) ) if a. line == b. line => {
310
+ // When the spans are in the same line, it means that the only content
311
+ // between them is whitespace, point only at the found token.
312
+ err. span_label ( sp, label_exp) ;
313
+ }
314
+ _ => {
315
+ err. span_label ( prev_sp, label_exp) ;
316
+ err. span_label ( sp, "unexpected token" ) ;
317
+ }
318
+ }
319
+ Err ( err)
320
+ }
321
+
270
322
/// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)`
271
323
/// and `await { <expr> }`.
272
324
crate fn parse_incorrect_await_syntax (
@@ -562,4 +614,23 @@ impl<'a> Parser<'a> {
562
614
}
563
615
}
564
616
617
+ crate fn expected_expression_found ( & self ) -> DiagnosticBuilder < ' a > {
618
+ let ( span, msg) = match ( & self . token , self . subparser_name ) {
619
+ ( & token:: Token :: Eof , Some ( origin) ) => {
620
+ let sp = self . sess . source_map ( ) . next_point ( self . span ) ;
621
+ ( sp, format ! ( "expected expression, found end of {}" , origin) )
622
+ }
623
+ _ => ( self . span , format ! (
624
+ "expected expression, found {}" ,
625
+ self . this_token_descr( ) ,
626
+ ) ) ,
627
+ } ;
628
+ let mut err = self . struct_span_err ( span, & msg) ;
629
+ let sp = self . sess . source_map ( ) . start_point ( self . span ) ;
630
+ if let Some ( sp) = self . sess . ambiguous_block_expr_parse . borrow ( ) . get ( & sp) {
631
+ self . sess . expr_parentheses_needed ( & mut err, * sp, None ) ;
632
+ }
633
+ err. span_label ( span, "expected expression" ) ;
634
+ err
635
+ }
565
636
}
0 commit comments