@@ -609,14 +609,21 @@ impl<'a> Parser<'a> {
609
609
Parser :: token_to_string ( & self . token )
610
610
}
611
611
612
+ pub fn token_descr ( & self ) -> Option < & ' static str > {
613
+ Some ( match & self . token {
614
+ t if t. is_special_ident ( ) => "reserved identifier" ,
615
+ t if t. is_used_keyword ( ) => "keyword" ,
616
+ t if t. is_unused_keyword ( ) => "reserved keyword" ,
617
+ _ => return None ,
618
+ } )
619
+ }
620
+
612
621
pub fn this_token_descr ( & self ) -> String {
613
- let prefix = match & self . token {
614
- t if t. is_special_ident ( ) => "reserved identifier " ,
615
- t if t. is_used_keyword ( ) => "keyword " ,
616
- t if t. is_unused_keyword ( ) => "reserved keyword " ,
617
- _ => "" ,
618
- } ;
619
- format ! ( "{}`{}`" , prefix, self . this_token_to_string( ) )
622
+ if let Some ( prefix) = self . token_descr ( ) {
623
+ format ! ( "{} `{}`" , prefix, self . this_token_to_string( ) )
624
+ } else {
625
+ format ! ( "`{}`" , self . this_token_to_string( ) )
626
+ }
620
627
}
621
628
622
629
pub fn unexpected_last < T > ( & self , t : & token:: Token ) -> PResult < ' a , T > {
@@ -752,11 +759,27 @@ impl<'a> Parser<'a> {
752
759
}
753
760
754
761
pub fn parse_ident ( & mut self ) -> PResult < ' a , ast:: Ident > {
762
+ self . parse_ident_common ( true )
763
+ }
764
+
765
+ fn parse_ident_common ( & mut self , recover : bool ) -> PResult < ' a , ast:: Ident > {
755
766
match self . token {
756
767
token:: Ident ( i) => {
757
768
if self . token . is_reserved_ident ( ) {
758
- self . span_err ( self . span , & format ! ( "expected identifier, found {}" ,
759
- self . this_token_descr( ) ) ) ;
769
+ let mut err = self . struct_span_err ( self . span ,
770
+ & format ! ( "expected identifier, found {}" ,
771
+ self . this_token_descr( ) ) ) ;
772
+ if let Some ( token_descr) = self . token_descr ( ) {
773
+ err. span_label ( self . span , format ! ( "expected identifier, found {}" ,
774
+ token_descr) ) ;
775
+ } else {
776
+ err. span_label ( self . span , "expected identifier" ) ;
777
+ }
778
+ if recover {
779
+ err. emit ( ) ;
780
+ } else {
781
+ return Err ( err) ;
782
+ }
760
783
}
761
784
self . bump ( ) ;
762
785
Ok ( i)
@@ -767,6 +790,12 @@ impl<'a> Parser<'a> {
767
790
} else {
768
791
let mut err = self . fatal ( & format ! ( "expected identifier, found `{}`" ,
769
792
self . this_token_to_string( ) ) ) ;
793
+ if let Some ( token_descr) = self . token_descr ( ) {
794
+ err. span_label ( self . span , format ! ( "expected identifier, found {}" ,
795
+ token_descr) ) ;
796
+ } else {
797
+ err. span_label ( self . span , "expected identifier" ) ;
798
+ }
770
799
if self . token == token:: Underscore {
771
800
err. note ( "`_` is a wildcard pattern, not an identifier" ) ;
772
801
}
@@ -2058,7 +2087,7 @@ impl<'a> Parser<'a> {
2058
2087
self . bump ( ) ;
2059
2088
Ok ( Ident :: with_empty_ctxt ( name) )
2060
2089
} else {
2061
- self . parse_ident ( )
2090
+ self . parse_ident_common ( false )
2062
2091
}
2063
2092
}
2064
2093
@@ -2075,7 +2104,7 @@ impl<'a> Parser<'a> {
2075
2104
hi = self . prev_span ;
2076
2105
( fieldname, self . parse_expr ( ) ?, false )
2077
2106
} else {
2078
- let fieldname = self . parse_ident ( ) ?;
2107
+ let fieldname = self . parse_ident_common ( false ) ?;
2079
2108
hi = self . prev_span ;
2080
2109
2081
2110
// Mimic `x: x` for the `x` field shorthand.
@@ -2426,6 +2455,7 @@ impl<'a> Parser<'a> {
2426
2455
2427
2456
fn parse_struct_expr ( & mut self , lo : Span , pth : ast:: Path , mut attrs : ThinVec < Attribute > )
2428
2457
-> PResult < ' a , P < Expr > > {
2458
+ let struct_sp = lo. to ( self . prev_span ) ;
2429
2459
self . bump ( ) ;
2430
2460
let mut fields = Vec :: new ( ) ;
2431
2461
let mut base = None ;
@@ -2460,6 +2490,7 @@ impl<'a> Parser<'a> {
2460
2490
match self . parse_field ( ) {
2461
2491
Ok ( f) => fields. push ( f) ,
2462
2492
Err ( mut e) => {
2493
+ e. span_label ( struct_sp, "while parsing this struct" ) ;
2463
2494
e. emit ( ) ;
2464
2495
self . recover_stmt ( ) ;
2465
2496
break ;
0 commit comments