Skip to content

Commit df56c50

Browse files
committed
Make TokenType::from_u32 foolproof.
Currently it relies on having the right integer for every variant, and if you add a variant you need to adjust the integers for all subsequent variants, which is a pain. This commit introduces a match guard formulation that takes advantage of the enum-to-integer conversion to avoid specifying the integer for each variant. And it does this via a macro to avoid lots of boilerplate.
1 parent b9bf0b4 commit df56c50

File tree

1 file changed

+126
-115
lines changed

1 file changed

+126
-115
lines changed

compiler/rustc_parse/src/parser/token_type.rs

+126-115
Original file line numberDiff line numberDiff line change
@@ -145,124 +145,135 @@ pub enum TokenType {
145145
// tidy-alphabetical-end
146146
}
147147

148+
// Macro to avoid repetitive boilerplate code.
149+
macro_rules! from_u32_match {
150+
($val:ident; $($tok:ident,)+) => {
151+
// A more obvious formulation would be `0 => TokenType::Eq`. But
152+
// this formulation with the guard lets us avoid specifying a
153+
// specific integer for each variant.
154+
match $val {
155+
$(
156+
t if t == TokenType::$tok as u32 => TokenType::$tok,
157+
)+
158+
_ => panic!("unhandled value: {}", $val),
159+
}
160+
};
161+
}
162+
148163
impl TokenType {
149164
fn from_u32(val: u32) -> TokenType {
150-
let token_type = match val {
151-
0 => TokenType::Eq,
152-
1 => TokenType::Lt,
153-
2 => TokenType::Le,
154-
3 => TokenType::EqEq,
155-
4 => TokenType::Gt,
156-
5 => TokenType::AndAnd,
157-
6 => TokenType::OrOr,
158-
7 => TokenType::Not,
159-
8 => TokenType::Tilde,
160-
161-
9 => TokenType::Plus,
162-
10 => TokenType::Minus,
163-
11 => TokenType::Star,
164-
12 => TokenType::And,
165-
13 => TokenType::Or,
166-
167-
14 => TokenType::At,
168-
15 => TokenType::Dot,
169-
16 => TokenType::DotDot,
170-
17 => TokenType::DotDotDot,
171-
18 => TokenType::DotDotEq,
172-
19 => TokenType::Comma,
173-
20 => TokenType::Semi,
174-
21 => TokenType::Colon,
175-
22 => TokenType::PathSep,
176-
23 => TokenType::RArrow,
177-
24 => TokenType::FatArrow,
178-
25 => TokenType::Pound,
179-
26 => TokenType::Question,
180-
27 => TokenType::OpenParen,
181-
28 => TokenType::CloseParen,
182-
29 => TokenType::OpenBrace,
183-
30 => TokenType::CloseBrace,
184-
31 => TokenType::OpenBracket,
185-
32 => TokenType::CloseBracket,
186-
33 => TokenType::Eof,
187-
188-
34 => TokenType::Operator,
189-
35 => TokenType::Ident,
190-
36 => TokenType::Lifetime,
191-
37 => TokenType::Path,
192-
38 => TokenType::Type,
193-
39 => TokenType::Const,
194-
195-
40 => TokenType::KwAs,
196-
41 => TokenType::KwAsync,
197-
42 => TokenType::KwAuto,
198-
43 => TokenType::KwAwait,
199-
44 => TokenType::KwBecome,
200-
45 => TokenType::KwBox,
201-
46 => TokenType::KwBreak,
202-
47 => TokenType::KwCatch,
203-
48 => TokenType::KwConst,
204-
49 => TokenType::KwContinue,
205-
50 => TokenType::KwCrate,
206-
51 => TokenType::KwDefault,
207-
52 => TokenType::KwDyn,
208-
53 => TokenType::KwElse,
209-
54 => TokenType::KwEnum,
210-
55 => TokenType::KwExtern,
211-
56 => TokenType::KwFn,
212-
57 => TokenType::KwFor,
213-
58 => TokenType::KwGen,
214-
59 => TokenType::KwIf,
215-
60 => TokenType::KwImpl,
216-
61 => TokenType::KwIn,
217-
62 => TokenType::KwLet,
218-
63 => TokenType::KwLoop,
219-
64 => TokenType::KwMacro,
220-
65 => TokenType::KwMacroRules,
221-
66 => TokenType::KwMatch,
222-
67 => TokenType::KwMod,
223-
68 => TokenType::KwMove,
224-
69 => TokenType::KwMut,
225-
70 => TokenType::KwPub,
226-
71 => TokenType::KwRaw,
227-
72 => TokenType::KwRef,
228-
73 => TokenType::KwReturn,
229-
74 => TokenType::KwReuse,
230-
75 => TokenType::KwSafe,
231-
76 => TokenType::KwSelfUpper,
232-
77 => TokenType::KwStatic,
233-
78 => TokenType::KwStruct,
234-
79 => TokenType::KwTrait,
235-
80 => TokenType::KwTry,
236-
81 => TokenType::KwType,
237-
82 => TokenType::KwUnderscore,
238-
83 => TokenType::KwUnsafe,
239-
84 => TokenType::KwUse,
240-
85 => TokenType::KwWhere,
241-
86 => TokenType::KwWhile,
242-
87 => TokenType::KwYield,
243-
244-
88 => TokenType::SymAttSyntax,
245-
89 => TokenType::SymClobberAbi,
246-
90 => TokenType::SymInlateout,
247-
91 => TokenType::SymInout,
248-
92 => TokenType::SymIs,
249-
93 => TokenType::SymLabel,
250-
94 => TokenType::SymLateout,
251-
95 => TokenType::SymMayUnwind,
252-
96 => TokenType::SymNomem,
253-
97 => TokenType::SymNoreturn,
254-
98 => TokenType::SymNostack,
255-
99 => TokenType::SymOptions,
256-
100 => TokenType::SymOut,
257-
101 => TokenType::SymPreservesFlags,
258-
102 => TokenType::SymPure,
259-
103 => TokenType::SymReadonly,
260-
104 => TokenType::SymSym,
261-
262-
_ => panic!("unhandled value: {val}"),
165+
let token_type = from_u32_match! { val;
166+
Eq,
167+
Lt,
168+
Le,
169+
EqEq,
170+
Gt,
171+
AndAnd,
172+
OrOr,
173+
Not,
174+
Tilde,
175+
176+
Plus,
177+
Minus,
178+
Star,
179+
And,
180+
Or,
181+
182+
At,
183+
Dot,
184+
DotDot,
185+
DotDotDot,
186+
DotDotEq,
187+
Comma,
188+
Semi,
189+
Colon,
190+
PathSep,
191+
RArrow,
192+
FatArrow,
193+
Pound,
194+
Question,
195+
OpenParen,
196+
CloseParen,
197+
OpenBrace,
198+
CloseBrace,
199+
OpenBracket,
200+
CloseBracket,
201+
Eof,
202+
203+
Operator,
204+
Ident,
205+
Lifetime,
206+
Path,
207+
Type,
208+
Const,
209+
210+
KwAs,
211+
KwAsync,
212+
KwAuto,
213+
KwAwait,
214+
KwBecome,
215+
KwBox,
216+
KwBreak,
217+
KwCatch,
218+
KwConst,
219+
KwContinue,
220+
KwCrate,
221+
KwDefault,
222+
KwDyn,
223+
KwElse,
224+
KwEnum,
225+
KwExtern,
226+
KwFn,
227+
KwFor,
228+
KwGen,
229+
KwIf,
230+
KwImpl,
231+
KwIn,
232+
KwLet,
233+
KwLoop,
234+
KwMacro,
235+
KwMacroRules,
236+
KwMatch,
237+
KwMod,
238+
KwMove,
239+
KwMut,
240+
KwPub,
241+
KwRaw,
242+
KwRef,
243+
KwReturn,
244+
KwReuse,
245+
KwSafe,
246+
KwSelfUpper,
247+
KwStatic,
248+
KwStruct,
249+
KwTrait,
250+
KwTry,
251+
KwType,
252+
KwUnderscore,
253+
KwUnsafe,
254+
KwUse,
255+
KwWhere,
256+
KwWhile,
257+
KwYield,
258+
259+
SymAttSyntax,
260+
SymClobberAbi,
261+
SymInlateout,
262+
SymInout,
263+
SymIs,
264+
SymLabel,
265+
SymLateout,
266+
SymMayUnwind,
267+
SymNomem,
268+
SymNoreturn,
269+
SymNostack,
270+
SymOptions,
271+
SymOut,
272+
SymPreservesFlags,
273+
SymPure,
274+
SymReadonly,
275+
SymSym,
263276
};
264-
// This assertion will detect if this method and the type definition get out of sync.
265-
assert_eq!(token_type as u32, val);
266277
token_type
267278
}
268279

0 commit comments

Comments
 (0)