1
Fork 0

Avoid a branch on key being local for queries that use the same local and extern providers

This commit is contained in:
bjorn3 2021-05-30 17:24:54 +02:00
parent 56694b0453
commit f5c3e83013
11 changed files with 189 additions and 27 deletions

View file

@ -55,6 +55,9 @@ enum QueryModifier {
/// Always evaluate the query, ignoring its dependencies
EvalAlways(Ident),
/// Use a separate query provider for local and extern crates
SeparateProvideExtern(Ident),
}
impl Parse for QueryModifier {
@ -118,6 +121,8 @@ impl Parse for QueryModifier {
Ok(QueryModifier::Anon(modifier))
} else if modifier == "eval_always" {
Ok(QueryModifier::EvalAlways(modifier))
} else if modifier == "separate_provide_extern" {
Ok(QueryModifier::SeparateProvideExtern(modifier))
} else {
Err(Error::new(modifier.span(), "unknown query modifier"))
}
@ -214,6 +219,9 @@ struct QueryModifiers {
// Always evaluate the query, ignoring its dependencies
eval_always: Option<Ident>,
/// Use a separate query provider for local and extern crates
separate_provide_extern: Option<Ident>,
}
/// Process query modifiers into a struct, erroring on duplicates
@ -227,6 +235,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
let mut no_hash = None;
let mut anon = None;
let mut eval_always = None;
let mut separate_provide_extern = None;
for modifier in query.modifiers.0.drain(..) {
match modifier {
QueryModifier::LoadCached(tcx, id, block) => {
@ -317,6 +326,15 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
}
eval_always = Some(ident);
}
QueryModifier::SeparateProvideExtern(ident) => {
if separate_provide_extern.is_some() {
panic!(
"duplicate modifier `separate_provide_extern` for query `{}`",
query.name
);
}
separate_provide_extern = Some(ident);
}
}
}
let desc = desc.unwrap_or_else(|| {
@ -332,6 +350,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
no_hash,
anon,
eval_always,
separate_provide_extern,
}
}
@ -462,6 +481,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
if let Some(eval_always) = &modifiers.eval_always {
attributes.push(quote! { (#eval_always) });
};
// Pass on the separate_provide_extern modifier
if let Some(separate_provide_extern) = &modifiers.separate_provide_extern {
attributes.push(quote! { (#separate_provide_extern) });
}
// This uses the span of the query definition for the commas,
// which can be important if we later encounter any ambiguity