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