@@ -160,6 +160,7 @@ pub struct Parser<'a> {
160
160
/// the span of the current token:
161
161
pub span : Span ,
162
162
/// the span of the previous token:
163
+ pub meta_var_span : Option < Span > ,
163
164
pub prev_span : Span ,
164
165
/// the previous token kind
165
166
prev_token_kind : PrevTokenKind ,
@@ -417,6 +418,7 @@ impl<'a> Parser<'a> {
417
418
token : token:: Underscore ,
418
419
span : syntax_pos:: DUMMY_SP ,
419
420
prev_span : syntax_pos:: DUMMY_SP ,
421
+ meta_var_span : None ,
420
422
prev_token_kind : PrevTokenKind :: Other ,
421
423
restrictions : Restrictions :: empty ( ) ,
422
424
obsolete_set : HashSet :: new ( ) ,
@@ -443,6 +445,7 @@ impl<'a> Parser<'a> {
443
445
parser. directory . path = PathBuf :: from ( sess. codemap ( ) . span_to_filename ( parser. span ) ) ;
444
446
parser. directory . path . pop ( ) ;
445
447
}
448
+ parser. process_potential_macro_variable ( ) ;
446
449
parser
447
450
}
448
451
@@ -1012,7 +1015,7 @@ impl<'a> Parser<'a> {
1012
1015
self . bug ( "attempted to bump the parser past EOF (may be stuck in a loop)" ) ;
1013
1016
}
1014
1017
1015
- self . prev_span = self . span ;
1018
+ self . prev_span = self . meta_var_span . take ( ) . unwrap_or ( self . span ) ;
1016
1019
1017
1020
// Record last token kind for possible error recovery.
1018
1021
self . prev_token_kind = match self . token {
@@ -1028,7 +1031,7 @@ impl<'a> Parser<'a> {
1028
1031
self . token = next. tok ;
1029
1032
self . expected_tokens . clear ( ) ;
1030
1033
// check after each token
1031
- self . check_unknown_macro_variable ( ) ;
1034
+ self . process_potential_macro_variable ( ) ;
1032
1035
}
1033
1036
1034
1037
/// Advance the parser using provided token as a next one. Use this when
@@ -1722,7 +1725,7 @@ impl<'a> Parser<'a> {
1722
1725
pub fn parse_path ( & mut self , mode : PathStyle ) -> PResult < ' a , ast:: Path > {
1723
1726
maybe_whole ! ( self , NtPath , |x| x) ;
1724
1727
1725
- let lo = self . span ;
1728
+ let lo = self . meta_var_span . unwrap_or ( self . span ) ;
1726
1729
let is_global = self . eat ( & token:: ModSep ) ;
1727
1730
1728
1731
// Parse any number of segments and bound sets. A segment is an
@@ -1744,13 +1747,9 @@ impl<'a> Parser<'a> {
1744
1747
segments. insert ( 0 , PathSegment :: crate_root ( ) ) ;
1745
1748
}
1746
1749
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
-
1751
1750
// Assemble the result.
1752
1751
Ok ( ast:: Path {
1753
- span : span ,
1752
+ span : lo . to ( self . prev_span ) ,
1754
1753
segments : segments,
1755
1754
} )
1756
1755
}
@@ -1763,8 +1762,8 @@ impl<'a> Parser<'a> {
1763
1762
let mut segments = Vec :: new ( ) ;
1764
1763
loop {
1765
1764
// First, parse an identifier.
1765
+ let ident_span = self . span ;
1766
1766
let identifier = self . parse_path_segment_ident ( ) ?;
1767
- let ident_span = self . prev_span ;
1768
1767
1769
1768
if self . check ( & token:: ModSep ) && self . look_ahead ( 1 , |t| * t == token:: Lt ) {
1770
1769
self . bump ( ) ;
@@ -1831,8 +1830,8 @@ impl<'a> Parser<'a> {
1831
1830
let mut segments = Vec :: new ( ) ;
1832
1831
loop {
1833
1832
// First, parse an identifier.
1833
+ let ident_span = self . span ;
1834
1834
let identifier = self . parse_path_segment_ident ( ) ?;
1835
- let ident_span = self . prev_span ;
1836
1835
1837
1836
// If we do not see a `::`, stop.
1838
1837
if !self . eat ( & token:: ModSep ) {
@@ -1873,10 +1872,11 @@ impl<'a> Parser<'a> {
1873
1872
let mut segments = Vec :: new ( ) ;
1874
1873
loop {
1875
1874
// First, parse an identifier.
1875
+ let ident_span = self . span ;
1876
1876
let identifier = self . parse_path_segment_ident ( ) ?;
1877
1877
1878
1878
// Assemble and push the result.
1879
- segments. push ( PathSegment :: from_ident ( identifier, self . prev_span ) ) ;
1879
+ segments. push ( PathSegment :: from_ident ( identifier, ident_span ) ) ;
1880
1880
1881
1881
// If we do not see a `::` or see `::{`/`::*`, stop.
1882
1882
if !self . check ( & token:: ModSep ) || self . is_import_coupler ( ) {
@@ -1896,8 +1896,9 @@ impl<'a> Parser<'a> {
1896
1896
fn expect_lifetime ( & mut self ) -> Lifetime {
1897
1897
match self . token {
1898
1898
token:: Lifetime ( ident) => {
1899
+ let ident_span = self . span ;
1899
1900
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 }
1901
1902
}
1902
1903
_ => self . span_bug ( self . span , "not a lifetime" )
1903
1904
}
@@ -2568,10 +2569,23 @@ impl<'a> Parser<'a> {
2568
2569
return Ok ( e) ;
2569
2570
}
2570
2571
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 ;
2575
2589
}
2576
2590
2577
2591
/// parse a single token tree from the input.
@@ -2589,9 +2603,9 @@ impl<'a> Parser<'a> {
2589
2603
} ,
2590
2604
token:: CloseDelim ( _) | token:: Eof => unreachable ! ( ) ,
2591
2605
_ => {
2592
- let token = mem:: replace ( & mut self . token , token:: Underscore ) ;
2606
+ let ( token, span ) = ( mem:: replace ( & mut self . token , token:: Underscore ) , self . span ) ;
2593
2607
self . bump ( ) ;
2594
- TokenTree :: Token ( self . prev_span , token)
2608
+ TokenTree :: Token ( span , token)
2595
2609
}
2596
2610
}
2597
2611
}
@@ -3489,9 +3503,9 @@ impl<'a> Parser<'a> {
3489
3503
fn parse_pat_ident ( & mut self ,
3490
3504
binding_mode : ast:: BindingMode )
3491
3505
-> PResult < ' a , PatKind > {
3506
+ let ident_span = self . span ;
3492
3507
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} ;
3495
3509
let sub = if self . eat ( & token:: At ) {
3496
3510
Some ( self . parse_pat ( ) ?)
3497
3511
} else {
@@ -4364,7 +4378,7 @@ impl<'a> Parser<'a> {
4364
4378
fn parse_self_arg ( & mut self ) -> PResult < ' a , Option < Arg > > {
4365
4379
let expect_ident = |this : & mut Self | match this. token {
4366
4380
// 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) }
4368
4382
_ => unreachable ! ( )
4369
4383
} ;
4370
4384
let isolated_self = |this : & mut Self , n| {
0 commit comments