/// Always remap the ParamEnv's constness before hashing.
remap_env_constness: Option<Ident>,
+
+ /// Generate a `feed` method to set the query's value from another query.
+ feedable: Option<Ident>,
}
fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
let mut depth_limit = None;
let mut separate_provide_extern = None;
let mut remap_env_constness = None;
+ let mut feedable = None;
while !input.is_empty() {
let modifier: Ident = input.parse()?;
try_insert!(separate_provide_extern = modifier);
} else if modifier == "remap_env_constness" {
try_insert!(remap_env_constness = modifier);
+ } else if modifier == "feedable" {
+ try_insert!(feedable = modifier);
} else {
return Err(Error::new(modifier.span(), "unknown query modifier"));
}
depth_limit,
separate_provide_extern,
remap_env_constness,
+ feedable,
})
}
.unwrap();
},
);
- let doc_string = format!("[query description - consider adding a doc-comment!] {}", doc_string);
+ let doc_string = format!("[query description - consider adding a doc-comment!] {doc_string}");
Ok(parse_quote! { #[doc = #doc_string] })
}
let mut query_stream = quote! {};
let mut query_description_stream = quote! {};
let mut query_cached_stream = quote! {};
+ let mut feedable_queries = quote! {};
for query in queries.0 {
let Query { name, arg, modifiers, .. } = &query;
[#attribute_stream] fn #name(#arg) #result,
});
+ if modifiers.feedable.is_some() {
+ assert!(modifiers.anon.is_none(), "Query {name} cannot be both `feedable` and `anon`.");
+ assert!(
+ modifiers.eval_always.is_none(),
+ "Query {name} cannot be both `feedable` and `eval_always`."
+ );
+ feedable_queries.extend(quote! {
+ #(#doc_comments)*
+ [#attribute_stream] fn #name(#arg) #result,
+ });
+ }
+
add_query_desc_cached_impl(&query, &mut query_description_stream, &mut query_cached_stream);
}
}
}
}
-
+ macro_rules! rustc_feedable_queries {
+ ( $macro:ident! ) => {
+ $macro!(#feedable_queries);
+ }
+ }
pub mod descs {
use super::*;
#query_description_stream