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| {

`