Improve Path
spans. · rust-lang/rust@8fde04b (original) (raw)
`@@ -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,
`
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> {
`
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| {
`