2019-02-06 17:33:01 +00:00
pub use BinOpToken ::* ;
2019-05-18 22:04:26 +00:00
pub use LitKind ::* ;
2019-12-22 22:42:04 +00:00
pub use Nonterminal ::* ;
2019-06-04 14:55:23 +00:00
pub use TokenKind ::* ;
2019-02-06 17:33:01 +00:00
2019-10-09 00:34:22 +00:00
use crate ::ast ;
2019-02-06 17:33:01 +00:00
use crate ::ptr ::P ;
2022-09-15 16:27:23 +00:00
use crate ::util ::case ::Case ;
2019-02-06 17:33:01 +00:00
2019-11-10 17:24:37 +00:00
use rustc_data_structures ::stable_hasher ::{ HashStable , StableHasher } ;
2019-02-14 22:10:02 +00:00
use rustc_data_structures ::sync ::Lrc ;
2019-11-16 10:53:44 +00:00
use rustc_macros ::HashStable_Generic ;
2020-06-14 11:30:42 +00:00
use rustc_span ::symbol ::{ kw , sym } ;
2020-04-19 11:00:18 +00:00
use rustc_span ::symbol ::{ Ident , Symbol } ;
2021-03-14 20:55:59 +00:00
use rustc_span ::{ self , edition ::Edition , Span , DUMMY_SP } ;
2020-03-07 11:37:38 +00:00
use std ::borrow ::Cow ;
2022-09-26 02:57:37 +00:00
use std ::fmt ;
2010-08-18 18:35:12 +00:00
2020-06-11 14:49:57 +00:00
#[ derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic) ]
2020-07-21 19:16:19 +00:00
pub enum CommentKind {
Line ,
Block ,
}
2020-06-11 14:49:57 +00:00
#[ derive(Clone, PartialEq, Encodable, Decodable, Hash, Debug, Copy) ]
2019-11-23 13:47:31 +00:00
#[ derive(HashStable_Generic) ]
2014-10-27 08:22:52 +00:00
pub enum BinOpToken {
Plus ,
Minus ,
Star ,
Slash ,
Percent ,
Caret ,
And ,
Or ,
Shl ,
Shr ,
2010-09-09 22:59:29 +00:00
}
2022-04-26 12:40:14 +00:00
/// Describes how a sequence of token trees is delimited.
/// Cannot use `proc_macro::Delimiter` directly because this
/// structure should implement some additional traits.
/// The `None` variant is also renamed to `Invisible` to be
/// less confusing and better convey the semantics.
#[ derive(Copy, Clone, Debug, PartialEq, Eq) ]
#[ derive(Encodable, Decodable, Hash, HashStable_Generic) ]
pub enum Delimiter {
/// `( ... )`
Parenthesis ,
/// `{ ... }`
2014-10-29 10:37:54 +00:00
Brace ,
2022-04-26 12:40:14 +00:00
/// `[ ... ]`
Bracket ,
2022-06-02 00:49:22 +00:00
/// `Ø ... Ø`
2022-04-26 12:40:14 +00:00
/// An invisible delimiter, that may, for example, appear around tokens coming from a
/// "macro variable" `$var`. It is important to preserve operator priorities in cases like
/// `$var * 3` where `$var` is `1 + 2`.
2022-06-02 00:49:22 +00:00
/// Invisible delimiters might not survive roundtrip of a token stream through a string.
2022-04-26 12:40:14 +00:00
Invisible ,
2014-10-29 10:37:54 +00:00
}
2022-10-10 02:40:56 +00:00
// Note that the suffix is *not* considered when deciding the `LitKind` in this
// type. This means that float literals like `1f32` are classified by this type
// as `Int`. Only upon conversion to `ast::LitKind` will such a literal be
// given the `Float` kind.
2020-06-11 14:49:57 +00:00
#[ derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic) ]
2019-05-18 22:04:26 +00:00
pub enum LitKind {
Bool , // AST only, must never appear in a `Token`
Byte ,
Char ,
2022-10-10 02:40:56 +00:00
Integer , // e.g. `1`, `1u8`, `1f32`
Float , // e.g. `1.`, `1.0`, `1e3f32`
2019-05-18 22:04:26 +00:00
Str ,
2022-03-23 22:07:39 +00:00
StrRaw ( u8 ) , // raw string delimited by `n` hash symbols
2019-05-18 22:04:26 +00:00
ByteStr ,
2022-03-23 22:07:39 +00:00
ByteStrRaw ( u8 ) , // raw byte string delimited by `n` hash symbols
2023-03-05 15:03:22 +00:00
CStr ,
CStrRaw ( u8 ) ,
2019-05-18 22:04:26 +00:00
Err ,
2014-11-18 23:17:40 +00:00
}
2019-05-19 16:56:45 +00:00
/// A literal token.
2020-06-11 14:49:57 +00:00
#[ derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic) ]
2019-05-18 22:04:26 +00:00
pub struct Lit {
pub kind : LitKind ,
pub symbol : Symbol ,
pub suffix : Option < Symbol > ,
}
2019-05-18 14:36:30 +00:00
2022-10-10 02:40:56 +00:00
impl Lit {
pub fn new ( kind : LitKind , symbol : Symbol , suffix : Option < Symbol > ) -> Lit {
Lit { kind , symbol , suffix }
}
/// Returns `true` if this is semantically a float literal. This includes
/// ones like `1f32` that have an `Integer` kind but a float suffix.
pub fn is_semantic_float ( & self ) -> bool {
match self . kind {
LitKind ::Float = > true ,
LitKind ::Integer = > match self . suffix {
Some ( sym ) = > sym = = sym ::f32 | | sym = = sym ::f64 ,
None = > false ,
} ,
_ = > false ,
}
}
/// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation.
pub fn from_token ( token : & Token ) -> Option < Lit > {
match token . uninterpolate ( ) . kind {
Ident ( name , false ) if name . is_bool_lit ( ) = > {
Some ( Lit ::new ( Bool , name , None ) )
}
Literal ( token_lit ) = > Some ( token_lit ) ,
Interpolated ( ref nt )
if let NtExpr ( expr ) | NtLiteral ( expr ) = & * * nt
& & let ast ::ExprKind ::Lit ( token_lit ) = expr . kind = >
{
2022-12-12 17:06:24 +00:00
Some ( token_lit )
2022-10-10 02:40:56 +00:00
}
_ = > None ,
}
}
}
2019-06-26 11:23:27 +00:00
impl fmt ::Display for Lit {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
let Lit { kind , symbol , suffix } = * self ;
match kind {
2022-12-19 09:31:55 +00:00
Byte = > write! ( f , " b'{symbol}' " ) ? ,
Char = > write! ( f , " '{symbol}' " ) ? ,
Str = > write! ( f , " \" {symbol} \" " ) ? ,
2019-12-22 22:42:04 +00:00
StrRaw ( n ) = > write! (
f ,
" r{delim} \" {string} \" {delim} " ,
delim = " # " . repeat ( n as usize ) ,
string = symbol
) ? ,
2022-12-19 09:31:55 +00:00
ByteStr = > write! ( f , " b \" {symbol} \" " ) ? ,
2019-12-22 22:42:04 +00:00
ByteStrRaw ( n ) = > write! (
f ,
" br{delim} \" {string} \" {delim} " ,
delim = " # " . repeat ( n as usize ) ,
string = symbol
) ? ,
2023-03-05 15:03:22 +00:00
CStr = > write! ( f , " c \" {symbol} \" " ) ? ,
CStrRaw ( n ) = > {
write! ( f , " cr{delim} \" {symbol} \" {delim} " , delim = " # " . repeat ( n as usize ) ) ?
}
2022-12-19 09:31:55 +00:00
Integer | Float | Bool | Err = > write! ( f , " {symbol} " ) ? ,
2019-06-26 11:23:27 +00:00
}
if let Some ( suffix ) = suffix {
2022-12-19 09:31:55 +00:00
write! ( f , " {suffix} " ) ? ;
2019-06-26 11:23:27 +00:00
}
Ok ( ( ) )
}
}
2019-05-18 22:04:26 +00:00
impl LitKind {
2019-05-19 16:56:45 +00:00
/// An English article for the literal token kind.
2019-10-15 20:48:13 +00:00
pub fn article ( self ) -> & 'static str {
2019-05-18 22:04:26 +00:00
match self {
Integer | Err = > " an " ,
2019-05-18 14:36:30 +00:00
_ = > " a " ,
}
}
2019-10-15 20:48:13 +00:00
pub fn descr ( self ) -> & 'static str {
2019-05-18 22:04:26 +00:00
match self {
Bool = > panic! ( " literal token contains `Lit::Bool` " ) ,
2019-05-19 16:56:45 +00:00
Byte = > " byte " ,
Char = > " char " ,
Integer = > " integer " ,
Float = > " float " ,
Str | StrRaw ( .. ) = > " string " ,
ByteStr | ByteStrRaw ( .. ) = > " byte string " ,
2023-03-05 15:03:22 +00:00
CStr | CStrRaw ( .. ) = > " C string " ,
2019-05-19 16:56:45 +00:00
Err = > " error " ,
2014-11-19 04:48:38 +00:00
}
}
2018-04-19 02:36:48 +00:00
2022-05-20 23:51:09 +00:00
pub ( crate ) fn may_have_suffix ( self ) -> bool {
2020-12-24 01:55:21 +00:00
matches! ( self , Integer | Float | Err )
2019-05-10 00:00:51 +00:00
}
2014-11-19 04:48:38 +00:00
}
2020-04-19 11:00:18 +00:00
pub fn ident_can_begin_expr ( name : Symbol , span : Span , is_raw : bool ) -> bool {
2019-06-05 08:56:06 +00:00
let ident_token = Token ::new ( Ident ( name , is_raw ) , span ) ;
2017-01-27 05:51:20 +00:00
2019-12-22 22:42:04 +00:00
! ident_token . is_reserved_ident ( )
| | ident_token . is_path_segment_keyword ( )
2020-02-22 17:19:49 +00:00
| | [
kw ::Async ,
kw ::Do ,
kw ::Box ,
kw ::Break ,
2020-09-21 20:55:58 +00:00
kw ::Const ,
2020-02-22 17:19:49 +00:00
kw ::Continue ,
kw ::False ,
kw ::For ,
kw ::If ,
kw ::Let ,
kw ::Loop ,
kw ::Match ,
kw ::Move ,
kw ::Return ,
kw ::True ,
2020-09-03 06:39:50 +00:00
kw ::Try ,
2020-02-22 17:19:49 +00:00
kw ::Unsafe ,
kw ::While ,
kw ::Yield ,
kw ::Static ,
]
. contains ( & name )
2017-01-27 05:51:20 +00:00
}
2020-04-19 11:00:18 +00:00
fn ident_can_begin_type ( name : Symbol , span : Span , is_raw : bool ) -> bool {
2019-06-05 08:56:06 +00:00
let ident_token = Token ::new ( Ident ( name , is_raw ) , span ) ;
2017-03-16 21:47:32 +00:00
2019-12-22 22:42:04 +00:00
! ident_token . is_reserved_ident ( )
| | ident_token . is_path_segment_keyword ( )
| | [ kw ::Underscore , kw ::For , kw ::Impl , kw ::Fn , kw ::Unsafe , kw ::Extern , kw ::Typeof , kw ::Dyn ]
. contains ( & name )
2017-03-16 21:47:32 +00:00
}
2020-06-11 14:49:57 +00:00
#[ derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic) ]
2019-06-04 14:55:23 +00:00
pub enum TokenKind {
2010-09-09 22:59:29 +00:00
/* Expression-operator symbols. */
2014-10-27 08:22:52 +00:00
Eq ,
Lt ,
Le ,
EqEq ,
Ne ,
Ge ,
Gt ,
AndAnd ,
OrOr ,
Not ,
Tilde ,
BinOp ( BinOpToken ) ,
BinOpEq ( BinOpToken ) ,
2010-09-09 22:59:29 +00:00
/* Structural symbols */
2014-10-27 08:22:52 +00:00
At ,
Dot ,
DotDot ,
DotDotDot ,
2017-09-19 05:40:04 +00:00
DotDotEq ,
2014-10-27 08:22:52 +00:00
Comma ,
Semi ,
Colon ,
ModSep ,
RArrow ,
LArrow ,
FatArrow ,
Pound ,
Dollar ,
Question ,
2018-05-13 21:01:56 +00:00
/// Used by proc macros for representing lifetimes, not generated by lexer right now.
SingleQuote ,
2019-02-08 13:53:55 +00:00
/// An opening delimiter (e.g., `{`).
2022-04-26 12:40:14 +00:00
OpenDelim ( Delimiter ) ,
2019-02-08 13:53:55 +00:00
/// A closing delimiter (e.g., `}`).
2022-04-26 12:40:14 +00:00
CloseDelim ( Delimiter ) ,
2012-01-25 23:38:09 +00:00
2010-09-09 22:59:29 +00:00
/* Literals */
2019-05-18 22:04:26 +00:00
Literal ( Lit ) ,
2010-09-09 22:59:29 +00:00
2020-03-09 09:42:33 +00:00
/// Identifier token.
/// Do not forget about `NtIdent` when you want to match on identifiers.
/// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
/// treat regular and interpolated identifiers in the same way.
2020-04-19 11:00:18 +00:00
Ident ( Symbol , /* is_raw */ bool ) ,
2020-03-09 09:42:33 +00:00
/// Lifetime identifier token.
/// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
/// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
/// treat regular and interpolated lifetime identifiers in the same way.
2020-04-19 11:00:18 +00:00
Lifetime ( Symbol ) ,
2012-06-12 17:50:17 +00:00
2022-05-04 06:12:09 +00:00
/// An embedded AST node, as produced by a macro. This only exists for
/// historical reasons. We'd like to get rid of it, for multiple reasons.
/// - It's conceptually very strange. Saying a token can contain an AST
/// node is like saying, in natural language, that a word can contain a
/// sentence.
/// - It requires special handling in a bunch of places in the parser.
/// - It prevents `Token` from implementing `Copy`.
/// It adds complexity and likely slows things down. Please don't add new
/// occurrences of this token kind!
2020-07-01 10:16:49 +00:00
Interpolated ( Lrc < Nonterminal > ) ,
2019-02-14 22:10:02 +00:00
2020-07-21 19:16:19 +00:00
/// A doc comment token.
/// `Symbol` is the doc comment's data excluding its "quotes" (`///`, `/**`, etc)
/// similarly to symbols in string literal tokens.
DocComment ( CommentKind , ast ::AttrStyle , Symbol ) ,
2014-07-05 05:30:39 +00:00
2014-10-27 08:22:52 +00:00
Eof ,
2010-09-09 22:59:29 +00:00
}
2010-08-18 18:35:12 +00:00
2020-06-11 14:49:57 +00:00
#[ derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic) ]
2019-06-04 15:48:40 +00:00
pub struct Token {
pub kind : TokenKind ,
pub span : Span ,
}
2019-06-08 19:38:39 +00:00
impl TokenKind {
pub fn lit ( kind : LitKind , symbol : Symbol , suffix : Option < Symbol > ) -> TokenKind {
Literal ( Lit ::new ( kind , symbol , suffix ) )
}
2022-11-27 11:15:06 +00:00
/// An approximation to proc-macro-style single-character operators used by rustc parser.
/// If the operator token can be broken into two tokens, the first of which is single-character,
/// then this function performs that operation, otherwise it returns `None`.
2020-02-22 13:22:38 +00:00
pub fn break_two_token_op ( & self ) -> Option < ( TokenKind , TokenKind ) > {
Some ( match * self {
Le = > ( Lt , Eq ) ,
EqEq = > ( Eq , Eq ) ,
Ne = > ( Not , Eq ) ,
Ge = > ( Gt , Eq ) ,
AndAnd = > ( BinOp ( And ) , BinOp ( And ) ) ,
OrOr = > ( BinOp ( Or ) , BinOp ( Or ) ) ,
BinOp ( Shl ) = > ( Lt , Lt ) ,
BinOp ( Shr ) = > ( Gt , Gt ) ,
BinOpEq ( Plus ) = > ( BinOp ( Plus ) , Eq ) ,
BinOpEq ( Minus ) = > ( BinOp ( Minus ) , Eq ) ,
BinOpEq ( Star ) = > ( BinOp ( Star ) , Eq ) ,
BinOpEq ( Slash ) = > ( BinOp ( Slash ) , Eq ) ,
BinOpEq ( Percent ) = > ( BinOp ( Percent ) , Eq ) ,
BinOpEq ( Caret ) = > ( BinOp ( Caret ) , Eq ) ,
BinOpEq ( And ) = > ( BinOp ( And ) , Eq ) ,
BinOpEq ( Or ) = > ( BinOp ( Or ) , Eq ) ,
BinOpEq ( Shl ) = > ( Lt , Le ) ,
BinOpEq ( Shr ) = > ( Gt , Ge ) ,
DotDot = > ( Dot , Dot ) ,
DotDotDot = > ( Dot , DotDot ) ,
ModSep = > ( Colon , Colon ) ,
RArrow = > ( BinOp ( Minus ) , Gt ) ,
LArrow = > ( Lt , BinOp ( Minus ) ) ,
FatArrow = > ( Eq , Gt ) ,
_ = > return None ,
} )
}
2019-06-08 19:38:39 +00:00
/// Returns tokens that are likely to be typed accidentally instead of the current token.
/// Enables better error recovery when the wrong token is found.
2019-10-15 20:48:13 +00:00
pub fn similar_tokens ( & self ) -> Option < Vec < TokenKind > > {
2019-06-08 19:38:39 +00:00
match * self {
Comma = > Some ( vec! [ Dot , Lt , Semi ] ) ,
Semi = > Some ( vec! [ Colon , Comma ] ) ,
2021-10-04 20:13:00 +00:00
FatArrow = > Some ( vec! [ Eq , RArrow ] ) ,
2019-12-22 22:42:04 +00:00
_ = > None ,
2019-06-08 19:38:39 +00:00
}
}
2020-10-03 18:30:32 +00:00
pub fn should_end_const_arg ( & self ) -> bool {
2020-12-24 01:55:21 +00:00
matches! ( self , Gt | Ge | BinOp ( Shr ) | BinOpEq ( Shr ) )
2020-10-03 18:30:32 +00:00
}
2019-06-08 19:38:39 +00:00
}
2019-06-08 16:45:12 +00:00
impl Token {
2019-10-16 08:59:30 +00:00
pub fn new ( kind : TokenKind , span : Span ) -> Self {
2019-06-08 19:38:39 +00:00
Token { kind , span }
}
/// Some token that will be thrown away later.
2019-10-15 20:48:13 +00:00
pub fn dummy ( ) -> Self {
2020-09-01 09:24:52 +00:00
Token ::new ( TokenKind ::Question , DUMMY_SP )
2019-06-08 19:38:39 +00:00
}
2020-04-19 11:00:18 +00:00
/// Recovers a `Token` from an `Ident`. This creates a raw identifier if necessary.
pub fn from_ast_ident ( ident : Ident ) -> Self {
2019-06-08 16:45:12 +00:00
Token ::new ( Ident ( ident . name , ident . is_raw_guess ( ) ) , ident . span )
2018-03-10 05:56:40 +00:00
}
2020-03-09 09:42:33 +00:00
/// For interpolated tokens, returns a span of the fragment to which the interpolated
/// token refers. For all other tokens this is just a regular span.
2020-03-04 21:34:57 +00:00
/// It is particularly important to use this for identifiers and lifetimes
2020-03-09 09:42:33 +00:00
/// for which spans affect name resolution and edition checks.
/// Note that keywords are also identifiers, so they should use this
/// if they keep spans or perform edition checks.
2020-03-04 21:34:57 +00:00
pub fn uninterpolated_span ( & self ) -> Span {
match & self . kind {
2020-07-01 10:16:49 +00:00
Interpolated ( nt ) = > nt . span ( ) ,
2020-03-04 21:34:57 +00:00
_ = > self . span ,
}
}
2022-12-16 13:11:08 +00:00
pub fn is_range_separator ( & self ) -> bool {
2022-12-14 13:40:03 +00:00
[ DotDot , DotDotDot , DotDotEq ] . contains ( & self . kind )
}
2019-10-15 20:48:13 +00:00
pub fn is_op ( & self ) -> bool {
2022-09-28 01:29:47 +00:00
match self . kind {
Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp ( _ )
| BinOpEq ( _ ) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon
| ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote = > true ,
OpenDelim ( .. ) | CloseDelim ( .. ) | Literal ( .. ) | DocComment ( .. ) | Ident ( .. )
| Lifetime ( .. ) | Interpolated ( .. ) | Eof = > false ,
}
2019-06-08 19:38:39 +00:00
}
2019-10-15 20:48:13 +00:00
pub fn is_like_plus ( & self ) -> bool {
2020-12-24 01:55:21 +00:00
matches! ( self . kind , BinOp ( Plus ) | BinOpEq ( Plus ) )
2018-05-25 21:09:32 +00:00
}
2015-04-18 01:18:46 +00:00
2014-10-27 12:33:30 +00:00
/// Returns `true` if the token can appear at the start of an expression.
2019-10-16 08:59:30 +00:00
pub fn can_begin_expr ( & self ) -> bool {
2020-03-07 12:58:27 +00:00
match self . uninterpolate ( ) . kind {
2019-06-05 08:56:06 +00:00
Ident ( name , is_raw ) = >
ident_can_begin_expr ( name , self . span , is_raw ) , // value name or keyword
2017-09-19 05:40:04 +00:00
OpenDelim ( .. ) | // tuple, array or block
Literal ( .. ) | // literal
Not | // operator not
BinOp ( Minus ) | // unary minus
BinOp ( Star ) | // dereference
BinOp ( Or ) | OrOr | // closure
BinOp ( And ) | // reference
AndAnd | // double reference
2017-11-04 23:46:41 +00:00
// DotDotDot is no longer supported, but we need some way to display the error
2017-09-19 05:40:04 +00:00
DotDot | DotDotDot | DotDotEq | // range notation
Lt | BinOp ( Shl ) | // associated path
ModSep | // global path
2018-04-22 11:34:42 +00:00
Lifetime ( .. ) | // labeled loop
2017-09-19 05:40:04 +00:00
Pound = > true , // expression attributes
2020-12-24 01:55:21 +00:00
Interpolated ( ref nt ) = > matches! ( * * nt , NtLiteral ( .. ) |
2018-04-09 23:08:47 +00:00
NtExpr ( .. ) |
NtBlock ( .. ) |
2020-12-24 01:55:21 +00:00
NtPath ( .. ) ) ,
2016-11-02 03:03:55 +00:00
_ = > false ,
2014-10-27 12:33:30 +00:00
}
}
2022-09-03 05:39:46 +00:00
/// Returns `true` if the token can appear at the start of an pattern.
///
/// Shamelessly borrowed from `can_begin_expr`, only used for diagnostics right now.
pub fn can_begin_pattern ( & self ) -> bool {
match self . uninterpolate ( ) . kind {
Ident ( name , is_raw ) = >
ident_can_begin_expr ( name , self . span , is_raw ) , // value name or keyword
| OpenDelim ( Delimiter ::Bracket | Delimiter ::Parenthesis ) // tuple or array
| Literal ( .. ) // literal
| BinOp ( Minus ) // unary minus
| BinOp ( And ) // reference
| AndAnd // double reference
// DotDotDot is no longer supported
| DotDot | DotDotDot | DotDotEq // ranges
| Lt | BinOp ( Shl ) // associated path
| ModSep = > true , // global path
Interpolated ( ref nt ) = > matches! ( * * nt , NtLiteral ( .. ) |
NtPat ( .. ) |
NtBlock ( .. ) |
NtPath ( .. ) ) ,
_ = > false ,
}
}
2017-01-17 18:18:29 +00:00
/// Returns `true` if the token can appear at the start of a type.
2019-10-16 08:59:30 +00:00
pub fn can_begin_type ( & self ) -> bool {
2020-03-07 12:58:27 +00:00
match self . uninterpolate ( ) . kind {
2019-06-05 08:56:06 +00:00
Ident ( name , is_raw ) = >
ident_can_begin_type ( name , self . span , is_raw ) , // type name or keyword
2022-04-26 12:40:14 +00:00
OpenDelim ( Delimiter ::Parenthesis ) | // tuple
OpenDelim ( Delimiter ::Bracket ) | // array
2017-05-12 18:05:39 +00:00
Not | // never
BinOp ( Star ) | // raw pointer
BinOp ( And ) | // reference
AndAnd | // double reference
Question | // maybe bound in trait object
Lifetime ( .. ) | // lifetime bound in trait object
Lt | BinOp ( Shl ) | // associated path
2017-01-17 18:18:29 +00:00
ModSep = > true , // global path
2020-12-24 01:55:21 +00:00
Interpolated ( ref nt ) = > matches! ( * * nt , NtTy ( .. ) | NtPath ( .. ) ) ,
2017-01-17 18:18:29 +00:00
_ = > false ,
}
}
2019-02-05 15:49:38 +00:00
/// Returns `true` if the token can appear at the start of a const param.
2019-10-15 20:48:13 +00:00
pub fn can_begin_const_arg ( & self ) -> bool {
2019-06-08 16:45:12 +00:00
match self . kind {
2022-04-26 12:40:14 +00:00
OpenDelim ( Delimiter ::Brace ) = > true ,
2020-12-24 01:55:21 +00:00
Interpolated ( ref nt ) = > matches! ( * * nt , NtExpr ( .. ) | NtBlock ( .. ) | NtLiteral ( .. ) ) ,
2020-03-16 22:36:14 +00:00
_ = > self . can_begin_literal_maybe_minus ( ) ,
2019-02-05 15:49:38 +00:00
}
}
2017-10-10 14:33:19 +00:00
/// Returns `true` if the token can appear at the start of a generic bound.
2019-10-15 20:48:13 +00:00
pub fn can_begin_bound ( & self ) -> bool {
2019-12-22 22:42:04 +00:00
self . is_path_start ( )
| | self . is_lifetime ( )
| | self . is_keyword ( kw ::For )
| | self = = & Question
2022-04-26 12:40:14 +00:00
| | self = = & OpenDelim ( Delimiter ::Parenthesis )
2017-10-10 14:33:19 +00:00
}
2019-05-18 22:04:26 +00:00
2022-08-15 07:10:31 +00:00
/// Returns `true` if the token can appear at the start of an item.
pub fn can_begin_item ( & self ) -> bool {
match self . kind {
Ident ( name , _ ) = > [
kw ::Fn ,
kw ::Use ,
kw ::Struct ,
kw ::Enum ,
kw ::Pub ,
kw ::Trait ,
kw ::Extern ,
kw ::Impl ,
kw ::Unsafe ,
2022-09-11 00:29:38 +00:00
kw ::Const ,
2022-08-15 07:10:31 +00:00
kw ::Static ,
kw ::Union ,
kw ::Macro ,
kw ::Mod ,
kw ::Type ,
]
. contains ( & name ) ,
_ = > false ,
}
}
2020-12-17 19:55:49 +00:00
/// Returns `true` if the token is any literal.
2019-10-16 08:59:30 +00:00
pub fn is_lit ( & self ) -> bool {
2020-12-24 01:55:21 +00:00
matches! ( self . kind , Literal ( .. ) )
2014-10-27 12:33:30 +00:00
}
2019-02-07 13:59:59 +00:00
/// Returns `true` if the token is any literal, a minus (which can prefix a literal,
2018-04-09 23:08:47 +00:00
/// for example a '-42', or one of the boolean idents).
2020-01-30 12:02:06 +00:00
///
2020-03-16 22:36:14 +00:00
/// In other words, would this token be a valid start of `parse_literal_maybe_minus`?
///
/// Keep this in sync with and `Lit::from_token`, excluding unary negation.
pub fn can_begin_literal_maybe_minus ( & self ) -> bool {
2020-03-07 12:58:27 +00:00
match self . uninterpolate ( ) . kind {
2019-08-27 08:21:41 +00:00
Literal ( .. ) | BinOp ( Minus ) = > true ,
Ident ( name , false ) if name . is_bool_lit ( ) = > true ,
2020-07-01 10:16:49 +00:00
Interpolated ( ref nt ) = > match & * * nt {
2020-03-16 22:36:14 +00:00
NtLiteral ( _ ) = > true ,
NtExpr ( e ) = > match & e . kind {
ast ::ExprKind ::Lit ( _ ) = > true ,
ast ::ExprKind ::Unary ( ast ::UnOp ::Neg , e ) = > {
matches! ( & e . kind , ast ::ExprKind ::Lit ( _ ) )
}
_ = > false ,
} ,
2019-12-22 22:42:04 +00:00
_ = > false ,
2018-08-05 15:37:48 +00:00
} ,
2019-12-22 22:42:04 +00:00
_ = > false ,
2018-04-09 23:08:47 +00:00
}
}
2019-06-05 08:00:22 +00:00
2022-11-27 11:15:06 +00:00
/// A convenience function for matching on identifiers during parsing.
/// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token
/// into the regular identifier or lifetime token it refers to,
/// otherwise returns the original token.
2020-03-07 11:37:38 +00:00
pub fn uninterpolate ( & self ) -> Cow < '_ , Token > {
match & self . kind {
2020-07-01 10:16:49 +00:00
Interpolated ( nt ) = > match * * nt {
2020-03-07 11:37:38 +00:00
NtIdent ( ident , is_raw ) = > {
Cow ::Owned ( Token ::new ( Ident ( ident . name , is_raw ) , ident . span ) )
}
NtLifetime ( ident ) = > Cow ::Owned ( Token ::new ( Lifetime ( ident . name ) , ident . span ) ) ,
_ = > Cow ::Borrowed ( self ) ,
} ,
_ = > Cow ::Borrowed ( self ) ,
}
}
2019-06-05 08:56:06 +00:00
/// Returns an identifier if this token is an identifier.
2022-05-03 02:40:35 +00:00
#[ inline ]
2020-04-19 11:00:18 +00:00
pub fn ident ( & self ) -> Option < ( Ident , /* is_raw */ bool ) > {
2022-05-03 02:40:35 +00:00
// We avoid using `Token::uninterpolate` here because it's slow.
match & self . kind {
& Ident ( name , is_raw ) = > Some ( ( Ident ::new ( name , self . span ) , is_raw ) ) ,
Interpolated ( nt ) = > match * * nt {
NtIdent ( ident , is_raw ) = > Some ( ( ident , is_raw ) ) ,
_ = > None ,
} ,
2019-06-05 08:56:06 +00:00
_ = > None ,
}
}
2019-06-05 08:00:22 +00:00
/// Returns a lifetime identifier if this token is a lifetime.
2022-05-03 02:40:35 +00:00
#[ inline ]
2020-04-19 11:00:18 +00:00
pub fn lifetime ( & self ) -> Option < Ident > {
2022-05-03 02:40:35 +00:00
// We avoid using `Token::uninterpolate` here because it's slow.
match & self . kind {
& Lifetime ( name ) = > Some ( Ident ::new ( name , self . span ) ) ,
Interpolated ( nt ) = > match * * nt {
NtLifetime ( ident ) = > Some ( ident ) ,
_ = > None ,
} ,
2019-06-05 08:00:22 +00:00
_ = > None ,
}
}
2018-04-09 23:08:47 +00:00
2017-03-29 07:17:18 +00:00
/// Returns `true` if the token is an identifier.
pub fn is_ident ( & self ) -> bool {
2019-06-08 16:45:12 +00:00
self . ident ( ) . is_some ( )
2017-03-29 07:17:18 +00:00
}
2019-08-27 08:14:07 +00:00
2018-03-24 16:49:50 +00:00
/// Returns `true` if the token is a lifetime.
2019-10-15 20:48:13 +00:00
pub fn is_lifetime ( & self ) -> bool {
2019-06-08 16:45:12 +00:00
self . lifetime ( ) . is_some ( )
2018-03-24 16:49:50 +00:00
}
2017-03-29 07:17:18 +00:00
2021-08-22 12:46:15 +00:00
/// Returns `true` if the token is an identifier whose name is the given
2018-03-22 05:38:24 +00:00
/// string slice.
2019-10-15 20:48:13 +00:00
pub fn is_ident_named ( & self , name : Symbol ) -> bool {
2023-05-24 14:19:22 +00:00
self . ident ( ) . is_some_and ( | ( ident , _ ) | ident . name = = name )
2018-03-22 05:38:24 +00:00
}
2014-10-27 12:33:30 +00:00
/// Returns `true` if the token is an interpolated path.
2018-05-31 22:53:30 +00:00
fn is_path ( & self ) -> bool {
2022-11-16 19:26:38 +00:00
if let Interpolated ( nt ) = & self . kind & & let NtPath ( .. ) = * * nt {
2022-02-26 16:45:36 +00:00
return true ;
2014-10-27 12:33:30 +00:00
}
2022-11-16 19:26:38 +00:00
2016-11-02 03:03:55 +00:00
false
2014-10-27 12:33:30 +00:00
}
2019-07-30 02:22:09 +00:00
/// Would `maybe_whole_expr` in `parser.rs` return `Ok(..)`?
/// That is, is this a pre-parsed expression dropped into the token stream
2019-07-31 19:25:11 +00:00
/// (which happens while parsing the result of macro expansion)?
2019-10-15 20:48:13 +00:00
pub fn is_whole_expr ( & self ) -> bool {
2022-11-16 19:26:38 +00:00
if let Interpolated ( nt ) = & self . kind
2022-05-03 05:12:43 +00:00
& & let NtExpr ( _ ) | NtLiteral ( _ ) | NtPath ( _ ) | NtBlock ( _ ) = * * nt
2022-02-26 16:45:36 +00:00
{
return true ;
2019-07-30 02:22:09 +00:00
}
false
}
2022-11-27 11:15:06 +00:00
/// Is the token an interpolated block (`$b:block`)?
2020-03-05 04:49:30 +00:00
pub fn is_whole_block ( & self ) -> bool {
2022-11-16 19:26:38 +00:00
if let Interpolated ( nt ) = & self . kind & & let NtBlock ( .. ) = * * nt {
2022-02-26 16:45:36 +00:00
return true ;
2020-03-05 04:49:30 +00:00
}
2022-11-16 19:26:38 +00:00
2020-03-05 04:49:30 +00:00
false
}
2014-10-27 12:33:30 +00:00
/// Returns `true` if the token is either the `mut` or `const` keyword.
2019-10-15 20:48:13 +00:00
pub fn is_mutability ( & self ) -> bool {
2019-12-22 22:42:04 +00:00
self . is_keyword ( kw ::Mut ) | | self . is_keyword ( kw ::Const )
2014-10-27 12:33:30 +00:00
}
2019-10-15 20:48:13 +00:00
pub fn is_qpath_start ( & self ) -> bool {
2016-10-19 20:33:41 +00:00
self = = & Lt | | self = = & BinOp ( Shl )
}
2019-10-15 20:48:13 +00:00
pub fn is_path_start ( & self ) -> bool {
2019-12-22 22:42:04 +00:00
self = = & ModSep
| | self . is_qpath_start ( )
| | self . is_path ( )
| | self . is_path_segment_keyword ( )
| | self . is_ident ( ) & & ! self . is_reserved_ident ( )
2016-04-20 23:03:29 +00:00
}
2014-10-27 12:33:30 +00:00
/// Returns `true` if the token is a given keyword, `kw`.
2019-05-11 14:41:37 +00:00
pub fn is_keyword ( & self , kw : Symbol ) -> bool {
2019-08-27 08:14:07 +00:00
self . is_non_raw_ident_where ( | id | id . name = = kw )
2014-10-27 12:33:30 +00:00
}
2022-09-15 16:27:23 +00:00
/// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this token is an identifier equal to `kw` ignoring the case.
pub fn is_keyword_case ( & self , kw : Symbol , case : Case ) -> bool {
2022-09-13 18:48:29 +00:00
self . is_keyword ( kw )
2022-09-15 16:27:23 +00:00
| | ( case = = Case ::Insensitive
2022-09-13 18:48:29 +00:00
& & self . is_non_raw_ident_where ( | id | {
id . name . as_str ( ) . to_lowercase ( ) = = kw . as_str ( ) . to_lowercase ( )
} ) )
}
2019-10-15 20:48:13 +00:00
pub fn is_path_segment_keyword ( & self ) -> bool {
2020-04-19 11:00:18 +00:00
self . is_non_raw_ident_where ( Ident ::is_path_segment_keyword )
2014-09-16 01:27:28 +00:00
}
2022-11-27 11:15:06 +00:00
/// Returns true for reserved identifiers used internally for elided lifetimes,
/// unnamed method parameters, crate root module, error recovery etc.
2019-10-15 20:48:13 +00:00
pub fn is_special_ident ( & self ) -> bool {
2020-04-19 11:00:18 +00:00
self . is_non_raw_ident_where ( Ident ::is_special )
2014-10-27 12:33:30 +00:00
}
2017-06-29 10:16:35 +00:00
/// Returns `true` if the token is a keyword used in the language.
2019-10-15 20:48:13 +00:00
pub fn is_used_keyword ( & self ) -> bool {
2020-04-19 11:00:18 +00:00
self . is_non_raw_ident_where ( Ident ::is_used_keyword )
2014-10-27 12:33:30 +00:00
}
2016-04-16 15:05:06 +00:00
/// Returns `true` if the token is a keyword reserved for possible future use.
2019-10-15 20:48:13 +00:00
pub fn is_unused_keyword ( & self ) -> bool {
2020-04-19 11:00:18 +00:00
self . is_non_raw_ident_where ( Ident ::is_unused_keyword )
2014-10-27 12:33:30 +00:00
}
2017-03-17 23:41:09 +00:00
2018-03-24 16:49:50 +00:00
/// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved_ident ( & self ) -> bool {
2020-04-19 11:00:18 +00:00
self . is_non_raw_ident_where ( Ident ::is_reserved )
2019-08-27 08:14:07 +00:00
}
2019-08-27 08:21:41 +00:00
/// Returns `true` if the token is the identifier `true` or `false`.
2019-10-15 20:48:13 +00:00
pub fn is_bool_lit ( & self ) -> bool {
2019-08-27 08:21:41 +00:00
self . is_non_raw_ident_where ( | id | id . name . is_bool_lit ( ) )
}
2021-09-05 02:35:59 +00:00
pub fn is_numeric_lit ( & self ) -> bool {
2021-09-05 02:38:39 +00:00
matches! (
self . kind ,
Literal ( Lit { kind : LitKind ::Integer , .. } ) | Literal ( Lit { kind : LitKind ::Float , .. } )
)
2021-09-05 02:35:59 +00:00
}
2019-08-27 08:14:07 +00:00
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
2020-04-19 11:00:18 +00:00
pub fn is_non_raw_ident_where ( & self , pred : impl FnOnce ( Ident ) -> bool ) -> bool {
2018-03-24 16:49:50 +00:00
match self . ident ( ) {
2019-08-27 08:14:07 +00:00
Some ( ( id , false ) ) = > pred ( id ) ,
2018-03-24 16:49:50 +00:00
_ = > false ,
}
}
2019-10-15 20:48:13 +00:00
pub fn glue ( & self , joint : & Token ) -> Option < Token > {
2019-06-08 16:45:12 +00:00
let kind = match self . kind {
Eq = > match joint . kind {
2017-03-17 23:41:09 +00:00
Eq = > EqEq ,
Gt = > FatArrow ,
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
Lt = > match joint . kind {
2017-03-17 23:41:09 +00:00
Eq = > Le ,
Lt = > BinOp ( Shl ) ,
Le = > BinOpEq ( Shl ) ,
BinOp ( Minus ) = > LArrow ,
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
Gt = > match joint . kind {
2017-03-17 23:41:09 +00:00
Eq = > Ge ,
Gt = > BinOp ( Shr ) ,
Ge = > BinOpEq ( Shr ) ,
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
Not = > match joint . kind {
2017-03-17 23:41:09 +00:00
Eq = > Ne ,
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
BinOp ( op ) = > match joint . kind {
2017-03-17 23:41:09 +00:00
Eq = > BinOpEq ( op ) ,
BinOp ( And ) if op = = And = > AndAnd ,
BinOp ( Or ) if op = = Or = > OrOr ,
Gt if op = = Minus = > RArrow ,
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
Dot = > match joint . kind {
2017-03-17 23:41:09 +00:00
Dot = > DotDot ,
DotDot = > DotDotDot ,
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
DotDot = > match joint . kind {
2017-03-17 23:41:09 +00:00
Dot = > DotDotDot ,
2017-09-19 05:40:04 +00:00
Eq = > DotDotEq ,
2017-03-17 23:41:09 +00:00
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
Colon = > match joint . kind {
2017-03-17 23:41:09 +00:00
Colon = > ModSep ,
_ = > return None ,
} ,
2019-06-08 16:45:12 +00:00
SingleQuote = > match joint . kind {
2022-12-19 09:31:55 +00:00
Ident ( name , false ) = > Lifetime ( Symbol ::intern ( & format! ( " ' {name} " ) ) ) ,
2018-05-13 21:01:56 +00:00
_ = > return None ,
} ,
2017-03-17 23:41:09 +00:00
2019-12-22 22:42:04 +00:00
Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq ( .. ) | At | DotDotDot
| DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar
| Question | OpenDelim ( .. ) | CloseDelim ( .. ) | Literal ( .. ) | Ident ( .. )
2020-09-01 09:24:52 +00:00
| Lifetime ( .. ) | Interpolated ( .. ) | DocComment ( .. ) | Eof = > return None ,
2019-06-08 16:45:12 +00:00
} ;
Some ( Token ::new ( kind , self . span . to ( joint . span ) ) )
2017-03-17 23:41:09 +00:00
}
2019-06-05 06:39:34 +00:00
}
2019-06-04 15:48:40 +00:00
impl PartialEq < TokenKind > for Token {
2022-09-28 03:55:00 +00:00
#[ inline ]
2019-06-04 15:48:40 +00:00
fn eq ( & self , rhs : & TokenKind ) -> bool {
self . kind = = * rhs
}
}
2020-06-11 14:49:57 +00:00
#[ derive(Clone, Encodable, Decodable) ]
2012-07-04 21:53:12 +00:00
/// For interpolation during macro expansion.
2014-01-09 13:05:33 +00:00
pub enum Nonterminal {
2014-10-29 21:44:41 +00:00
NtItem ( P < ast ::Item > ) ,
2014-01-09 13:05:33 +00:00
NtBlock ( P < ast ::Block > ) ,
2022-04-06 02:08:39 +00:00
NtStmt ( P < ast ::Stmt > ) ,
2014-10-29 21:44:41 +00:00
NtPat ( P < ast ::Pat > ) ,
NtExpr ( P < ast ::Expr > ) ,
NtTy ( P < ast ::Ty > ) ,
2020-04-19 11:00:18 +00:00
NtIdent ( Ident , /* is_raw */ bool ) ,
NtLifetime ( Ident ) ,
2018-04-09 23:08:47 +00:00
NtLiteral ( P < ast ::Expr > ) ,
2014-06-09 20:19:38 +00:00
/// Stuff inside brackets for attributes
2019-12-13 00:25:08 +00:00
NtMeta ( P < ast ::AttrItem > ) ,
2022-04-06 02:08:39 +00:00
NtPath ( P < ast ::Path > ) ,
NtVis ( P < ast ::Visibility > ) ,
2012-06-12 17:50:17 +00:00
}
2020-06-11 14:49:57 +00:00
#[ derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable) ]
2020-07-27 12:04:54 +00:00
pub enum NonterminalKind {
Item ,
Block ,
Stmt ,
2021-04-15 01:34:51 +00:00
PatParam {
/// Keep track of whether the user used `:pat_param` or `:pat` and we inferred it from the
2020-12-28 22:57:13 +00:00
/// edition of the span. This is used for diagnostics.
inferred : bool ,
} ,
2021-04-28 02:15:59 +00:00
PatWithOr ,
2020-07-27 12:04:54 +00:00
Expr ,
Ty ,
Ident ,
Lifetime ,
Literal ,
Meta ,
Path ,
Vis ,
TT ,
}
impl NonterminalKind {
2020-12-28 22:57:13 +00:00
/// The `edition` closure is used to get the edition for the given symbol. Doing
/// `span.edition()` is expensive, so we do it lazily.
pub fn from_symbol (
symbol : Symbol ,
edition : impl FnOnce ( ) -> Edition ,
) -> Option < NonterminalKind > {
2020-07-27 12:04:54 +00:00
Some ( match symbol {
sym ::item = > NonterminalKind ::Item ,
sym ::block = > NonterminalKind ::Block ,
sym ::stmt = > NonterminalKind ::Stmt ,
2020-12-28 22:57:13 +00:00
sym ::pat = > match edition ( ) {
Edition ::Edition2015 | Edition ::Edition2018 = > {
2021-04-15 01:34:51 +00:00
NonterminalKind ::PatParam { inferred : true }
2020-12-28 22:57:13 +00:00
}
2022-02-28 23:13:24 +00:00
Edition ::Edition2021 | Edition ::Edition2024 = > NonterminalKind ::PatWithOr ,
2020-12-28 22:57:13 +00:00
} ,
2021-04-15 01:34:51 +00:00
sym ::pat_param = > NonterminalKind ::PatParam { inferred : false } ,
2020-07-27 12:04:54 +00:00
sym ::expr = > NonterminalKind ::Expr ,
sym ::ty = > NonterminalKind ::Ty ,
sym ::ident = > NonterminalKind ::Ident ,
sym ::lifetime = > NonterminalKind ::Lifetime ,
sym ::literal = > NonterminalKind ::Literal ,
sym ::meta = > NonterminalKind ::Meta ,
sym ::path = > NonterminalKind ::Path ,
sym ::vis = > NonterminalKind ::Vis ,
sym ::tt = > NonterminalKind ::TT ,
_ = > return None ,
} )
}
2020-08-01 15:45:17 +00:00
fn symbol ( self ) -> Symbol {
match self {
NonterminalKind ::Item = > sym ::item ,
NonterminalKind ::Block = > sym ::block ,
NonterminalKind ::Stmt = > sym ::stmt ,
2021-04-15 01:34:51 +00:00
NonterminalKind ::PatParam { inferred : false } = > sym ::pat_param ,
2021-04-28 02:15:59 +00:00
NonterminalKind ::PatParam { inferred : true } | NonterminalKind ::PatWithOr = > sym ::pat ,
2020-08-01 15:45:17 +00:00
NonterminalKind ::Expr = > sym ::expr ,
NonterminalKind ::Ty = > sym ::ty ,
NonterminalKind ::Ident = > sym ::ident ,
NonterminalKind ::Lifetime = > sym ::lifetime ,
NonterminalKind ::Literal = > sym ::literal ,
NonterminalKind ::Meta = > sym ::meta ,
NonterminalKind ::Path = > sym ::path ,
NonterminalKind ::Vis = > sym ::vis ,
NonterminalKind ::TT = > sym ::tt ,
}
}
}
impl fmt ::Display for NonterminalKind {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
write! ( f , " {} " , self . symbol ( ) )
}
2020-07-27 12:04:54 +00:00
}
2020-03-04 21:34:57 +00:00
impl Nonterminal {
2021-01-07 13:43:22 +00:00
pub fn span ( & self ) -> Span {
2020-03-04 21:34:57 +00:00
match self {
NtItem ( item ) = > item . span ,
NtBlock ( block ) = > block . span ,
NtStmt ( stmt ) = > stmt . span ,
NtPat ( pat ) = > pat . span ,
NtExpr ( expr ) | NtLiteral ( expr ) = > expr . span ,
NtTy ( ty ) = > ty . span ,
NtIdent ( ident , _ ) | NtLifetime ( ident ) = > ident . span ,
NtMeta ( attr_item ) = > attr_item . span ( ) ,
NtPath ( path ) = > path . span ,
NtVis ( vis ) = > vis . span ,
}
}
}
2018-03-24 13:00:44 +00:00
impl PartialEq for Nonterminal {
fn eq ( & self , rhs : & Self ) -> bool {
match ( self , rhs ) {
2019-12-22 22:42:04 +00:00
( NtIdent ( ident_lhs , is_raw_lhs ) , NtIdent ( ident_rhs , is_raw_rhs ) ) = > {
ident_lhs = = ident_rhs & & is_raw_lhs = = is_raw_rhs
}
2018-03-24 13:00:44 +00:00
( NtLifetime ( ident_lhs ) , NtLifetime ( ident_rhs ) ) = > ident_lhs = = ident_rhs ,
// FIXME: Assume that all "complex" nonterminal are not equal, we can't compare them
// correctly based on data from AST. This will prevent them from matching each other
// in macros. The comparison will become possible only when each nonterminal has an
// attached token stream from which it was parsed.
_ = > false ,
}
}
}
2015-01-20 23:45:07 +00:00
impl fmt ::Debug for Nonterminal {
2019-02-06 17:33:01 +00:00
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
2014-02-28 09:23:06 +00:00
match * self {
NtItem ( .. ) = > f . pad ( " NtItem(..) " ) ,
NtBlock ( .. ) = > f . pad ( " NtBlock(..) " ) ,
NtStmt ( .. ) = > f . pad ( " NtStmt(..) " ) ,
NtPat ( .. ) = > f . pad ( " NtPat(..) " ) ,
NtExpr ( .. ) = > f . pad ( " NtExpr(..) " ) ,
NtTy ( .. ) = > f . pad ( " NtTy(..) " ) ,
NtIdent ( .. ) = > f . pad ( " NtIdent(..) " ) ,
2018-04-09 23:08:47 +00:00
NtLiteral ( .. ) = > f . pad ( " NtLiteral(..) " ) ,
2014-03-26 23:14:07 +00:00
NtMeta ( .. ) = > f . pad ( " NtMeta(..) " ) ,
2014-02-28 09:23:06 +00:00
NtPath ( .. ) = > f . pad ( " NtPath(..) " ) ,
2016-04-24 16:04:01 +00:00
NtVis ( .. ) = > f . pad ( " NtVis(..) " ) ,
2017-05-10 00:30:47 +00:00
NtLifetime ( .. ) = > f . pad ( " NtLifetime(..) " ) ,
2014-02-28 09:23:06 +00:00
}
}
}
2019-11-23 13:47:31 +00:00
impl < CTX > HashStable < CTX > for Nonterminal
2019-12-22 22:42:04 +00:00
where
CTX : crate ::HashStableContext ,
2019-11-23 13:47:31 +00:00
{
fn hash_stable ( & self , _hcx : & mut CTX , _hasher : & mut StableHasher ) {
panic! ( " interpolated tokens should not be present in the HIR " )
}
}
2022-09-29 23:23:55 +00:00
// Some types are used a lot. Make sure they don't unintentionally get bigger.
#[ cfg(all(target_arch = " x86_64 " , target_pointer_width = " 64 " )) ]
mod size_asserts {
use super ::* ;
use rustc_data_structures ::static_assert_size ;
2022-10-05 19:46:21 +00:00
// tidy-alphabetical-start
2022-09-29 23:23:55 +00:00
static_assert_size! ( Lit , 12 ) ;
static_assert_size! ( LitKind , 2 ) ;
static_assert_size! ( Nonterminal , 16 ) ;
static_assert_size! ( Token , 24 ) ;
static_assert_size! ( TokenKind , 16 ) ;
2022-10-05 19:46:21 +00:00
// tidy-alphabetical-end
2022-09-29 23:23:55 +00:00
}