mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Delete counter from symbols proc macro in favor of hashmap as source of truth
This commit is contained in:
parent
95742ff23c
commit
8dea49ad7b
@ -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)]
|
||||
|
Loading…
Reference in New Issue
Block a user