@@ -32,6 +32,18 @@ pub enum InvisibleOrigin {
3232 ProcMacro,
3333}
3434
35+ impl InvisibleOrigin {
36+ // Should the parser skip these invisible delimiters? Ideally this function
37+ // will eventually disappear and no invisible delimiters will be skipped.
38+ #[inline]
39+ pub fn skip(&self) -> bool {
40+ match self {
41+ InvisibleOrigin::MetaVar(_) => false,
42+ InvisibleOrigin::ProcMacro => true,
43+ }
44+ }
45+ }
46+
3547impl PartialEq for InvisibleOrigin {
3648 #[inline]
3749 fn eq(&self, _other: &InvisibleOrigin) -> bool {
@@ -125,8 +137,7 @@ impl Delimiter {
125137 pub fn skip(&self) -> bool {
126138 match self {
127139 Delimiter::Parenthesis | Delimiter::Bracket | Delimiter::Brace => false,
128- Delimiter::Invisible(InvisibleOrigin::MetaVar(_)) => false,
129- Delimiter::Invisible(InvisibleOrigin::ProcMacro) => true,
140+ Delimiter::Invisible(origin) => origin.skip(),
130141 }
131142 }
132143
@@ -140,6 +151,24 @@ impl Delimiter {
140151 _ => false,
141152 }
142153 }
154+
155+ pub fn as_open_token_kind(&self) -> TokenKind {
156+ match *self {
157+ Delimiter::Parenthesis => OpenParen,
158+ Delimiter::Brace => OpenBrace,
159+ Delimiter::Bracket => OpenBracket,
160+ Delimiter::Invisible(origin) => OpenInvisible(origin),
161+ }
162+ }
163+
164+ pub fn as_close_token_kind(&self) -> TokenKind {
165+ match *self {
166+ Delimiter::Parenthesis => CloseParen,
167+ Delimiter::Brace => CloseBrace,
168+ Delimiter::Bracket => CloseBracket,
169+ Delimiter::Invisible(origin) => CloseInvisible(origin),
170+ }
171+ }
143172}
144173
145174// Note that the suffix is *not* considered when deciding the `LitKind` in this
@@ -194,9 +223,9 @@ impl Lit {
194223 match token.uninterpolate().kind {
195224 Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)),
196225 Literal(token_lit) => Some(token_lit),
197- OpenDelim(Delimiter::Invisible (InvisibleOrigin::MetaVar(
226+ OpenInvisible (InvisibleOrigin::MetaVar(
198227 MetaVarKind::Literal | MetaVarKind::Expr { .. },
199- ))) => {
228+ )) => {
200229 // Unreachable with the current test suite.
201230 panic!("from_token metavar");
202231 }
@@ -426,10 +455,22 @@ pub enum TokenKind {
426455 Question,
427456 /// Used by proc macros for representing lifetimes, not generated by lexer right now.
428457 SingleQuote,
429- /// An opening delimiter (e.g., `{`).
430- OpenDelim(Delimiter),
431- /// A closing delimiter (e.g., `}`).
432- CloseDelim(Delimiter),
458+ /// `(`
459+ OpenParen,
460+ /// `)`
461+ CloseParen,
462+ /// `{`
463+ OpenBrace,
464+ /// `}`
465+ CloseBrace,
466+ /// `[`
467+ OpenBracket,
468+ /// `]`
469+ CloseBracket,
470+ /// Invisible opening delimiter, produced by a macro.
471+ OpenInvisible(InvisibleOrigin),
472+ /// Invisible closing delimiter, produced by a macro.
473+ CloseInvisible(InvisibleOrigin),
433474
434475 /* Literals */
435476 Literal(Lit),
@@ -530,6 +571,37 @@ impl TokenKind {
530571 pub fn should_end_const_arg(&self) -> bool {
531572 matches!(self, Gt | Ge | Shr | ShrEq)
532573 }
574+
575+ pub fn is_delim(&self) -> bool {
576+ self.open_delim().is_some() || self.close_delim().is_some()
577+ }
578+
579+ pub fn open_delim(&self) -> Option<Delimiter> {
580+ match *self {
581+ OpenParen => Some(Delimiter::Parenthesis),
582+ OpenBrace => Some(Delimiter::Brace),
583+ OpenBracket => Some(Delimiter::Bracket),
584+ OpenInvisible(origin) => Some(Delimiter::Invisible(origin)),
585+ _ => None,
586+ }
587+ }
588+
589+ pub fn close_delim(&self) -> Option<Delimiter> {
590+ match *self {
591+ CloseParen => Some(Delimiter::Parenthesis),
592+ CloseBrace => Some(Delimiter::Brace),
593+ CloseBracket => Some(Delimiter::Bracket),
594+ CloseInvisible(origin) => Some(Delimiter::Invisible(origin)),
595+ _ => None,
596+ }
597+ }
598+
599+ pub fn is_close_delim_or_eof(&self) -> bool {
600+ match self {
601+ CloseParen | CloseBrace | CloseBracket | CloseInvisible(_) | Eof => true,
602+ _ => false,
603+ }
604+ }
533605}
534606
535607impl Token {
@@ -559,7 +631,8 @@ impl Token {
559631 | DotDotDot | DotDotEq | Comma | Semi | Colon | PathSep | RArrow | LArrow
560632 | FatArrow | Pound | Dollar | Question | SingleQuote => true,
561633
562- OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..)
634+ OpenParen | CloseParen | OpenBrace | CloseBrace | OpenBracket | CloseBracket
635+ | OpenInvisible(_) | CloseInvisible(_) | Literal(..) | DocComment(..) | Ident(..)
563636 | NtIdent(..) | Lifetime(..) | NtLifetime(..) | Eof => false,
564637 }
565638 }
@@ -573,11 +646,12 @@ impl Token {
573646 /// **NB**: Take care when modifying this function, since it will change
574647 /// the stable set of tokens that are allowed to match an expr nonterminal.
575648 pub fn can_begin_expr(&self) -> bool {
576- use Delimiter::*;
577649 match self.uninterpolate().kind {
578650 Ident(name, is_raw) =>
579651 ident_can_begin_expr(name, self.span, is_raw), // value name or keyword
580- OpenDelim(Parenthesis | Brace | Bracket) | // tuple, array or block
652+ OpenParen | // tuple
653+ OpenBrace | // block
654+ OpenBracket | // array
581655 Literal(..) | // literal
582656 Bang | // operator not
583657 Minus | // unary minus
@@ -591,12 +665,12 @@ impl Token {
591665 PathSep | // global path
592666 Lifetime(..) | // labeled loop
593667 Pound => true, // expression attributes
594- OpenDelim(Delimiter::Invisible (InvisibleOrigin::MetaVar(
668+ OpenInvisible (InvisibleOrigin::MetaVar(
595669 MetaVarKind::Block |
596670 MetaVarKind::Expr { .. } |
597671 MetaVarKind::Literal |
598672 MetaVarKind::Path
599- ))) => true,
673+ )) => true,
600674 _ => false,
601675 }
602676 }
@@ -608,8 +682,8 @@ impl Token {
608682 match &self.uninterpolate().kind {
609683 // box, ref, mut, and other identifiers (can stricten)
610684 Ident(..) | NtIdent(..) |
611- OpenDelim(Delimiter::Parenthesis) | // tuple pattern
612- OpenDelim(Delimiter::Bracket) | // slice pattern
685+ OpenParen | // tuple pattern
686+ OpenBracket | // slice pattern
613687 And | // reference
614688 Minus | // negative literal
615689 AndAnd | // double reference
@@ -620,14 +694,14 @@ impl Token {
620694 Lt | // path (UFCS constant)
621695 Shl => true, // path (double UFCS)
622696 Or => matches!(pat_kind, PatWithOr), // leading vert `|` or-pattern
623- OpenDelim(Delimiter::Invisible (InvisibleOrigin::MetaVar(
697+ OpenInvisible (InvisibleOrigin::MetaVar(
624698 MetaVarKind::Expr { .. } |
625699 MetaVarKind::Literal |
626700 MetaVarKind::Meta { .. } |
627701 MetaVarKind::Pat(_) |
628702 MetaVarKind::Path |
629703 MetaVarKind::Ty { .. }
630- ))) => true,
704+ )) => true,
631705 _ => false,
632706 }
633707 }
@@ -637,8 +711,8 @@ impl Token {
637711 match self.uninterpolate().kind {
638712 Ident(name, is_raw) =>
639713 ident_can_begin_type(name, self.span, is_raw), // type name or keyword
640- OpenDelim(Delimiter::Parenthesis) | // tuple
641- OpenDelim(Delimiter::Bracket) | // array
714+ OpenParen | // tuple
715+ OpenBracket | // array
642716 Bang | // never
643717 Star | // raw pointer
644718 And | // reference
@@ -647,10 +721,10 @@ impl Token {
647721 Lifetime(..) | // lifetime bound in trait object
648722 Lt | Shl | // associated path
649723 PathSep => true, // global path
650- OpenDelim(Delimiter::Invisible (InvisibleOrigin::MetaVar(
724+ OpenInvisible (InvisibleOrigin::MetaVar(
651725 MetaVarKind::Ty { .. } |
652726 MetaVarKind::Path
653- ))) => true,
727+ )) => true,
654728 // For anonymous structs or unions, which only appear in specific positions
655729 // (type of struct fields or union fields), we don't consider them as regular types
656730 _ => false,
@@ -660,11 +734,11 @@ impl Token {
660734 /// Returns `true` if the token can appear at the start of a const param.
661735 pub fn can_begin_const_arg(&self) -> bool {
662736 match self.kind {
663- OpenDelim(Delimiter::Brace) | Literal(..) | Minus => true,
737+ OpenBrace | Literal(..) | Minus => true,
664738 Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
665- OpenDelim(Delimiter::Invisible (InvisibleOrigin::MetaVar(
739+ OpenInvisible (InvisibleOrigin::MetaVar(
666740 MetaVarKind::Expr { .. } | MetaVarKind::Block | MetaVarKind::Literal,
667- ))) => true,
741+ )) => true,
668742 _ => false,
669743 }
670744 }
@@ -711,7 +785,7 @@ impl Token {
711785 match self.uninterpolate().kind {
712786 Literal(..) | Minus => true,
713787 Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
714- OpenDelim(Delimiter::Invisible( InvisibleOrigin::MetaVar(mv_kind) )) => match mv_kind {
788+ OpenInvisible( InvisibleOrigin::MetaVar(mv_kind)) => match mv_kind {
715789 MetaVarKind::Literal => true,
716790 MetaVarKind::Expr { can_begin_literal_maybe_minus, .. } => {
717791 can_begin_literal_maybe_minus
@@ -725,7 +799,7 @@ impl Token {
725799 pub fn can_begin_string_literal(&self) -> bool {
726800 match self.uninterpolate().kind {
727801 Literal(..) => true,
728- OpenDelim(Delimiter::Invisible( InvisibleOrigin::MetaVar(mv_kind) )) => match mv_kind {
802+ OpenInvisible( InvisibleOrigin::MetaVar(mv_kind)) => match mv_kind {
729803 MetaVarKind::Literal => true,
730804 MetaVarKind::Expr { can_begin_string_literal, .. } => can_begin_string_literal,
731805 _ => false,
@@ -892,7 +966,7 @@ impl Token {
892966 /// from an expanded metavar?
893967 pub fn is_metavar_seq(&self) -> Option<MetaVarKind> {
894968 match self.kind {
895- OpenDelim(Delimiter::Invisible( InvisibleOrigin::MetaVar(kind) )) => Some(kind),
969+ OpenInvisible( InvisibleOrigin::MetaVar(kind)) => Some(kind),
896970 _ => None,
897971 }
898972 }
@@ -970,7 +1044,8 @@ impl Token {
9701044 Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | PlusEq | MinusEq | StarEq | SlashEq
9711045 | PercentEq | CaretEq | AndEq | OrEq | ShlEq | ShrEq | At | DotDotDot | DotDotEq
9721046 | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question
973- | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..)
1047+ | OpenParen | CloseParen | OpenBrace | CloseBrace | OpenBracket | CloseBracket
1048+ | OpenInvisible(_) | CloseInvisible(_) | Literal(..) | Ident(..) | NtIdent(..)
9741049 | Lifetime(..) | NtLifetime(..) | DocComment(..) | Eof,
9751050 _,
9761051 ) => {
0 commit comments