@@ -121,6 +121,11 @@ pub fn symbols(input: TokenStream) -> TokenStream {
121121 output
122122}
123123
124+ struct Preinterned {
125+ idx : u32 ,
126+ span_of_name : Span ,
127+ }
128+
124129fn symbols_with_errors ( input : TokenStream ) -> ( TokenStream , Vec < syn:: Error > ) {
125130 let mut errors = Errors :: default ( ) ;
126131
@@ -137,17 +142,20 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
137142 let mut keyword_stream = quote ! { } ;
138143 let mut symbols_stream = quote ! { } ;
139144 let mut prefill_stream = quote ! { } ;
140- let mut counter = 0u32 ;
141- let mut keys =
142- HashMap :: < String , Span > :: with_capacity ( input . keywords . len ( ) + input . symbols . len ( ) + 10 ) ;
145+ let mut entries = HashMap :: < String , Preinterned > :: with_capacity (
146+ input . keywords . len ( ) + input . symbols . len ( ) + 10 ,
147+ ) ;
143148 let mut prev_key: Option < ( Span , String ) > = None ;
144149
145- let mut check_dup = |span : Span , str : & str , errors : & mut Errors | {
146- if let Some ( prev_span ) = keys . get ( str) {
150+ let mut insert = |span : Span , str : & str , errors : & mut Errors | -> u32 {
151+ if let Some ( prev ) = entries . get ( str) {
147152 errors. error ( span, format ! ( "Symbol `{str}` is duplicated" ) ) ;
148- errors. error ( * prev_span, "location of previous definition" . to_string ( ) ) ;
153+ errors. error ( prev. span_of_name , "location of previous definition" . to_string ( ) ) ;
154+ prev. idx
149155 } else {
150- keys. insert ( str. to_string ( ) , span) ;
156+ let idx = u32:: try_from ( entries. len ( ) ) . expect ( "way too many symbols" ) ;
157+ entries. insert ( str. to_string ( ) , Preinterned { idx, span_of_name : span } ) ;
158+ idx
151159 }
152160 } ;
153161
@@ -166,14 +174,13 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
166174 let name = & keyword. name ;
167175 let value = & keyword. value ;
168176 let value_string = value. value ( ) ;
169- check_dup ( keyword. name . span ( ) , & value_string, & mut errors) ;
177+ let idx = insert ( keyword. name . span ( ) , & value_string, & mut errors) ;
170178 prefill_stream. extend ( quote ! {
171179 #value,
172180 } ) ;
173181 keyword_stream. extend ( quote ! {
174- pub const #name: Symbol = Symbol :: new( #counter ) ;
182+ pub const #name: Symbol = Symbol :: new( #idx ) ;
175183 } ) ;
176- counter += 1 ;
177184 }
178185
179186 // Generate the listed symbols.
@@ -183,32 +190,31 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
183190 Value :: SameAsName => name. to_string ( ) ,
184191 Value :: String ( lit) => lit. value ( ) ,
185192 } ;
186- check_dup ( symbol. name . span ( ) , & value, & mut errors) ;
193+ let idx = insert ( symbol. name . span ( ) , & value, & mut errors) ;
187194 check_order ( symbol. name . span ( ) , & name. to_string ( ) , & mut errors) ;
188195
189196 prefill_stream. extend ( quote ! {
190197 #value,
191198 } ) ;
192199 symbols_stream. extend ( quote ! {
193- pub const #name: Symbol = Symbol :: new( #counter ) ;
200+ pub const #name: Symbol = Symbol :: new( #idx ) ;
194201 } ) ;
195- counter += 1 ;
196202 }
197203
198204 // Generate symbols for the strings "0", "1", ..., "9".
199- let digits_base = counter;
200- counter += 10 ;
201205 for n in 0 ..10 {
202206 let n = n. to_string ( ) ;
203- check_dup ( Span :: call_site ( ) , & n, & mut errors) ;
207+ insert ( Span :: call_site ( ) , & n, & mut errors) ;
204208 prefill_stream. extend ( quote ! {
205209 #n,
206210 } ) ;
207211 }
208212
213+ let symbol_digits_base = entries[ "0" ] . idx ;
214+ let preinterned_symbols_count = u32:: try_from ( entries. len ( ) ) . expect ( "way too many symbols" ) ;
209215 let output = quote ! {
210- const SYMBOL_DIGITS_BASE : u32 = #digits_base ;
211- const PREINTERNED_SYMBOLS_COUNT : u32 = #counter ;
216+ const SYMBOL_DIGITS_BASE : u32 = #symbol_digits_base ;
217+ const PREINTERNED_SYMBOLS_COUNT : u32 = #preinterned_symbols_count ;
212218
213219 #[ doc( hidden) ]
214220 #[ allow( non_upper_case_globals) ]
0 commit comments