@@ -102,15 +102,25 @@ impl Parse for Input {
102
102
}
103
103
}
104
104
105
+ /// WARNING: this function must behave equivalently to
106
+ /// `Symbol::try_new_inlined()`. It does, modulo the fact that it accepts fewer
107
+ /// inputs, panicking on any string containing non-ASCII or NUL bytes. This is
108
+ /// fine because static symbols never contain such bytes. Once those bytes are
109
+ /// excluded, it reduces to a mere length check.
110
+ fn is_inlinable ( s : & str ) -> bool {
111
+ assert ! ( s. as_bytes( ) . iter( ) . all( |& b| 0 < b && b < 0x80 ) ) ;
112
+ s. len ( ) <= 4
113
+ }
114
+
105
115
pub fn symbols ( input : TokenStream ) -> TokenStream {
106
116
let input = parse_macro_input ! ( input as Input ) ;
107
117
108
118
let mut keyword_stream = quote ! { } ;
109
119
let mut symbols_stream = quote ! { } ;
110
120
let mut digits_stream = quote ! { } ;
111
- let mut prefill_stream = quote ! { } ;
121
+ let mut prefill_tabled_stream = quote ! { } ;
122
+ let mut tabled_counter = 0u32 ;
112
123
let mut keyword_class_stream = quote ! { } ;
113
- let mut counter = 0u32 ;
114
124
let mut keys = HashSet :: < String > :: new ( ) ;
115
125
let mut prev_key: Option < String > = None ;
116
126
let mut errors = Vec :: < String > :: new ( ) ;
@@ -136,18 +146,26 @@ pub fn symbols(input: TokenStream) -> TokenStream {
136
146
for keyword in keywords {
137
147
let name = & keyword. name ;
138
148
let value = & keyword. value ;
139
- check_dup ( & value. value ( ) , & mut errors) ;
140
- prefill_stream. extend ( quote ! {
141
- #value,
142
- } ) ;
143
- keyword_stream. extend ( quote ! {
144
- #[ allow( non_upper_case_globals) ]
145
- pub const #name: Symbol = Symbol :: new( #counter) ;
146
- } ) ;
149
+ let v = value. value ( ) ;
150
+ check_dup ( & v, & mut errors) ;
151
+ if is_inlinable ( & v) {
152
+ keyword_stream. extend ( quote ! {
153
+ #[ allow( non_upper_case_globals) ]
154
+ pub const #name: Symbol = Symbol :: new_inlined( #value) ;
155
+ } ) ;
156
+ } else {
157
+ prefill_tabled_stream. extend ( quote ! {
158
+ #value,
159
+ } ) ;
160
+ keyword_stream. extend ( quote ! {
161
+ #[ allow( non_upper_case_globals) ]
162
+ pub const #name: Symbol = Symbol :: new_tabled( #tabled_counter) ;
163
+ } ) ;
164
+ tabled_counter += 1 ;
165
+ }
147
166
class_stream. extend ( quote ! {
148
167
| kw:: #name
149
168
} ) ;
150
- counter += 1 ;
151
169
}
152
170
if let Some ( class) = class {
153
171
keyword_class_stream. extend ( quote ! {
@@ -170,28 +188,32 @@ pub fn symbols(input: TokenStream) -> TokenStream {
170
188
} ;
171
189
check_dup ( & value, & mut errors) ;
172
190
check_order ( & name. to_string ( ) , & mut errors) ;
173
- prefill_stream. extend ( quote ! {
174
- #value,
175
- } ) ;
176
- symbols_stream. extend ( quote ! {
177
- #[ allow( rustc:: default_hash_types) ]
178
- #[ allow( non_upper_case_globals) ]
179
- pub const #name: Symbol = Symbol :: new( #counter) ;
180
- } ) ;
181
- counter += 1 ;
191
+ if is_inlinable ( & value) {
192
+ symbols_stream. extend ( quote ! {
193
+ #[ allow( rustc:: default_hash_types) ]
194
+ #[ allow( non_upper_case_globals) ]
195
+ pub const #name: Symbol = Symbol :: new_inlined( #value) ;
196
+ } ) ;
197
+ } else {
198
+ prefill_tabled_stream. extend ( quote ! {
199
+ #value,
200
+ } ) ;
201
+ symbols_stream. extend ( quote ! {
202
+ #[ allow( rustc:: default_hash_types) ]
203
+ #[ allow( non_upper_case_globals) ]
204
+ pub const #name: Symbol = Symbol :: new_tabled( #tabled_counter) ;
205
+ } ) ;
206
+ tabled_counter += 1 ;
207
+ }
182
208
}
183
209
184
210
// Generate symbols for the strings "0", "1", ..., "9".
185
211
for n in 0 ..10 {
186
212
let n = n. to_string ( ) ;
187
213
check_dup ( & n, & mut errors) ;
188
- prefill_stream. extend ( quote ! {
189
- #n,
190
- } ) ;
191
214
digits_stream. extend ( quote ! {
192
- Symbol :: new ( #counter ) ,
215
+ Symbol :: new_inlined ( #n ) ,
193
216
} ) ;
194
- counter += 1 ;
195
217
}
196
218
197
219
if !errors. is_empty ( ) {
@@ -221,8 +243,8 @@ pub fn symbols(input: TokenStream) -> TokenStream {
221
243
222
244
impl Interner {
223
245
pub fn fresh( ) -> Self {
224
- Interner :: prefill ( & [
225
- #prefill_stream
246
+ Interner :: prefill_tabled ( & [
247
+ #prefill_tabled_stream
226
248
] )
227
249
}
228
250
}
0 commit comments