refactor: Introduce CacheKey trait (#3323)

This PR introduces a new `CacheKey` trait for types that can be used as a cache key.

I'm not entirely sure if this is worth the "overhead", but I was surprised to find `HashableHashSet` and got scared when I looked at the time complexity of the `hash` function. These implementations must be extremely slow in hashed collections.

I then searched for usages and quickly realized that only the cache uses these `Hash` implementations, where performance is less sensitive.

This PR introduces a new `CacheKey` trait to communicate the difference between a hash and computing a key for the cache. The new trait can be implemented for types that don't implement `Hash` for performance reasons, and we can define additional constraints on the implementation:  For example, we'll want to enforce portability when we add remote caching support. Using a different trait further allows us not to implement it for types without stable identities (e.g. pointers) or use other implementations than the standard hash function.
This commit is contained in:
Micha Reiser 2023-03-03 19:29:49 +01:00 committed by GitHub
parent d1288dc2b1
commit cdbe2ee496
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 842 additions and 331 deletions

View file

@ -1,8 +1,10 @@
//! This crate implements internal macros for the `ruff` library.
use crate::cache_key::derive_cache_key;
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput, ItemFn};
mod cache_key;
mod config;
mod define_violation;
mod derive_message_formats;
@ -20,6 +22,16 @@ pub fn derive_config(input: proc_macro::TokenStream) -> proc_macro::TokenStream
.into()
}
#[proc_macro_derive(CacheKey)]
pub fn cache_key(input: TokenStream) -> TokenStream {
let item = parse_macro_input!(input as DeriveInput);
let result = derive_cache_key(&item);
let stream = result.unwrap_or_else(|err| err.to_compile_error());
TokenStream::from(stream)
}
#[proc_macro]
pub fn register_rules(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
let mapping = parse_macro_input!(item as register_rules::Input);