1use rustc_ast::token::TokenKind;
2use rustc_span::symbol::{Symbol, kw, sym};
3
4#[derive(Debug, Clone, Copy, PartialEq)]
19pub enum TokenType {
20 Eq,
22 Lt,
23 Le,
24 EqEq,
25 Gt,
26 AndAnd,
27 OrOr,
28 Bang,
29 Tilde,
30
31 Plus,
33 Minus,
34 Star,
35 And,
36 Or,
37
38 At,
40 Dot,
41 DotDot,
42 DotDotDot,
43 DotDotEq,
44 Comma,
45 Semi,
46 Colon,
47 PathSep,
48 RArrow,
49 FatArrow,
50 Pound,
51 Question,
52 OpenParen,
53 CloseParen,
54 OpenBrace,
55 CloseBrace,
56 OpenBracket,
57 CloseBracket,
58 Eof,
59
60 Operator,
63 Ident,
65 Lifetime,
67 Path,
69 Type,
71 Const,
73
74 KwAs,
77 KwAsync,
78 KwAuto,
79 KwAwait,
80 KwBecome,
81 KwBox,
82 KwBreak,
83 KwCatch,
84 KwConst,
85 KwContinue,
86 KwContractEnsures,
87 KwContractRequires,
88 KwCrate,
89 KwDefault,
90 KwDyn,
91 KwElse,
92 KwEnum,
93 KwExtern,
94 KwFn,
95 KwFor,
96 KwGen,
97 KwIf,
98 KwImpl,
99 KwIn,
100 KwLet,
101 KwLoop,
102 KwMacro,
103 KwMacroRules,
104 KwMatch,
105 KwMod,
106 KwMove,
107 KwMut,
108 KwPub,
109 KwRaw,
110 KwRef,
111 KwReturn,
112 KwReuse,
113 KwSafe,
114 KwSelfUpper,
115 KwStatic,
116 KwStruct,
117 KwSuper,
118 KwTrait,
119 KwTry,
120 KwType,
121 KwUnderscore,
122 KwUnsafe,
123 KwUse,
124 KwWhere,
125 KwWhile,
126 KwYield,
127 SymAttSyntax,
132 SymClobberAbi,
133 SymInlateout,
134 SymInout,
135 SymIs,
136 SymLabel,
137 SymLateout,
138 SymMayUnwind,
139 SymNomem,
140 SymNoreturn,
141 SymNostack,
142 SymOptions,
143 SymOut,
144 SymPreservesFlags,
145 SymPure,
146 SymReadonly,
147 SymSym,
148 }
150
151macro_rules! from_u32_match {
153 ($val:ident; $($tok:ident,)+) => {
154 match $val {
158 $(
159 t if t == TokenType::$tok as u32 => TokenType::$tok,
160 )+
161 _ => panic!("unhandled value: {}", $val),
162 }
163 };
164}
165
166impl TokenType {
167 fn from_u32(val: u32) -> TokenType {
168 let token_type = from_u32_match! { val;
169 Eq,
170 Lt,
171 Le,
172 EqEq,
173 Gt,
174 AndAnd,
175 OrOr,
176 Bang,
177 Tilde,
178
179 Plus,
180 Minus,
181 Star,
182 And,
183 Or,
184
185 At,
186 Dot,
187 DotDot,
188 DotDotDot,
189 DotDotEq,
190 Comma,
191 Semi,
192 Colon,
193 PathSep,
194 RArrow,
195 FatArrow,
196 Pound,
197 Question,
198 OpenParen,
199 CloseParen,
200 OpenBrace,
201 CloseBrace,
202 OpenBracket,
203 CloseBracket,
204 Eof,
205
206 Operator,
207 Ident,
208 Lifetime,
209 Path,
210 Type,
211 Const,
212
213 KwAs,
214 KwAsync,
215 KwAuto,
216 KwAwait,
217 KwBecome,
218 KwBox,
219 KwBreak,
220 KwCatch,
221 KwConst,
222 KwContinue,
223 KwContractEnsures,
224 KwContractRequires,
225 KwCrate,
226 KwDefault,
227 KwDyn,
228 KwElse,
229 KwEnum,
230 KwExtern,
231 KwFn,
232 KwFor,
233 KwGen,
234 KwIf,
235 KwImpl,
236 KwIn,
237 KwLet,
238 KwLoop,
239 KwMacro,
240 KwMacroRules,
241 KwMatch,
242 KwMod,
243 KwMove,
244 KwMut,
245 KwPub,
246 KwRaw,
247 KwRef,
248 KwReturn,
249 KwReuse,
250 KwSafe,
251 KwSelfUpper,
252 KwStatic,
253 KwStruct,
254 KwSuper,
255 KwTrait,
256 KwTry,
257 KwType,
258 KwUnderscore,
259 KwUnsafe,
260 KwUse,
261 KwWhere,
262 KwWhile,
263 KwYield,
264
265 SymAttSyntax,
266 SymClobberAbi,
267 SymInlateout,
268 SymInout,
269 SymIs,
270 SymLabel,
271 SymLateout,
272 SymMayUnwind,
273 SymNomem,
274 SymNoreturn,
275 SymNostack,
276 SymOptions,
277 SymOut,
278 SymPreservesFlags,
279 SymPure,
280 SymReadonly,
281 SymSym,
282 };
283 token_type
284 }
285
286 pub(super) fn is_keyword(&self) -> Option<Symbol> {
287 match self {
288 TokenType::KwAs => Some(kw::As),
289 TokenType::KwAsync => Some(kw::Async),
290 TokenType::KwAuto => Some(kw::Auto),
291 TokenType::KwAwait => Some(kw::Await),
292 TokenType::KwBecome => Some(kw::Become),
293 TokenType::KwBox => Some(kw::Box),
294 TokenType::KwBreak => Some(kw::Break),
295 TokenType::KwCatch => Some(kw::Catch),
296 TokenType::KwConst => Some(kw::Const),
297 TokenType::KwContinue => Some(kw::Continue),
298 TokenType::KwContractEnsures => Some(kw::ContractEnsures),
299 TokenType::KwContractRequires => Some(kw::ContractRequires),
300 TokenType::KwCrate => Some(kw::Crate),
301 TokenType::KwDefault => Some(kw::Default),
302 TokenType::KwDyn => Some(kw::Dyn),
303 TokenType::KwElse => Some(kw::Else),
304 TokenType::KwEnum => Some(kw::Enum),
305 TokenType::KwExtern => Some(kw::Extern),
306 TokenType::KwFn => Some(kw::Fn),
307 TokenType::KwFor => Some(kw::For),
308 TokenType::KwGen => Some(kw::Gen),
309 TokenType::KwIf => Some(kw::If),
310 TokenType::KwImpl => Some(kw::Impl),
311 TokenType::KwIn => Some(kw::In),
312 TokenType::KwLet => Some(kw::Let),
313 TokenType::KwLoop => Some(kw::Loop),
314 TokenType::KwMacroRules => Some(kw::MacroRules),
315 TokenType::KwMacro => Some(kw::Macro),
316 TokenType::KwMatch => Some(kw::Match),
317 TokenType::KwMod => Some(kw::Mod),
318 TokenType::KwMove => Some(kw::Move),
319 TokenType::KwMut => Some(kw::Mut),
320 TokenType::KwPub => Some(kw::Pub),
321 TokenType::KwRaw => Some(kw::Raw),
322 TokenType::KwRef => Some(kw::Ref),
323 TokenType::KwReturn => Some(kw::Return),
324 TokenType::KwReuse => Some(kw::Reuse),
325 TokenType::KwSafe => Some(kw::Safe),
326 TokenType::KwSelfUpper => Some(kw::SelfUpper),
327 TokenType::KwStatic => Some(kw::Static),
328 TokenType::KwStruct => Some(kw::Struct),
329 TokenType::KwSuper => Some(kw::Super),
330 TokenType::KwTrait => Some(kw::Trait),
331 TokenType::KwTry => Some(kw::Try),
332 TokenType::KwType => Some(kw::Type),
333 TokenType::KwUnderscore => Some(kw::Underscore),
334 TokenType::KwUnsafe => Some(kw::Unsafe),
335 TokenType::KwUse => Some(kw::Use),
336 TokenType::KwWhere => Some(kw::Where),
337 TokenType::KwWhile => Some(kw::While),
338 TokenType::KwYield => Some(kw::Yield),
339
340 TokenType::SymAttSyntax => Some(sym::att_syntax),
341 TokenType::SymClobberAbi => Some(sym::clobber_abi),
342 TokenType::SymInlateout => Some(sym::inlateout),
343 TokenType::SymInout => Some(sym::inout),
344 TokenType::SymIs => Some(sym::is),
345 TokenType::SymLabel => Some(sym::label),
346 TokenType::SymLateout => Some(sym::lateout),
347 TokenType::SymMayUnwind => Some(sym::may_unwind),
348 TokenType::SymNomem => Some(sym::nomem),
349 TokenType::SymNoreturn => Some(sym::noreturn),
350 TokenType::SymNostack => Some(sym::nostack),
351 TokenType::SymOptions => Some(sym::options),
352 TokenType::SymOut => Some(sym::out),
353 TokenType::SymPreservesFlags => Some(sym::preserves_flags),
354 TokenType::SymPure => Some(sym::pure),
355 TokenType::SymReadonly => Some(sym::readonly),
356 TokenType::SymSym => Some(sym::sym),
357 _ => None,
358 }
359 }
360
361 pub(super) fn to_string(&self) -> String {
364 match self {
365 TokenType::Eq => "`=`",
366 TokenType::Lt => "`<`",
367 TokenType::Le => "`<=`",
368 TokenType::EqEq => "`==`",
369 TokenType::Gt => "`>`",
370 TokenType::AndAnd => "`&&`",
371 TokenType::OrOr => "`||`",
372 TokenType::Bang => "`!`",
373 TokenType::Tilde => "`~`",
374
375 TokenType::Plus => "`+`",
376 TokenType::Minus => "`-`",
377 TokenType::Star => "`*`",
378 TokenType::And => "`&`",
379 TokenType::Or => "`|`",
380
381 TokenType::At => "`@`",
382 TokenType::Dot => "`.`",
383 TokenType::DotDot => "`..`",
384 TokenType::DotDotDot => "`...`",
385 TokenType::DotDotEq => "`..=`",
386 TokenType::Comma => "`,`",
387 TokenType::Semi => "`;`",
388 TokenType::Colon => "`:`",
389 TokenType::PathSep => "`::`",
390 TokenType::RArrow => "`->`",
391 TokenType::FatArrow => "`=>`",
392 TokenType::Pound => "`#`",
393 TokenType::Question => "`?`",
394 TokenType::OpenParen => "`(`",
395 TokenType::CloseParen => "`)`",
396 TokenType::OpenBrace => "`{`",
397 TokenType::CloseBrace => "`}`",
398 TokenType::OpenBracket => "`[`",
399 TokenType::CloseBracket => "`]`",
400 TokenType::Eof => "<eof>",
401
402 TokenType::Operator => "an operator",
403 TokenType::Ident => "identifier",
404 TokenType::Lifetime => "lifetime",
405 TokenType::Path => "path",
406 TokenType::Type => "type",
407 TokenType::Const => "a const expression",
408
409 _ => return format!("`{}`", self.is_keyword().unwrap()),
410 }
411 .to_string()
412 }
413}
414
415#[derive(Clone, Copy, Debug)]
419pub struct ExpTokenPair<'a> {
420 pub tok: &'a TokenKind,
421 pub token_type: TokenType,
422}
423
424#[derive(Clone, Copy)]
428pub struct ExpKeywordPair {
429 pub kw: Symbol,
430 pub token_type: TokenType,
431}
432
433#[macro_export]
439#[cfg_attr(rustfmt, rustfmt::skip)]
443macro_rules! exp {
444 (@tok, $tok:ident) => {
446 $crate::parser::token_type::ExpTokenPair {
447 tok: &rustc_ast::token::$tok,
448 token_type: $crate::parser::token_type::TokenType::$tok
449 }
450 };
451
452 (@kw, $kw:ident, $token_type:ident) => {
454 $crate::parser::token_type::ExpKeywordPair {
455 kw: rustc_span::symbol::kw::$kw,
456 token_type: $crate::parser::token_type::TokenType::$token_type,
457 }
458 };
459 (@sym, $kw:ident, $token_type:ident) => {
460 $crate::parser::token_type::ExpKeywordPair {
461 kw: rustc_span::symbol::sym::$kw,
462 token_type: $crate::parser::token_type::TokenType::$token_type,
463 }
464 };
465
466 (Eq) => { exp!(@tok, Eq) };
467 (Lt) => { exp!(@tok, Lt) };
468 (Le) => { exp!(@tok, Le) };
469 (EqEq) => { exp!(@tok, EqEq) };
470 (Gt) => { exp!(@tok, Gt) };
471 (AndAnd) => { exp!(@tok, AndAnd) };
472 (OrOr) => { exp!(@tok, OrOr) };
473 (Bang) => { exp!(@tok, Bang) };
474 (Tilde) => { exp!(@tok, Tilde) };
475 (Plus) => { exp!(@tok, Plus) };
476 (Minus) => { exp!(@tok, Minus) };
477 (Star) => { exp!(@tok, Star) };
478 (And) => { exp!(@tok, And) };
479 (Or) => { exp!(@tok, Or) };
480 (At) => { exp!(@tok, At) };
481 (Dot) => { exp!(@tok, Dot) };
482 (DotDot) => { exp!(@tok, DotDot) };
483 (DotDotDot) => { exp!(@tok, DotDotDot) };
484 (DotDotEq) => { exp!(@tok, DotDotEq) };
485 (Comma) => { exp!(@tok, Comma) };
486 (Semi) => { exp!(@tok, Semi) };
487 (Colon) => { exp!(@tok, Colon) };
488 (PathSep) => { exp!(@tok, PathSep) };
489 (RArrow) => { exp!(@tok, RArrow) };
490 (FatArrow) => { exp!(@tok, FatArrow) };
491 (Pound) => { exp!(@tok, Pound) };
492 (Question) => { exp!(@tok, Question) };
493 (Eof) => { exp!(@tok, Eof) };
494
495 (OpenParen) => { exp!(@tok, OpenParen) };
496 (OpenBrace) => { exp!(@tok, OpenBrace) };
497 (OpenBracket) => { exp!(@tok, OpenBracket) };
498 (CloseParen) => { exp!(@tok, CloseParen) };
499 (CloseBrace) => { exp!(@tok, CloseBrace) };
500 (CloseBracket) => { exp!(@tok, CloseBracket) };
501
502 (As) => { exp!(@kw, As, KwAs) };
503 (Async) => { exp!(@kw, Async, KwAsync) };
504 (Auto) => { exp!(@kw, Auto, KwAuto) };
505 (Await) => { exp!(@kw, Await, KwAwait) };
506 (Become) => { exp!(@kw, Become, KwBecome) };
507 (Box) => { exp!(@kw, Box, KwBox) };
508 (Break) => { exp!(@kw, Break, KwBreak) };
509 (Catch) => { exp!(@kw, Catch, KwCatch) };
510 (Const) => { exp!(@kw, Const, KwConst) };
511 (Continue) => { exp!(@kw, Continue, KwContinue) };
512 (ContractEnsures) => { exp!(@kw, ContractEnsures, KwContractEnsures) };
513 (ContractRequires) => { exp!(@kw, ContractRequires, KwContractRequires) };
514 (Crate) => { exp!(@kw, Crate, KwCrate) };
515 (Default) => { exp!(@kw, Default, KwDefault) };
516 (Dyn) => { exp!(@kw, Dyn, KwDyn) };
517 (Else) => { exp!(@kw, Else, KwElse) };
518 (Enum) => { exp!(@kw, Enum, KwEnum) };
519 (Extern) => { exp!(@kw, Extern, KwExtern) };
520 (Fn) => { exp!(@kw, Fn, KwFn) };
521 (For) => { exp!(@kw, For, KwFor) };
522 (Gen) => { exp!(@kw, Gen, KwGen) };
523 (If) => { exp!(@kw, If, KwIf) };
524 (Impl) => { exp!(@kw, Impl, KwImpl) };
525 (In) => { exp!(@kw, In, KwIn) };
526 (Let) => { exp!(@kw, Let, KwLet) };
527 (Loop) => { exp!(@kw, Loop, KwLoop) };
528 (Macro) => { exp!(@kw, Macro, KwMacro) };
529 (MacroRules) => { exp!(@kw, MacroRules, KwMacroRules) };
530 (Match) => { exp!(@kw, Match, KwMatch) };
531 (Mod) => { exp!(@kw, Mod, KwMod) };
532 (Move) => { exp!(@kw, Move, KwMove) };
533 (Mut) => { exp!(@kw, Mut, KwMut) };
534 (Pub) => { exp!(@kw, Pub, KwPub) };
535 (Raw) => { exp!(@kw, Raw, KwRaw) };
536 (Ref) => { exp!(@kw, Ref, KwRef) };
537 (Return) => { exp!(@kw, Return, KwReturn) };
538 (Reuse) => { exp!(@kw, Reuse, KwReuse) };
539 (Safe) => { exp!(@kw, Safe, KwSafe) };
540 (SelfUpper) => { exp!(@kw, SelfUpper, KwSelfUpper) };
541 (Static) => { exp!(@kw, Static, KwStatic) };
542 (Struct) => { exp!(@kw, Struct, KwStruct) };
543 (Super) => { exp!(@kw, Super, KwSuper) };
544 (Trait) => { exp!(@kw, Trait, KwTrait) };
545 (Try) => { exp!(@kw, Try, KwTry) };
546 (Type) => { exp!(@kw, Type, KwType) };
547 (Underscore) => { exp!(@kw, Underscore, KwUnderscore) };
548 (Unsafe) => { exp!(@kw, Unsafe, KwUnsafe) };
549 (Use) => { exp!(@kw, Use, KwUse) };
550 (Where) => { exp!(@kw, Where, KwWhere) };
551 (While) => { exp!(@kw, While, KwWhile) };
552 (Yield) => { exp!(@kw, Yield, KwYield) };
553
554 (AttSyntax) => { exp!(@sym, att_syntax, SymAttSyntax) };
555 (ClobberAbi) => { exp!(@sym, clobber_abi, SymClobberAbi) };
556 (Inlateout) => { exp!(@sym, inlateout, SymInlateout) };
557 (Inout) => { exp!(@sym, inout, SymInout) };
558 (Is) => { exp!(@sym, is, SymIs) };
559 (Label) => { exp!(@sym, label, SymLabel) };
560 (Lateout) => { exp!(@sym, lateout, SymLateout) };
561 (MayUnwind) => { exp!(@sym, may_unwind, SymMayUnwind) };
562 (Nomem) => { exp!(@sym, nomem, SymNomem) };
563 (Noreturn) => { exp!(@sym, noreturn, SymNoreturn) };
564 (Nostack) => { exp!(@sym, nostack, SymNostack) };
565 (Options) => { exp!(@sym, options, SymOptions) };
566 (Out) => { exp!(@sym, out, SymOut) };
567 (PreservesFlags) => { exp!(@sym, preserves_flags, SymPreservesFlags) };
568 (Pure) => { exp!(@sym, pure, SymPure) };
569 (Readonly) => { exp!(@sym, readonly, SymReadonly) };
570 (Sym) => { exp!(@sym, sym, SymSym) };
571}
572
573#[derive(Clone, Copy)]
577pub(super) struct TokenTypeSet(u128);
578
579impl TokenTypeSet {
580 pub(super) fn new() -> TokenTypeSet {
581 TokenTypeSet(0)
582 }
583
584 pub(super) fn is_empty(&self) -> bool {
585 self.0 == 0
586 }
587
588 pub(super) fn insert(&mut self, token_type: TokenType) {
589 self.0 = self.0 | (1u128 << token_type as u32)
590 }
591
592 pub(super) fn clear(&mut self) {
593 self.0 = 0
594 }
595
596 pub(super) fn contains(&self, token_type: TokenType) -> bool {
597 self.0 & (1u128 << token_type as u32) != 0
598 }
599
600 pub(super) fn iter(&self) -> TokenTypeSetIter {
601 TokenTypeSetIter(*self)
602 }
603}
604
605pub(super) struct TokenTypeSetIter(TokenTypeSet);
609
610impl Iterator for TokenTypeSetIter {
611 type Item = TokenType;
612
613 fn next(&mut self) -> Option<TokenType> {
614 let num_bits: u32 = (size_of_val(&self.0.0) * 8) as u32;
615 assert_eq!(num_bits, 128);
616 let z = self.0.0.trailing_zeros();
617 if z == num_bits {
618 None
619 } else {
620 self.0.0 &= !(1 << z); Some(TokenType::from_u32(z))
622 }
623 }
624}