Skip to content

Commit 5a44f11

Browse files
authored
Unrolled build for #154698
Rollup merge of #154698 - nnethercote:rm-desc-cache-modules-2, r=Zalathar Improve workings of the `desc` query modifier and custom query cycle handlers This PR does two things involving query modifiers. - It changes how the `desc` query modifier is handled, eliminating the generated `_description_fns` module. - It adds a new `handle_cycle_error` query modifier for queries that do custom cycle handling. Details are in the individual commits. r? @Zalathar
2 parents 5bbdeaa + 15c6e6e commit 5a44f11

File tree

8 files changed

+117
-103
lines changed

8 files changed

+117
-103
lines changed

compiler/rustc_macros/src/query.rs

Lines changed: 48 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ impl<T: Parse> Parse for List<T> {
128128
}
129129

130130
struct Desc {
131+
// This ident is always `desc` but we need it for its span, for `crate::query::modifiers`.
131132
modifier: Ident,
132133
expr_list: Punctuated<Expr, Token![,]>,
133134
}
@@ -141,22 +142,26 @@ struct QueryModifiers {
141142
desc: Desc,
142143
eval_always: Option<Ident>,
143144
feedable: Option<Ident>,
145+
handle_cycle_error: Option<Ident>,
144146
no_force: Option<Ident>,
145147
no_hash: Option<Ident>,
146148
separate_provide_extern: Option<Ident>,
147149
// tidy-alphabetical-end
148150
}
149151

150152
fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
153+
// tidy-alphabetical-start
151154
let mut arena_cache = None;
152155
let mut cache_on_disk = None;
156+
let mut depth_limit = None;
153157
let mut desc = None;
158+
let mut eval_always = None;
159+
let mut feedable = None;
160+
let mut handle_cycle_error = None;
154161
let mut no_force = None;
155162
let mut no_hash = None;
156-
let mut eval_always = None;
157-
let mut depth_limit = None;
158163
let mut separate_provide_extern = None;
159-
let mut feedable = None;
164+
// tidy-alphabetical-end
160165

161166
while !input.is_empty() {
162167
let modifier: Ident = input.parse()?;
@@ -170,29 +175,31 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
170175
};
171176
}
172177

173-
if modifier == "desc" {
178+
if modifier == "arena_cache" {
179+
try_insert!(arena_cache = modifier);
180+
} else if modifier == "cache_on_disk" {
181+
try_insert!(cache_on_disk = modifier);
182+
} else if modifier == "depth_limit" {
183+
try_insert!(depth_limit = modifier);
184+
} else if modifier == "desc" {
174185
// Parse a description modifier like:
175186
// `desc { "foo {}", tcx.item_path(key) }`
176187
let attr_content;
177188
braced!(attr_content in input);
178189
let expr_list = attr_content.parse_terminated(Expr::parse, Token![,])?;
179190
try_insert!(desc = Desc { modifier, expr_list });
180-
} else if modifier == "cache_on_disk" {
181-
try_insert!(cache_on_disk = modifier);
182-
} else if modifier == "arena_cache" {
183-
try_insert!(arena_cache = modifier);
191+
} else if modifier == "eval_always" {
192+
try_insert!(eval_always = modifier);
193+
} else if modifier == "feedable" {
194+
try_insert!(feedable = modifier);
195+
} else if modifier == "handle_cycle_error" {
196+
try_insert!(handle_cycle_error = modifier);
184197
} else if modifier == "no_force" {
185198
try_insert!(no_force = modifier);
186199
} else if modifier == "no_hash" {
187200
try_insert!(no_hash = modifier);
188-
} else if modifier == "eval_always" {
189-
try_insert!(eval_always = modifier);
190-
} else if modifier == "depth_limit" {
191-
try_insert!(depth_limit = modifier);
192201
} else if modifier == "separate_provide_extern" {
193202
try_insert!(separate_provide_extern = modifier);
194-
} else if modifier == "feedable" {
195-
try_insert!(feedable = modifier);
196203
} else {
197204
return Err(Error::new(modifier.span(), "unknown query modifier"));
198205
}
@@ -201,15 +208,18 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
201208
return Err(input.error("no description provided"));
202209
};
203210
Ok(QueryModifiers {
211+
// tidy-alphabetical-start
204212
arena_cache,
205213
cache_on_disk,
214+
depth_limit,
206215
desc,
216+
eval_always,
217+
feedable,
218+
handle_cycle_error,
207219
no_force,
208220
no_hash,
209-
eval_always,
210-
depth_limit,
211221
separate_provide_extern,
212-
feedable,
222+
// tidy-alphabetical-end
213223
})
214224
}
215225

