Skip to content

Commit ba86d8a

Browse files
committed
Make rustc_with_all_queries! pass query modifiers as named values
1 parent b730a84 commit ba86d8a

7 files changed

Lines changed: 258 additions & 338 deletions

File tree

compiler/rustc_macros/src/query.rs

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use proc_macro::TokenStream;
22
use proc_macro2::Span;
3-
use quote::{quote, quote_spanned};
3+
use quote::quote;
44
use syn::parse::{Parse, ParseStream, Result};
55
use syn::punctuated::Punctuated;
66
use syn::spanned::Spanned;
@@ -315,51 +315,13 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
315315
ReturnType::Type(..) => quote! { #return_ty },
316316
};
317317

318-
let mut modifiers_out = vec![];
319-
320-
macro_rules! passthrough {
321-
( $( $modifier:ident ),+ $(,)? ) => {
322-
$( if let Some($modifier) = &modifiers.$modifier {
323-
modifiers_out.push(quote! { (#$modifier) });
324-
}; )+
325-
}
326-
}
327-
328-
passthrough!(
329-
arena_cache,
330-
cycle_fatal,
331-
cycle_delay_bug,
332-
cycle_stash,
333-
no_hash,
334-
anon,
335-
eval_always,
336-
feedable,
337-
depth_limit,
338-
separate_provide_extern,
339-
return_result_from_ensure_ok,
340-
);
341-
342-
// If there was a `cache_on_disk_if` modifier in the real input, pass
343-
// on a synthetic `(cache_on_disk)` modifier that can be inspected by
344-
// macro-rules macros.
345-
if modifiers.cache_on_disk_if.is_some() {
346-
modifiers_out.push(quote! { (cache_on_disk) });
347-
}
348-
349-
// This uses the span of the query definition for the commas,
350-
// which can be important if we later encounter any ambiguity
351-
// errors with any of the numerous macro_rules! macros that
352-
// we use. Using the call-site span would result in a span pointing
353-
// at the entire `rustc_queries!` invocation, which wouldn't
354-
// be very useful.
355-
let span = name.span();
356-
let modifiers_stream = quote_spanned! { span => #(#modifiers_out),* };
318+
let modifiers_stream = modifiers::make_modifiers_stream(&query, modifiers);
357319

358320
// Add the query to the group
359321
query_stream.extend(quote! {
360322
#(#doc_comments)*
361-
[#modifiers_stream]
362-
fn #name(#key_ty) #return_ty,
323+
fn #name(#key_ty) #return_ty
324+
{ #modifiers_stream }
363325
});
364326

365327
if let Some(feedable) = &modifiers.feedable {

compiler/rustc_macros/src/query/modifiers.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use quote::{quote, quote_spanned};
12
use syn::parse::{Parse, ParseStream, Result};
23
use syn::punctuated::Punctuated;
34
use syn::{Block, Error, Expr, Ident, Token, braced};
45

6+
use crate::query::Query;
7+
58
pub(crate) struct Desc {
69
pub(crate) modifier: Ident,
710
pub(crate) expr_list: Punctuated<Expr, Token![,]>,
@@ -115,3 +118,68 @@ pub(crate) fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModif
115118
return_result_from_ensure_ok,
116119
})
117120
}
121+
122+
pub(crate) fn make_modifiers_stream(
123+
query: &Query,
124+
modifiers: &QueryModifiers,
125+
) -> proc_macro2::TokenStream {
126+
let QueryModifiers {
127+
// tidy-alphabetical-start
128+
anon,
129+
arena_cache,
130+
cache_on_disk_if,
131+
cycle_delay_bug,
132+
cycle_fatal,
133+
cycle_stash,
134+
depth_limit,
135+
desc: _,
136+
eval_always,
137+
feedable,
138+
no_hash,
139+
return_result_from_ensure_ok,
140+
separate_provide_extern,
141+
// tidy-alphabetical-end
142+
} = modifiers;
143+
144+
let is_anon = anon.is_some();
145+
let is_arena_cache = arena_cache.is_some();
146+
let is_cache_on_disk = cache_on_disk_if.is_some();
147+
148+
let cycle_error_handling = if cycle_delay_bug.is_some() {
149+
quote! { DelayBug }
150+
} else if cycle_fatal.is_some() {
151+
quote! { Fatal }
152+
} else if cycle_stash.is_some() {
153+
quote! { Stash }
154+
} else {
155+
quote! { Error }
156+
};
157+
158+
let is_depth_limit = depth_limit.is_some();
159+
let is_eval_always = eval_always.is_some();
160+
let is_feedable = feedable.is_some();
161+
let is_no_hash = no_hash.is_some();
162+
let is_return_result_from_ensure_ok = return_result_from_ensure_ok.is_some();
163+
let is_separate_provide_extern = separate_provide_extern.is_some();
164+
165+
// Giving an input span to the modifier names in the modifier list seems
166+
// to give slightly more helpful errors when one of the callback macros
167+
// fails to parse the modifier list.
168+
let query_name_span = query.name.span();
169+
quote_spanned! {
170+
query_name_span =>
171+
// Search for (QMODLIST) to find all occurrences of this query modifier list.
172+
// tidy-alphabetical-start
173+
anon: #is_anon,
174+
arena_cache: #is_arena_cache,
175+
cache_on_disk: #is_cache_on_disk,
176+
cycle_error_handling: #cycle_error_handling,
177+
depth_limit: #is_depth_limit,
178+
eval_always: #is_eval_always,
179+
feedable: #is_feedable,
180+
no_hash: #is_no_hash,
181+
return_result_from_ensure_ok: #is_return_result_from_ensure_ok,
182+
separate_provide_extern: #is_separate_provide_extern,
183+
// tidy-alphabetical-end
184+
}
185+
}

compiler/rustc_middle/src/dep_graph/dep_node.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,10 @@ macro_rules! define_dep_nodes {
268268
queries {
269269
$(
270270
$(#[$q_attr:meta])*
271-
[$($modifiers:tt)*]
272-
fn $q_name:ident($K:ty) -> $V:ty,
271+
fn $q_name:ident($K:ty) -> $V:ty
272+
// Search for (QMODLIST) to find all occurrences of this query modifier list.
273+
// Query modifiers are currently not used here, so skip the whole list.
274+
{ $($modifiers:tt)* }
273275
)*
274276
}
275277
non_queries {

compiler/rustc_middle/src/query/inner.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Helper functions that serve as the immediate implementation of
22
//! `tcx.$query(..)` and its variations.
33
4-
use rustc_data_structures::assert_matches;
54
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
65

76
use crate::dep_graph;
@@ -71,19 +70,15 @@ pub(crate) fn query_ensure_error_guaranteed<'tcx, C, T>(
7170
tcx: TyCtxt<'tcx>,
7271
query: &'tcx QueryVTable<'tcx, C>,
7372
key: C::Key,
74-
// This arg is needed to match the signature of `query_ensure`,
75-
// but should always be `EnsureMode::Ok`.
76-
ensure_mode: EnsureMode,
7773
) -> Result<(), ErrorGuaranteed>
7874
where
7975
C: QueryCache<Value = Erased<Result<T, ErrorGuaranteed>>>,
8076
Result<T, ErrorGuaranteed>: Erasable,
8177
{
82-
assert_matches!(ensure_mode, EnsureMode::Ok);
83-
8478
if let Some(res) = try_get_cached(tcx, &query.cache, &key) {
8579
erase::restore_val(res).map(drop)
8680
} else {
81+
let ensure_mode = EnsureMode::Ok;
8782
(query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Ensure { ensure_mode })
8883
.map(erase::restore_val)
8984
.map(|res| res.map(drop))

0 commit comments

Comments
 (0)