refactor: Lower type-refs before type inference

This refactors how we deal with items in hir-def lowering.

- It now lowers all of them through an "ExpressionStore" (kind of a misnomer as this point) as their so called *Signatures.
- We now uniformly lower type AST into TypeRefs before type inference.
- Likewise, this moves macro expansion out of type inference, resulting in a single place where we do non-defmap macro expansion.
- Finally, this PR removes a lot of information from ItemTree, making the DefMap a lot less likely to be recomputed and have it only depend on actual early name resolution related information (not 100% true, we still have ADT fields in there but thats a follow up removal).
This commit is contained in:
Lukas Wirth 2025-01-25 17:20:10 +01:00
parent 588948f267
commit 1fd9520c92
127 changed files with 6733 additions and 7993 deletions

View file

@ -12,7 +12,9 @@ use queries::{
use quote::{ToTokens, format_ident, quote};
use syn::spanned::Spanned;
use syn::visit_mut::VisitMut;
use syn::{Attribute, FnArg, ItemTrait, Path, TraitItem, TraitItemFn, parse_quote};
use syn::{
Attribute, FnArg, ItemTrait, Path, TraitItem, TraitItemFn, parse_quote, parse_quote_spanned,
};
mod queries;
@ -127,12 +129,12 @@ pub(crate) fn query_group_impl(
let mut lookup_signatures = vec![];
let mut lookup_methods = vec![];
for item in item_trait.clone().items {
for item in &mut item_trait.items {
if let syn::TraitItem::Fn(method) = item {
let method_name = &method.sig.ident;
let signature = &method.sig.clone();
let signature = &method.sig;
let (_attrs, salsa_attrs) = filter_attrs(method.attrs);
let (_attrs, salsa_attrs) = filter_attrs(method.attrs.clone());
let mut query_kind = QueryKind::Tracked;
let mut invoke = None;
@ -190,6 +192,9 @@ pub(crate) fn query_group_impl(
invoke = Some(path.0.clone());
query_kind = QueryKind::TrackedWithSalsaStruct;
}
"tracked" if method.default.is_some() => {
query_kind = QueryKind::TrackedWithSalsaStruct;
}
"lru" => {
let lru_count = syn::parse::<Parenthesized<syn::LitInt>>(tts)?;
let lru_count = lru_count.0.base10_parse::<u32>()?;
@ -218,6 +223,10 @@ pub(crate) fn query_group_impl(
}
}
if let Some(block) = &mut method.default {
SelfToDbRewriter.visit_block_mut(block);
}
match (query_kind, invoke) {
// input
(QueryKind::Input, None) => {
@ -277,31 +286,35 @@ pub(crate) fn query_group_impl(
invoke,
cycle,
lru,
default: method.default.take(),
};
trait_methods.push(Queries::TrackedQuery(method));
}
(QueryKind::TrackedWithSalsaStruct, Some(invoke)) => {
(QueryKind::TrackedWithSalsaStruct, invoke) => {
// while it is possible to make this reachable, it's not really worthwhile for a migration aid.
// doing this would require attaching an attribute to the salsa struct parameter
// in the query.
assert_ne!(invoke.is_none(), method.default.is_none());
let method = TrackedQuery {
trait_name: trait_name_ident.clone(),
generated_struct: None,
signature: signature.clone(),
pat_and_tys: pat_and_tys.clone(),
invoke: Some(invoke),
invoke,
cycle,
lru,
default: method.default.take(),
};
trait_methods.push(Queries::TrackedQuery(method))
}
// while it is possible to make this reachable, it's not really worthwhile for a migration aid.
// doing this would require attaching an attribute to the salsa struct parameter in the query.
(QueryKind::TrackedWithSalsaStruct, None) => unreachable!(),
(QueryKind::Transparent, invoke) => {
let method = Transparent {
signature: method.sig.clone(),
pat_and_tys: pat_and_tys.clone(),
invoke,
default: method.default.take(),
};
trait_methods.push(Queries::Transparent(method));
}
@ -435,3 +448,13 @@ pub(crate) fn token_stream_with_error(mut tokens: TokenStream, error: syn::Error
tokens.extend(TokenStream::from(error.into_compile_error()));
tokens
}
struct SelfToDbRewriter;
impl VisitMut for SelfToDbRewriter {
fn visit_expr_path_mut(&mut self, i: &mut syn::ExprPath) {
if i.path.is_ident("self") {
i.path = parse_quote_spanned!(i.path.span() => db);
}
}
}

View file

@ -1,13 +1,14 @@
//! The IR of the `#[query_group]` macro.
use quote::{ToTokens, format_ident, quote};
use syn::{FnArg, Ident, PatType, Path, Receiver, ReturnType, Type, parse_quote};
use quote::{ToTokens, format_ident, quote, quote_spanned};
use syn::{FnArg, Ident, PatType, Path, Receiver, ReturnType, Type, parse_quote, spanned::Spanned};
pub(crate) struct TrackedQuery {
pub(crate) trait_name: Ident,
pub(crate) signature: syn::Signature,
pub(crate) pat_and_tys: Vec<PatType>,
pub(crate) invoke: Option<Path>,
pub(crate) default: Option<syn::Block>,
pub(crate) cycle: Option<Path>,
pub(crate) lru: Option<u32>,
pub(crate) generated_struct: Option<GeneratedInputStruct>,
@ -47,6 +48,14 @@ impl ToTokens for TrackedQuery {
.map(|pat_type| pat_type.pat.clone())
.collect::<Vec<Box<syn::Pat>>>();
let invoke_block = match &self.default {
Some(default) => quote! { #default },
None => {
let invoke_params: proc_macro2::TokenStream = quote! {db, #(#params),*};
quote_spanned! { invoke.span() => {#invoke(#invoke_params)}}
}
};
let method = match &self.generated_struct {
Some(generated_struct) => {
let input_struct_name = &generated_struct.input_struct_name;
@ -59,9 +68,8 @@ impl ToTokens for TrackedQuery {
db: &dyn #trait_name,
_input: #input_struct_name,
#(#pat_and_tys),*
) #ret {
#invoke(db, #(#params),*)
}
) #ret
#invoke_block
#shim(self, #create_data_ident(self), #(#params),*)
}
}
@ -73,9 +81,9 @@ impl ToTokens for TrackedQuery {
fn #shim(
db: &dyn #trait_name,
#(#pat_and_tys),*
) #ret {
#invoke(db, #(#params),*)
}
) #ret
#invoke_block
#shim(self, #(#params),*)
}
}
@ -216,6 +224,7 @@ pub(crate) struct Transparent {
pub(crate) signature: syn::Signature,
pub(crate) pat_and_tys: Vec<PatType>,
pub(crate) invoke: Option<Path>,
pub(crate) default: Option<syn::Block>,
}
impl ToTokens for Transparent {
@ -233,10 +242,15 @@ impl ToTokens for Transparent {
None => sig.ident.to_token_stream(),
};
let method = quote! {
#sig {
#invoke(self, #(#ty),*)
}
let method = match &self.default {
Some(default) => quote! {
#sig { let db = self; #default }
},
None => quote! {
#sig {
#invoke(self, #(#ty),*)
}
},
};
method.to_tokens(tokens);