22
22
//! cargo expand > /tmp/rustc_span.rs # it's a big file
23
23
//! ```
24
24
25
+ use indexmap:: IndexMap ;
25
26
use proc_macro2:: { Span , TokenStream } ;
26
27
use quote:: quote;
27
- use std:: collections:: HashMap ;
28
28
use syn:: parse:: { Parse , ParseStream , Result } ;
29
29
use syn:: { braced, punctuated:: Punctuated , Expr , Ident , Lit , LitStr , Macro , Token } ;
30
30
@@ -136,30 +136,29 @@ pub fn symbols(input: TokenStream) -> TokenStream {
136
136
output
137
137
}
138
138
139
- struct Preinterned {
140
- idx : u32 ,
141
- span_of_name : Span ,
142
- }
143
-
144
139
struct Entries {
145
- map : HashMap < String , Preinterned > ,
140
+ map : IndexMap < String , Span > ,
146
141
}
147
142
148
143
impl Entries {
149
144
fn with_capacity ( capacity : usize ) -> Self {
150
- Entries { map : HashMap :: with_capacity ( capacity) }
145
+ Entries { map : IndexMap :: with_capacity ( capacity) }
151
146
}
152
147
153
148
fn insert ( & mut self , span : Span , str : & str , errors : & mut Errors ) -> u32 {
154
- if let Some ( prev) = self . map . get ( str) {
155
- errors. error ( span, format ! ( "Symbol `{str}` is duplicated" ) ) ;
156
- errors. error ( prev. span_of_name , "location of previous definition" . to_string ( ) ) ;
157
- prev. idx
158
- } else {
159
- let idx = self . len ( ) ;
160
- self . map . insert ( str. to_string ( ) , Preinterned { idx, span_of_name : span } ) ;
161
- idx
162
- }
149
+ let idx = match self . map . entry ( str. to_string ( ) ) {
150
+ indexmap:: map:: Entry :: Occupied ( prev) => {
151
+ errors. error ( span, format ! ( "Symbol `{str}` is duplicated" ) ) ;
152
+ errors. error ( * prev. get ( ) , "location of previous definition" . to_string ( ) ) ;
153
+ prev. index ( )
154
+ }
155
+ indexmap:: map:: Entry :: Vacant ( entry) => {
156
+ let idx = entry. index ( ) ;
157
+ entry. insert ( span) ;
158
+ idx
159
+ }
160
+ } ;
161
+ u32:: try_from ( idx) . expect ( "way too many symbols" )
163
162
}
164
163
165
164
fn len ( & self ) -> u32 {
@@ -273,8 +272,8 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
273
272
}
274
273
} ;
275
274
276
- let idx = if let Some ( prev) = entries. map . get ( & value) {
277
- prev. idx
275
+ let idx = if let Some ( prev) = entries. map . get_index_of ( & value) {
276
+ u32 :: try_from ( prev) . expect ( "way too many symbols" )
278
277
} else {
279
278
prefill_stream. extend ( quote ! {
280
279
#value,
@@ -288,7 +287,8 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
288
287
} ) ;
289
288
}
290
289
291
- let symbol_digits_base = entries. map [ "0" ] . idx ;
290
+ let symbol_digits_base =
291
+ u32:: try_from ( entries. map . get_index_of ( "0" ) . unwrap ( ) ) . expect ( "way too many symbols" ) ;
292
292
let preinterned_symbols_count = entries. len ( ) ;
293
293
let output = quote ! {
294
294
const SYMBOL_DIGITS_BASE : u32 = #symbol_digits_base;
0 commit comments