@@ -126,6 +126,32 @@ struct Preinterned {
126126 span_of_name : Span ,
127127}
128128
129+ struct Entries {
130+ map : HashMap < String , Preinterned > ,
131+ }
132+
133+ impl Entries {
134+ fn with_capacity ( capacity : usize ) -> Self {
135+ Entries { map : HashMap :: with_capacity ( capacity) }
136+ }
137+
138+ fn insert ( & mut self , span : Span , str : & str , errors : & mut Errors ) -> u32 {
139+ if let Some ( prev) = self . map . get ( str) {
140+ errors. error ( span, format ! ( "Symbol `{str}` is duplicated" ) ) ;
141+ errors. error ( prev. span_of_name , "location of previous definition" . to_string ( ) ) ;
142+ prev. idx
143+ } else {
144+ let idx = self . len ( ) ;
145+ self . map . insert ( str. to_string ( ) , Preinterned { idx, span_of_name : span } ) ;
146+ idx
147+ }
148+ }
149+
150+ fn len ( & self ) -> u32 {
151+ u32:: try_from ( self . map . len ( ) ) . expect ( "way too many symbols" )
152+ }
153+ }
154+
129155fn symbols_with_errors ( input : TokenStream ) -> ( TokenStream , Vec < syn:: Error > ) {
130156 let mut errors = Errors :: default ( ) ;
131157
@@ -142,23 +168,9 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
142168 let mut keyword_stream = quote ! { } ;
143169 let mut symbols_stream = quote ! { } ;
144170 let mut prefill_stream = quote ! { } ;
145- let mut entries = HashMap :: < String , Preinterned > :: with_capacity (
146- input. keywords . len ( ) + input. symbols . len ( ) + 10 ,
147- ) ;
171+ let mut entries = Entries :: with_capacity ( input. keywords . len ( ) + input. symbols . len ( ) + 10 ) ;
148172 let mut prev_key: Option < ( Span , String ) > = None ;
149173
150- let mut insert = |span : Span , str : & str , errors : & mut Errors | -> u32 {
151- if let Some ( prev) = entries. get ( str) {
152- errors. error ( span, format ! ( "Symbol `{str}` is duplicated" ) ) ;
153- errors. error ( prev. span_of_name , "location of previous definition" . to_string ( ) ) ;
154- prev. idx
155- } else {
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
159- }
160- } ;
161-
162174 let mut check_order = |span : Span , str : & str , errors : & mut Errors | {
163175 if let Some ( ( prev_span, ref prev_str) ) = prev_key {
164176 if str < prev_str {
@@ -174,7 +186,7 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
174186 let name = & keyword. name ;
175187 let value = & keyword. value ;
176188 let value_string = value. value ( ) ;
177- let idx = insert ( keyword. name . span ( ) , & value_string, & mut errors) ;
189+ let idx = entries . insert ( keyword. name . span ( ) , & value_string, & mut errors) ;
178190 prefill_stream. extend ( quote ! {
179191 #value,
180192 } ) ;
@@ -190,7 +202,7 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
190202 Value :: SameAsName => name. to_string ( ) ,
191203 Value :: String ( lit) => lit. value ( ) ,
192204 } ;
193- let idx = insert ( symbol. name . span ( ) , & value, & mut errors) ;
205+ let idx = entries . insert ( symbol. name . span ( ) , & value, & mut errors) ;
194206 check_order ( symbol. name . span ( ) , & name. to_string ( ) , & mut errors) ;
195207
196208 prefill_stream. extend ( quote ! {
@@ -204,14 +216,14 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
204216 // Generate symbols for the strings "0", "1", ..., "9".
205217 for n in 0 ..10 {
206218 let n = n. to_string ( ) ;
207- insert ( Span :: call_site ( ) , & n, & mut errors) ;
219+ entries . insert ( Span :: call_site ( ) , & n, & mut errors) ;
208220 prefill_stream. extend ( quote ! {
209221 #n,
210222 } ) ;
211223 }
212224
213- let symbol_digits_base = entries[ "0" ] . idx ;
214- let preinterned_symbols_count = u32 :: try_from ( entries. len ( ) ) . expect ( "way too many symbols" ) ;
225+ let symbol_digits_base = entries. map [ "0" ] . idx ;
226+ let preinterned_symbols_count = entries. len ( ) ;
215227 let output = quote ! {
216228 const SYMBOL_DIGITS_BASE : u32 = #symbol_digits_base;
217229 const PREINTERNED_SYMBOLS_COUNT : u32 = #preinterned_symbols_count;
0 commit comments