mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-19 11:35:16 +00:00
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:
parent
588948f267
commit
1fd9520c92
127 changed files with 6733 additions and 7993 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue