Auto merge of #69801 - petrochenkov:nonorm, r= · rust-lang/rust@5f66c2a (original) (raw)

`@@ -14,8 +14,8 @@ use rustc_macros::HashStable_Generic;

`

14

14

`use rustc_span::symbol::kw;

`

15

15

`use rustc_span::symbol::Symbol;

`

16

16

`use rustc_span::{self, Span, DUMMY_SP};

`

17

``

`-

use std::fmt;

`

18

``

`-

use std::mem;

`

``

17

`+

use std::borrow::Cow;

`

``

18

`+

use std::{fmt, mem};

`

19

19

``

20

20

`#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]

`

21

21

`#[derive(HashStable_Generic)]

`

`@@ -328,6 +328,18 @@ impl Token {

`

328

328

` mem::replace(self, Token::dummy())

`

329

329

`}

`

330

330

``

``

331

`+

/// For interpolated tokens returns a span of the fragment to which the interpolated

`

``

332

`+

/// token refers, for all other tokens this is just a regular span.

`

``

333

`+

/// It is particularly important to use this for identifiers and lifetimes

`

``

334

`+

/// for which spans affect name resolution. This also includes edition checks

`

``

335

`+

/// for edition-specific keyword identifiers.

`

``

336

`+

pub fn uninterpolated_span(&self) -> Span {

`

``

337

`+

match &self.kind {

`

``

338

`+

Interpolated(nt) => nt.span(),

`

``

339

`+

_ => self.span,

`

``

340

`+

}

`

``

341

`+

}

`

``

342

+

331

343

`pub fn is_op(&self) -> bool {

`

332

344

`match self.kind {

`

333

345

`OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..)

`

`@@ -345,7 +357,7 @@ impl Token {

`

345

357

``

346

358

`` /// Returns true if the token can appear at the start of an expression.

``

347

359

`pub fn can_begin_expr(&self) -> bool {

`

348

``

`-

match self.kind {

`

``

360

`+

match self.uninterpolate().kind {

`

349

361

`Ident(name, is_raw) =>

`

350

362

`ident_can_begin_expr(name, self.span, is_raw), // value name or keyword

`

351

363

`OpenDelim(..) | // tuple, array or block

`

`@@ -363,12 +375,10 @@ impl Token {

`

363

375

`Lifetime(..) | // labeled loop

`

364

376

`Pound => true, // expression attributes

`

365

377

`Interpolated(ref nt) => match **nt {

`

366

``

`-

NtIdent(ident, is_raw) => ident_can_begin_expr(ident.name, ident.span, is_raw),

`

367

378

`NtLiteral(..) |

`

368

379

`NtExpr(..) |

`

369

380

`NtBlock(..) |

`

370

``

`-

NtPath(..) |

`

371

``

`-

NtLifetime(..) => true,

`

``

381

`+

NtPath(..) => true,

`

372

382

` _ => false,

`

373

383

`},

`

374

384

` _ => false,

`

`@@ -377,7 +387,7 @@ impl Token {

`

377

387

``

378

388

`` /// Returns true if the token can appear at the start of a type.

``

379

389

`pub fn can_begin_type(&self) -> bool {

`

380

``

`-

match self.kind {

`

``

390

`+

match self.uninterpolate().kind {

`

381

391

`Ident(name, is_raw) =>

`

382

392

`ident_can_begin_type(name, self.span, is_raw), // type name or keyword

`

383

393

`OpenDelim(Paren) | // tuple

`

`@@ -391,8 +401,7 @@ impl Token {

`

391

401

`Lt | BinOp(Shl) | // associated path

`

392

402

`ModSep => true, // global path

`

393

403

`Interpolated(ref nt) => match **nt {

`

394

``

`-

NtIdent(ident, is_raw) => ident_can_begin_type(ident.name, ident.span, is_raw),

`

395

``

`-

NtTy(..) | NtPath(..) | NtLifetime(..) => true,

`

``

404

`+

NtTy(..) | NtPath(..) => true,

`

396

405

` _ => false,

`

397

406

`},

`

398

407

` _ => false,

`

`@@ -433,38 +442,47 @@ impl Token {

`

433

442

`///

`

434

443

`` /// Keep this in sync with Lit::from_token.

``

435

444

`pub fn can_begin_literal_or_bool(&self) -> bool {

`

436

``

`-

match self.kind {

`

``

445

`+

match self.uninterpolate().kind {

`

437

446

