@@ -160,6 +160,7 @@ pub struct Parser<'a> {
160160 /// the span of the current token:
161161 pub span : Span ,
162162 /// the span of the previous token:
163+ pub meta_var_span : Option < Span > ,
163164 pub prev_span : Span ,
164165 /// the previous token kind
165166 prev_token_kind : PrevTokenKind ,
@@ -417,6 +418,7 @@ impl<'a> Parser<'a> {
417418 token : token:: Underscore ,
418419 span : syntax_pos:: DUMMY_SP ,
419420 prev_span : syntax_pos:: DUMMY_SP ,
421+ meta_var_span : None ,
420422 prev_token_kind : PrevTokenKind :: Other ,
421423 restrictions : Restrictions :: empty ( ) ,
422424 obsolete_set : HashSet :: new ( ) ,
@@ -443,6 +445,7 @@ impl<'a> Parser<'a> {
443445 parser. directory . path = PathBuf :: from ( sess. codemap ( ) . span_to_filename ( parser. span ) ) ;
444446 parser. directory . path . pop ( ) ;
445447 }
448+ parser. process_potential_macro_variable ( ) ;
446449 parser
447450 }
448451
@@ -1012,7 +1015,7 @@ impl<'a> Parser<'a> {
10121015 self . bug ( "attempted to bump the parser past EOF (may be stuck in a loop)" ) ;
10131016 }
10141017
1015- self . prev_span = self . span ;
1018+ self . prev_span = self . meta_var_span . take ( ) . unwrap_or ( self . span ) ;
10161019
10171020 // Record last token kind for possible error recovery.
10181021 self . prev_token_kind = match self . token {
@@ -1028,7 +1031,7 @@ impl<'a> Parser<'a> {
10281031 self . token = next. tok ;
10291032 self . expected_tokens . clear ( ) ;
10301033 // check after each token
1031- self . check_unknown_macro_variable ( ) ;
1034+ self . process_potential_macro_variable ( ) ;
10321035 }
10331036
10341037 /// Advance the parser using provided token as a next one. Use this when
@@ -1722,7 +1725,7 @@ impl<'a> Parser<'a> {
17221725 pub fn parse_path ( & mut self , mode : PathStyle ) -> PResult < ' a , ast:: Path > {
17231726 maybe_whole ! ( self , NtPath , |x| x) ;
17241727
1725- let lo = self . span ;
1728+ let lo = self . meta_var_span . unwrap_or ( self . span ) ;
17261729 let is_global = self . eat ( & token:: ModSep ) ;
17271730
17281731 // Parse any number of segments and bound sets. A segment is an
@@ -1744,13 +1747,9 @@ impl<'a> Parser<'a> {
17441747 segments. insert ( 0 , PathSegment :: crate_root ( ) ) ;
17451748 }
17461749
1747- // Assemble the span.
1748- // FIXME(#39450) This is bogus if part of the path is macro generated.
1749- let span = lo. to ( self . prev_span ) ;
1750-
17511750 // Assemble the result.
17521751 Ok ( ast:: Path {
1753- span : span ,
1752+ span : lo . to ( self . prev_span ) ,
17541753 segments : segments,
17551754 } )
17561755 }
@@ -1763,8 +1762,8 @@ impl<'a> Parser<'a> {
17631762 let mut segments = Vec :: new ( ) ;
17641763 loop {
17651764 // First, parse an identifier.
1765+ let ident_span = self . span ;
17661766 let identifier = self . parse_path_segment_ident ( ) ?;
1767- let ident_span = self . prev_span ;
17681767
17691768 if self . check ( & token:: ModSep ) && self . look_ahead ( 1 , |t| * t == token:: Lt ) {
17701769 self . bump ( ) ;
@@ -1831,8 +1830,8 @@ impl<'a> Parser<'a> {
18311830 let mut segments = Vec :: new ( ) ;
18321831 loop {
18331832 // First, parse an identifier.
1833+ let ident_span = self . span ;
18341834 let identifier = self . parse_path_segment_ident ( ) ?;
1835- let ident_span = self . prev_span ;
18361835
18371836 // If we do not see a `::`, stop.
18381837 if !self . eat ( & token:: ModSep ) {
@@ -1873,10 +1872,11 @@ impl<'a> Parser<'a> {
18731872 let mut segments = Vec :: new ( ) ;
18741873 loop {
18751874 // First, parse an identifier.
1875+ let ident_span = self . span ;
18761876 let identifier = self . parse_path_segment_ident ( ) ?;
18771877
18781878 // Assemble and push the result.
1879- segments. push ( PathSegment :: from_ident ( identifier, self . prev_span ) ) ;
1879+ segments. push ( PathSegment :: from_ident ( identifier, ident_span ) ) ;
18801880
18811881 // If we do not see a `::` or see `::{`/`::*`, stop.
18821882 if !self . check ( & token:: ModSep ) || self . is_import_coupler ( ) {
@@ -1896,8 +1896,9 @@ impl<'a> Parser<'a> {
18961896 fn expect_lifetime ( & mut self ) -> Lifetime {
18971897 match self . token {
18981898 token:: Lifetime ( ident) => {
1899+ let ident_span = self . span ;
18991900 self . bump ( ) ;
1900- Lifetime { name : ident. name , span : self . prev_span , id : ast:: DUMMY_NODE_ID }
1901+ Lifetime { name : ident. name , span : ident_span , id : ast:: DUMMY_NODE_ID }
19011902 }
19021903 _ => self . span_bug ( self . span , "not a lifetime" )
19031904 }
@@ -2568,10 +2569,23 @@ impl<'a> Parser<'a> {
25682569 return Ok ( e) ;
25692570 }
25702571
2571- pub fn check_unknown_macro_variable ( & mut self ) {
2572- if let token:: SubstNt ( name) = self . token {
2573- self . fatal ( & format ! ( "unknown macro variable `{}`" , name) ) . emit ( )
2574- }
2572+ pub fn process_potential_macro_variable ( & mut self ) {
2573+ let ident = match self . token {
2574+ token:: SubstNt ( name) => {
2575+ self . fatal ( & format ! ( "unknown macro variable `{}`" , name) ) . emit ( ) ;
2576+ return
2577+ }
2578+ token:: Interpolated ( ref nt) => {
2579+ self . meta_var_span = Some ( self . span ) ;
2580+ match * * nt {
2581+ token:: NtIdent ( ident) => ident,
2582+ _ => return ,
2583+ }
2584+ }
2585+ _ => return ,
2586+ } ;
2587+ self . token = token:: Ident ( ident. node ) ;
2588+ self . span = ident. span ;
25752589 }
25762590
25772591 /// parse a single token tree from the input.
@@ -2589,9 +2603,9 @@ impl<'a> Parser<'a> {
25892603 } ,
25902604 token:: CloseDelim ( _) | token:: Eof => unreachable ! ( ) ,
25912605 _ => {
2592- let token = mem:: replace ( & mut self . token , token:: Underscore ) ;
2606+ let ( token, span ) = ( mem:: replace ( & mut self . token , token:: Underscore ) , self . span ) ;
25932607 self . bump ( ) ;
2594- TokenTree :: Token ( self . prev_span , token)
2608+ TokenTree :: Token ( span , token)
25952609 }
25962610 }
25972611 }
@@ -3489,9 +3503,9 @@ impl<'a> Parser<'a> {
34893503 fn parse_pat_ident ( & mut self ,
34903504 binding_mode : ast:: BindingMode )
34913505 -> PResult < ' a , PatKind > {
3506+ let ident_span = self . span ;
34923507 let ident = self . parse_ident ( ) ?;
3493- let prev_span = self . prev_span ;
3494- let name = codemap:: Spanned { span : prev_span, node : ident} ;
3508+ let name = codemap:: Spanned { span : ident_span, node : ident} ;
34953509 let sub = if self . eat ( & token:: At ) {
34963510 Some ( self . parse_pat ( ) ?)
34973511 } else {
@@ -4364,7 +4378,7 @@ impl<'a> Parser<'a> {
43644378 fn parse_self_arg ( & mut self ) -> PResult < ' a , Option < Arg > > {
43654379 let expect_ident = |this : & mut Self | match this. token {
43664380 // Preserve hygienic context.
4367- token:: Ident ( ident) => { this. bump ( ) ; codemap:: respan ( this . prev_span , ident) }
4381+ token:: Ident ( ident) => { let sp = this. span ; this . bump ( ) ; codemap:: respan ( sp , ident) }
43684382 _ => unreachable ! ( )
43694383 } ;
43704384 let isolated_self = |this : & mut Self , n| {
0 commit comments