about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2023-10-25 13:20:47 -0700
committerDavid Tolnay <dtolnay@gmail.com>2023-10-26 01:57:09 -0700
commit8dea49ad7baa4fbb8b2394a6682d601065350134 (patch)
tree24db3bf8ddd4e2bd1a24d299acd463ae0b86a4bd
parent95742ff23cf2283da796f483386367f7fdc06bc6 (diff)
downloadrust-8dea49ad7baa4fbb8b2394a6682d601065350134.tar.gz
rust-8dea49ad7baa4fbb8b2394a6682d601065350134.zip
Delete counter from symbols proc macro in favor of hashmap as source of truth
-rw-r--r--compiler/rustc_macros/src/symbols.rs42
1 files changed, 24 insertions, 18 deletions
diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs
index c48df8313b2..d06f1d08214 100644
--- a/compiler/rustc_macros/src/symbols.rs
+++ b/compiler/rustc_macros/src/symbols.rs
@@ -121,6 +121,11 @@ pub fn symbols(input: TokenStream) -> TokenStream {
     output
 }
 
+struct Preinterned {
+    idx: u32,
+    span_of_name: Span,
+}
+
 fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
     let mut errors = Errors::default();
 
@@ -137,17 +142,20 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
     let mut keyword_stream = quote! {};
     let mut symbols_stream = quote! {};
     let mut prefill_stream = quote! {};
-    let mut counter = 0u32;
-    let mut keys =
-        HashMap::<String, Span>::with_capacity(input.keywords.len() + input.symbols.len() + 10);
+    let mut entries = HashMap::<String, Preinterned>::with_capacity(
+        input.keywords.len() + input.symbols.len() + 10,
+    );
     let mut prev_key: Option<(Span, String)> = None;
 
-    let mut check_dup = |span: Span, str: &str, errors: &mut Errors| {
-        if let Some(prev_span) = keys.get(str) {
+    let mut insert = |span: Span, str: &str, errors: &mut Errors| -> u32 {
+        if let Some(prev) = entries.get(str) {
             errors.error(span, format!("Symbol `{str}` is duplicated"));
-            errors.error(*prev_span, "location of previous definition".to_string());
+            errors.error(prev.span_of_name, "location of previous definition".to_string());
+            prev.idx
         } else {
-            keys.insert(str.to_string(), span);
+            let idx = u32::try_from(entries.len()).expect("way too many symbols");
+            entries.insert(str.to_string(), Preinterned { idx, span_of_name: span });
+            idx
         }
     };
 
@@ -166,14 +174,13 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
         let name = &keyword.name;
         let value = &keyword.value;
         let value_string = value.value();
-        check_dup(keyword.name.span(), &value_string, &mut errors);
+        let idx = insert(keyword.name.span(), &value_string, &mut errors);
         prefill_stream.extend(quote! {
             #value,
         });
         keyword_stream.extend(quote! {
-            pub const #name: Symbol = Symbol::new(#counter);
+            pub const #name: Symbol = Symbol::new(#idx);
         });
-        counter += 1;
     }
 
     // Generate the listed symbols.
@@ -183,32 +190,31 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
             Value::SameAsName => name.to_string(),
             Value::String(lit) => lit.value(),
         };
-        check_dup(symbol.name.span(), &value, &mut errors);
+        let idx = insert(symbol.name.span(), &value, &mut errors);
         check_order(symbol.name.span(), &name.to_string(), &mut errors);
 
         prefill_stream.extend(quote! {
             #value,
         });
         symbols_stream.extend(quote! {
-            pub const #name: Symbol = Symbol::new(#counter);
+            pub const #name: Symbol = Symbol::new(#idx);
         });
-        counter += 1;
     }
 
     // Generate symbols for the strings "0", "1", ..., "9".
-    let digits_base = counter;
-    counter += 10;
     for n in 0..10 {
         let n = n.to_string();
-        check_dup(Span::call_site(), &n, &mut errors);
+        insert(Span::call_site(), &n, &mut errors);
         prefill_stream.extend(quote! {
             #n,
         });
     }
 
+    let symbol_digits_base = entries["0"].idx;
+    let preinterned_symbols_count = u32::try_from(entries.len()).expect("way too many symbols");
     let output = quote! {
-        const SYMBOL_DIGITS_BASE: u32 = #digits_base;
-        const PREINTERNED_SYMBOLS_COUNT: u32 = #counter;
+        const SYMBOL_DIGITS_BASE: u32 = #symbol_digits_base;
+        const PREINTERNED_SYMBOLS_COUNT: u32 = #preinterned_symbols_count;
 
         #[doc(hidden)]
         #[allow(non_upper_case_globals)]