@@ -609,14 +609,21 @@ impl<'a> Parser<'a> {
609609 Parser :: token_to_string ( & self . token )
610610 }
611611
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+
612621 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+ }
620627 }
621628
622629 pub fn unexpected_last < T > ( & self , t : & token:: Token ) -> PResult < ' a , T > {
@@ -752,11 +759,27 @@ impl<'a> Parser<'a> {
752759 }
753760
754761 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 > {
755766 match self . token {
756767 token:: Ident ( i) => {
757768 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+ }
760783 }
761784 self . bump ( ) ;
762785 Ok ( i)
@@ -767,6 +790,12 @@ impl<'a> Parser<'a> {
767790 } else {
768791 let mut err = self . fatal ( & format ! ( "expected identifier, found `{}`" ,
769792 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+ }
770799 if self . token == token:: Underscore {
771800 err. note ( "`_` is a wildcard pattern, not an identifier" ) ;
772801 }
@@ -2058,7 +2087,7 @@ impl<'a> Parser<'a> {
20582087 self . bump ( ) ;
20592088 Ok ( Ident :: with_empty_ctxt ( name) )
20602089 } else {
2061- self . parse_ident ( )
2090+ self . parse_ident_common ( false )
20622091 }
20632092 }
20642093
@@ -2075,7 +2104,7 @@ impl<'a> Parser<'a> {
20752104 hi = self . prev_span ;
20762105 ( fieldname, self . parse_expr ( ) ?, false )
20772106 } else {
2078- let fieldname = self . parse_ident ( ) ?;
2107+ let fieldname = self . parse_ident_common ( false ) ?;
20792108 hi = self . prev_span ;
20802109
20812110 // Mimic `x: x` for the `x` field shorthand.
@@ -2426,6 +2455,7 @@ impl<'a> Parser<'a> {
24262455
24272456 fn parse_struct_expr ( & mut self , lo : Span , pth : ast:: Path , mut attrs : ThinVec < Attribute > )
24282457 -> PResult < ' a , P < Expr > > {
2458+ let struct_sp = lo. to ( self . prev_span ) ;
24292459 self . bump ( ) ;
24302460 let mut fields = Vec :: new ( ) ;
24312461 let mut base = None ;
@@ -2460,6 +2490,7 @@ impl<'a> Parser<'a> {
24602490 match self . parse_field ( ) {
24612491 Ok ( f) => fields. push ( f) ,
24622492 Err ( mut e) => {
2493+ e. span_label ( struct_sp, "while parsing this struct" ) ;
24632494 e. emit ( ) ;
24642495 self . recover_stmt ( ) ;
24652496 break ;
0 commit comments