@@ -238,24 +248,40 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
238248
arena_cache,
239249
cache_on_disk,
240250
depth_limit,
241-
desc: _,
251+
desc,
242252
eval_always,
243253
feedable,
254+
handle_cycle_error,
244255
no_force,
245256
no_hash,
246257
separate_provide_extern,
247258
// tidy-alphabetical-end
248259
} = &query.modifiers;
249260

261+
// tidy-alphabetical-start
250262
let arena_cache = arena_cache.is_some();
251263
let cache_on_disk = cache_on_disk.is_some();
252264
let depth_limit = depth_limit.is_some();
265+
let desc = {
266+
// Put a description closure in the `desc` modifier.
267+
let key_pat = &query.key_pat;
268+
let key_ty = &query.key_ty;
269+
let desc_expr_list = &desc.expr_list;
270+
quote! {
271+
{
272+
#[allow(unused_variables)]
273+
|tcx: TyCtxt<'tcx>, #key_pat: #key_ty| format!(#desc_expr_list)
274+
}
275+
}
276+
};
253277
let eval_always = eval_always.is_some();
254278
let feedable = feedable.is_some();
279+
let handle_cycle_error = handle_cycle_error.is_some();
255280
let no_force = no_force.is_some();
256281
let no_hash = no_hash.is_some();
257282
let returns_error_guaranteed = returns_error_guaranteed(&query.return_ty);
258283
let separate_provide_extern = separate_provide_extern.is_some();
284+
// tidy-alphabetical-end
259285

260286
// Giving an input span to the modifier names in the modifier list seems
261287
// to give slightly more helpful errors when one of the callback macros
@@ -268,8 +294,10 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
268294
arena_cache: #arena_cache,
269295
cache_on_disk: #cache_on_disk,
270296
depth_limit: #depth_limit,
297+
desc: #desc,
271298
eval_always: #eval_always,
272299
feedable: #feedable,
300+
handle_cycle_error: #handle_cycle_error,
273301
no_force: #no_force,
274302
no_hash: #no_hash,
275303
returns_error_guaranteed: #returns_error_guaranteed,
@@ -305,37 +333,6 @@ fn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attrib
305333
Ok(parse_quote! { #[doc = #doc_string] })
306334
}
307335

308-
/// Contains token streams that are used to accumulate per-query helper
309-
/// functions, to be used by the final output of `rustc_queries!`.
310-
///
311-
/// Helper items typically have the same name as the query they relate to,
312-
/// and expect to be interpolated into a dedicated module.
313-
#[derive(Default)]
314-
struct HelperTokenStreams {
315-
description_fns_stream: proc_macro2::TokenStream,
316-
}
317-
318-
fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) {
319-
let Query { name, key_pat, key_ty, modifiers, .. } = &query;
320-
321-
// Replace span for `name` to make rust-analyzer ignore it.
322-
let mut erased_name = name.clone();
323-
erased_name.set_span(Span::call_site());
324-
325-
let Desc { expr_list, .. } = &modifiers.desc;
326-
327-
let desc = quote! {
328-
#[allow(unused_variables)]
329-
pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: #key_ty) -> String {
330-
format!(#expr_list)
331-
}
332-
};
333-
334-
streams.description_fns_stream.extend(quote! {
335-
#desc
336-
});
337-
}
338-
339336
/// Add hints for rust-analyzer
340337
fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::TokenStream) {
341338
// Add links to relevant modifiers
@@ -366,8 +363,10 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke
366363
arena_cache,
367364
cache_on_disk,
368365
depth_limit,
366+
// `desc` is handled above
369367
eval_always,
370368
feedable,
369+
handle_cycle_error,
371370
no_force,
372371
no_hash,
373372
separate_provide_extern,
@@ -409,7 +408,6 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
409408

410409
let mut query_stream = quote! {};
411410
let mut non_query_stream = quote! {};
412-
let mut helpers = HelperTokenStreams::default();
413411
let mut analyzer_stream = quote! {};
414412
let mut errors = quote! {};
415413

@@ -462,11 +460,8 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
462460
}
463461

464462
add_to_analyzer_stream(&query, &mut analyzer_stream);
465-
make_helpers_for_query(&query, &mut helpers);
466463
}
467464

