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