276: Keep parameter names of queries in `query_group` attribute r=nikomatsakis a=Veykril

Now that RA gets to a point where it can expand attributes it would be helpful not to discard parameter names.
Before:
![Code_1XD5LiRfJw](https://user-images.githubusercontent.com/3757771/123661119-9420ab00-d834-11eb-8d59-296533e0a96e.png)
After:
![Code_kwRhvPySuL](https://user-images.githubusercontent.com/3757771/123661116-93881480-d834-11eb-88e4-b8e4dbf2be52.png)


Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-08-24 19:51:37 +00:00 committed by GitHub
commit 114d6db8f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -37,14 +37,13 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
let mut queries = vec![];
for item in input.items {
if let TraitItem::Method(method) = item {
let query_name = method.sig.ident.to_string();
let mut storage = QueryStorage::Memoized;
let mut cycle = None;
let mut invoke = None;
let query_name = method.sig.ident.to_string();
let mut query_type = Ident::new(
&format!("{}Query", method.sig.ident.to_string().to_camel_case()),
Span::call_site(),
);
let mut query_type = format_ident!("{}Query", query_name.to_string().to_camel_case());
let mut num_storages = 0;
// Extract attributes.
@ -88,9 +87,10 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
}
}
let sig_span = method.sig.span();
// Check attribute combinations.
if num_storages > 1 {
return Error::new(method.sig.span(), "multiple storage attributes specified")
return Error::new(sig_span, "multiple storage attributes specified")
.to_compile_error()
.into();
}
@ -112,26 +112,27 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
Some(FnArg::Receiver(sr)) if sr.mutability.is_none() => (),
_ => {
return Error::new(
method.sig.span(),
format!(
"first argument of query `{}` must be `&self`",
method.sig.ident,
),
sig_span,
format!("first argument of query `{}` must be `&self`", query_name),
)
.to_compile_error()
.into();
}
}
let mut keys: Vec<Type> = vec![];
for arg in iter {
match *arg {
FnArg::Typed(ref arg) => {
keys.push((*arg.ty).clone());
}
ref arg => {
let mut keys: Vec<(Ident, Type)> = vec![];
for (idx, arg) in iter.enumerate() {
match arg {
FnArg::Typed(syn::PatType { pat, ty, .. }) => keys.push((
match pat.as_ref() {
syn::Pat::Ident(ident_pat) => ident_pat.ident.clone(),
_ => format_ident!("key{}", idx),
},
Type::clone(ty),
)),
arg => {
return Error::new(
arg.span(),
format!("unsupported argument `{:?}` of `{}`", arg, method.sig.ident,),
format!("unsupported argument `{:?}` of `{}`", arg, query_name,),
)
.to_compile_error()
.into();
@ -145,10 +146,7 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
ref ret => {
return Error::new(
ret.span(),
format!(
"unsupported return type `{:?}` of `{}`",
ret, method.sig.ident
),
format!("unsupported return type `{:?}` of `{}`", ret, query_name),
)
.to_compile_error()
.into();
@ -165,23 +163,15 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
//
// fn lookup_foo(&self, x: u32) -> (Key1, Key2)
let lookup_query = if let QueryStorage::Interned = storage {
let lookup_query_type = Ident::new(
&format!(
"{}LookupQuery",
method.sig.ident.to_string().to_camel_case()
),
Span::call_site(),
);
let lookup_fn_name = Ident::new(
&format!("lookup_{}", method.sig.ident.to_string()),
method.sig.ident.span(),
);
let keys = &keys;
let lookup_query_type =
format_ident!("{}LookupQuery", query_name.to_string().to_camel_case());
let lookup_fn_name = format_ident!("lookup_{}", query_name);
let keys = keys.iter().map(|(_, ty)| ty);
let lookup_value: Type = parse_quote!((#(#keys),*));
let lookup_keys = vec![value.clone()];
let lookup_keys = vec![(parse_quote! { key }, value.clone())];
Some(Query {
query_type: lookup_query_type,
query_name: format!("lookup_{}", query_name),
query_name: format!("{}", lookup_fn_name),
fn_name: lookup_fn_name,
attrs: vec![], // FIXME -- some automatically generated docs on this method?
storage: QueryStorage::InternedLookup {
@ -212,20 +202,15 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
}
}
let group_storage = Ident::new(
&format!("{}GroupStorage__", trait_name.to_string()),
Span::call_site(),
);
let group_storage = format_ident!("{}GroupStorage__", trait_name, span = Span::call_site());
let mut query_fn_declarations = proc_macro2::TokenStream::new();
let mut query_fn_definitions = proc_macro2::TokenStream::new();
let mut storage_fields = proc_macro2::TokenStream::new();
let mut queries_with_storage = vec![];
for query in &queries {
let key_names: &Vec<_> = &(0..query.keys.len())
.map(|i| Ident::new(&format!("key{}", i), Span::call_site()))
.collect();
let keys = &query.keys;
let (key_names, keys): (Vec<_>, Vec<_>) =
query.keys.iter().map(|(pat, ty)| (pat, ty)).unzip();
let value = &query.value;
let fn_name = &query.fn_name;
let qt = &query.query_type;
@ -266,9 +251,8 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
// For input queries, we need `set_foo` etc
if let QueryStorage::Input = query.storage {
let set_fn_name = Ident::new(&format!("set_{}", fn_name), fn_name.span());
let set_with_durability_fn_name =
Ident::new(&format!("set_{}_with_durability", fn_name), fn_name.span());
let set_fn_name = format_ident!("set_{}", fn_name);
let set_with_durability_fn_name = format_ident!("set_{}_with_durability", fn_name);
let set_fn_docs = format!(
"
@ -396,7 +380,7 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
}
QueryStorage::Transparent => panic!("should have been filtered"),
};
let keys = &query.keys;
let keys = query.keys.iter().map(|(_, ty)| ty);
let value = &query.value;
let query_name = &query.query_name;
@ -489,9 +473,8 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
// Implement the QueryFunction trait for queries which need it.
if query.storage.needs_query_function() {
let span = query.fn_name.span();
let key_names: &Vec<_> = &(0..query.keys.len())
.map(|i| Ident::new(&format!("key{}", i), Span::call_site()))
.collect();
let key_names: Vec<_> = query.keys.iter().map(|(pat, _)| pat).collect();
let key_pattern = if query.keys.len() == 1 {
quote! { #(#key_names),* }
} else {
@ -683,7 +666,7 @@ struct Query {
attrs: Vec<syn::Attribute>,
query_type: Ident,
storage: QueryStorage,
keys: Vec<syn::Type>,
keys: Vec<(Ident, syn::Type)>,
value: syn::Type,
invoke: Option<syn::Path>,
cycle: Option<syn::Path>,