468-
let HelperTokenStreams { description_fns_stream } = helpers;
469-
470465
TokenStream::from(quote! {
471466
/// Higher-order macro that invokes the specified macro with (a) a list of all query
472467
/// signatures (including modifiers), and (b) a list of non-query names. This allows
@@ -490,17 +485,6 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
490485
#analyzer_stream
491486
}
492487

493-
/// Functions that format a human-readable description of each query
494-
/// and its key, as specified by the `desc` query modifier.
495-
///
496-
/// (The leading `_` avoids collisions with actual query names when
497-
/// expanded in `rustc_middle::queries`, and makes this macro-generated
498-
/// module easier to search for.)
499-
pub mod _description_fns {
500-
use super::*;
501-
#description_fns_stream
502-
}
503-
504488
#errors
505489
})
506490
}

compiler/rustc_middle/src/queries.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ rustc_queries! {
583583
// messages about cycles that then abort.)
584584
query check_representability(key: LocalDefId) {
585585
desc { "checking if `{}` is representable", tcx.def_path_str(key) }
586+
handle_cycle_error
586587
// We don't want recursive representability calls to be forced with
587588
// incremental compilation because, if a cycle occurs, we need the
588589
// entire cycle to be in memory for diagnostics.
@@ -593,6 +594,7 @@ rustc_queries! {
593594
/// details, particularly on the modifiers.
594595
query check_representability_adt_ty(key: Ty<'tcx>) {
595596
desc { "checking if `{}` is representable", key }
597+
handle_cycle_error
596598
no_force
597599
}
598600

@@ -1032,6 +1034,7 @@ rustc_queries! {
10321034
query variances_of(def_id: DefId) -> &'tcx [ty::Variance] {
10331035
desc { "computing the variances of `{}`", tcx.def_path_str(def_id) }
10341036
cache_on_disk
1037+
handle_cycle_error
10351038
separate_provide_extern
10361039
}
10371040

@@ -1164,6 +1167,7 @@ rustc_queries! {
11641167
query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
11651168
desc { "computing function signature of `{}`", tcx.def_path_str(key) }
11661169
cache_on_disk
1170+
handle_cycle_error
11671171
separate_provide_extern
11681172
}
11691173

@@ -1756,6 +1760,7 @@ rustc_queries! {
17561760
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
17571761
depth_limit
17581762
desc { "computing layout of `{}`", key.value }
1763+
handle_cycle_error
17591764
}
17601765

17611766
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.

compiler/rustc_middle/src/query/modifiers.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ pub(crate) struct eval_always;
5858
/// Generate a `feed` method to set the query's value from another query.
5959
pub(crate) struct feedable;
6060

61+
/// # `handle_cycle_error` query modifier
62+
///
63+
/// The default behaviour for a query cycle is to emit a cycle error and halt
64+
/// compilation. Queries with this modifier will instead use a custom handler,
65+
/// which must be provided at `rustc_query_impl::handle_cycle_error::$name`,
66+
/// where `$name` is the query name.
67+
pub(crate) struct handle_cycle_error;
68+
6169
/// # `no_force` query modifier
6270
///
6371
/// Dep nodes of queries with this modifier will never be "forced" when trying

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,10 @@ macro_rules! define_callbacks {
301301
arena_cache: $arena_cache:literal,
302302
cache_on_disk: $cache_on_disk:literal,
303303
depth_limit: $depth_limit:literal,
304+
desc: $desc:expr,
304305
eval_always: $eval_always:literal,
305306
feedable: $feedable:literal,
307+
handle_cycle_error: $handle_cycle_error:literal,
306308
no_force: $no_force:literal,
307309
no_hash: $no_hash:literal,
308310
returns_error_guaranteed: $returns_error_guaranteed:literal,
@@ -435,8 +437,7 @@ macro_rules! define_callbacks {
435437
pub fn description(&self, tcx: TyCtxt<'tcx>) -> String {
436438
let (name, description) = ty::print::with_no_queries!(match self {
437439
$(
438-
TaggedQueryKey::$name(key) =>
439-
(stringify!($name), _description_fns::$name(tcx, *key)),
440+
TaggedQueryKey::$name(key) => (stringify!($name), ($desc)(tcx, *key)),
440441
)*
441442
});
442443
if tcx.sess.verbose_internals() {

compiler/rustc_query_impl/src/dep_kind_vtables.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ macro_rules! define_dep_kind_vtables {
135135
arena_cache: $arena_cache:literal,
136136
cache_on_disk: $cache_on_disk:literal,
137137
depth_limit: $depth_limit:literal,
138+
desc: $desc:expr,
138139
eval_always: $eval_always:literal,
139140
feedable: $feedable:literal,
141+
handle_cycle_error: $handle_cycle_error:literal,
140142
no_force: $no_force:literal,
141143
no_hash: $no_hash:literal,
142144
returns_error_guaranteed: $returns_error_guaranteed:literal,

0 commit comments

Comments
 (0)