`Literal(..) | BinOp(Minus) => true,

`

438

447

`Ident(name, false) if name.is_bool_lit() => true,

`

439

448

`Interpolated(ref nt) => match &**nt {

`

440

``

`-

NtIdent(ident, false) if ident.name.is_bool_lit() => true,

`

441

449

`NtExpr(e) | NtLiteral(e) => matches!(e.kind, ast::ExprKind::Lit(_)),

`

442

450

` _ => false,

`

443

451

`},

`

444

452

` _ => false,

`

445

453

`}

`

446

454

`}

`

447

455

``

``

456

`` +

// Turns interpolated identifier ($i: ident) or lifetime ($l: lifetime) token

``

``

457

`+

// into the regular identifier or lifetime token it refers to,

`

``

458

`+

// otherwise returns the original token.

`

``

459

`+

pub fn uninterpolate(&self) -> Cow<'_, Token> {

`

``

460

`+

match &self.kind {

`

``

461

`+

Interpolated(nt) => match **nt {

`

``

462

`+

NtIdent(ident, is_raw) => {

`

``

463

`+

Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span))

`

``

464

`+

}

`

``

465

`+

NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)),

`

``

466

`+

_ => Cow::Borrowed(self),

`

``

467

`+

},

`

``

468

`+

_ => Cow::Borrowed(self),

`

``

469

`+

}

`

``

470

`+

}

`

``

471

+

448

472

`/// Returns an identifier if this token is an identifier.

`

449

473

`pub fn ident(&self) -> Option<(ast::Ident, /* is_raw */ bool)> {

`

450

``

`-

match self.kind {

`

451

``

`-

Ident(name, is_raw) => Some((ast::Ident::new(name, self.span), is_raw)),

`

452

``

`-

Interpolated(ref nt) => match **nt {

`

453

``

`-

NtIdent(ident, is_raw) => Some((ident, is_raw)),

`

454

``

`-

_ => None,

`

455

``

`-

},

`

``

474

`+

let token = self.uninterpolate();

`

``

475

`+

match token.kind {

`

``

476

`+

Ident(name, is_raw) => Some((ast::Ident::new(name, token.span), is_raw)),

`

456

477

` _ => None,

`

457

478

`}

`

458

479

`}

`

459

480

``

460

481

`/// Returns a lifetime identifier if this token is a lifetime.

`

461

482

`pub fn lifetime(&self) -> Optionast::Ident {

`

462

``

`-

match self.kind {

`

463

``

`-

Lifetime(name) => Some(ast::Ident::new(name, self.span)),

`

464

``

`-

Interpolated(ref nt) => match **nt {

`

465

``

`-

NtLifetime(ident) => Some(ident),

`

466

``

`-

_ => None,

`

467

``

`-

},

`

``

483

`+

let token = self.uninterpolate();

`

``

484

`+

match token.kind {

`

``

485

`+

Lifetime(name) => Some(ast::Ident::new(name, token.span)),

`

468

486

` _ => None,

`

469

487

`}

`

470

488

`}

`

`@@ -714,6 +732,24 @@ pub enum Nonterminal {

`

714

732

`#[cfg(target_arch = "x86_64")]

`

715

733

`rustc_data_structures::static_assert_size!(Nonterminal, 40);

`

716

734

``

``

735

`+

impl Nonterminal {

`

``

736

`+

fn span(&self) -> Span {

`

``

737

`+

match self {

`

``

738

`+

NtItem(item) => item.span,

`

``

739

`+

NtBlock(block) => block.span,

`

``

740

`+

NtStmt(stmt) => stmt.span,

`

``

741

`+

NtPat(pat) => pat.span,

`

``

742

`+

NtExpr(expr) | NtLiteral(expr) => expr.span,

`

``

743

`+

NtTy(ty) => ty.span,

`

``

744

`+

NtIdent(ident, _) | NtLifetime(ident) => ident.span,

`

``

745

`+

NtMeta(attr_item) => attr_item.span(),

`

``

746

`+

NtPath(path) => path.span,

`

``

747

`+

NtVis(vis) => vis.span,

`

``

748

`+

NtTT(tt) => tt.span(),

`

``

749

`+

}

`

``

750

`+

}

`

``

751

`+

}

`

``

752

+

717

753

`impl PartialEq for Nonterminal {

`

718

754

`fn eq(&self, rhs: &Self) -> bool {

`

719

755

`match (self, rhs) {

`