Skip to content

Commit 6d7ea71

Browse files
authored
Rollup merge of rust-lang#153760 - Zalathar:query-impl, r=nnethercote
Move and expand the big `rustc_query_impl` macro into a physical `query_impl.rs` While looking through rust-lang#153588, I came up with a related but different change that I think resolves a lot of tension in the current module arrangement. The core idea is that if we both define and expand the big macro in the same physical module `rustc_query_impl::query_impl`, then we no longer need to worry about where `mod query_impl` should be declared, or where its imports should go, because those questions now have simple and obvious answers. The second commit follows up with some more changes inspired by rust-lang#153588. Those particular follow-ups are not essential to the main idea of this PR. r? nnethercote
2 parents 3c57d7a + 69ea0c5 commit 6d7ea71

5 files changed

Lines changed: 284 additions & 272 deletions

File tree

compiler/rustc_query_impl/src/execution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use rustc_span::{DUMMY_SP, Span};
1818
use tracing::warn;
1919

2020
use crate::dep_graph::{DepNode, DepNodeIndex};
21-
use crate::for_each_query_vtable;
2221
use crate::job::{QueryJobInfo, QueryJobMap, find_cycle_in_stack, report_cycle};
2322
use crate::plumbing::{current_query_job, next_job_id, start_query};
23+
use crate::query_impl::for_each_query_vtable;
2424

2525
#[inline]
2626
fn equivalent_key<K: Eq, V>(k: K) -> impl Fn(&(K, V)) -> bool {

compiler/rustc_query_impl/src/lib.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,24 @@
1010

1111
use rustc_data_structures::sync::AtomicU64;
1212
use rustc_middle::dep_graph;
13-
use rustc_middle::queries::{self, ExternProviders, Providers, TaggedQueryKey};
13+
use rustc_middle::queries::{ExternProviders, Providers};
14+
use rustc_middle::query::QueryCache;
1415
use rustc_middle::query::on_disk_cache::OnDiskCache;
1516
use rustc_middle::query::plumbing::{QuerySystem, QueryVTable};
16-
use rustc_middle::query::{AsLocalQueryKey, QueryCache, QueryMode};
1717
use rustc_middle::ty::TyCtxt;
18-
use rustc_span::Span;
1918

2019
pub use crate::dep_kind_vtables::make_dep_kind_vtables;
2120
pub use crate::execution::{CollectActiveJobsKind, collect_active_jobs_from_all_queries};
2221
pub use crate::job::{QueryJobMap, break_query_cycles, print_query_stack};
2322

24-
#[macro_use]
25-
mod plumbing;
26-
2723
mod dep_kind_vtables;
2824
mod error;
2925
mod execution;
3026
mod from_cycle_error;
3127
mod job;
28+
mod plumbing;
3229
mod profiling_support;
30+
mod query_impl;
3331

3432
/// Trait that knows how to look up the [`QueryVTable`] for a particular query.
3533
///
@@ -51,7 +49,7 @@ pub fn query_system<'tcx>(
5149
on_disk_cache: Option<OnDiskCache>,
5250
incremental: bool,
5351
) -> QuerySystem<'tcx> {
54-
let mut query_vtables = make_query_vtables(incremental);
52+
let mut query_vtables = query_impl::make_query_vtables(incremental);
5553
from_cycle_error::specialize_query_vtables(&mut query_vtables);
5654
QuerySystem {
5755
arenas: Default::default(),
@@ -63,8 +61,6 @@ pub fn query_system<'tcx>(
6361
}
6462
}
6563

66-
rustc_middle::rustc_with_all_queries! { define_queries! }
67-
6864
pub fn provide(providers: &mut rustc_middle::util::Providers) {
6965
providers.hooks.alloc_self_profile_query_strings =
7066
profiling_support::alloc_self_profile_query_strings;

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 2 additions & 261 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
//! The implementation of the query system itself. This defines the macros that
2-
//! generate the actual methods on tcx which find and execute the provider,
3-
//! manage the caches, and so forth.
4-
51
use std::num::NonZero;
62

73
use rustc_data_structures::sync::{DynSend, DynSync};
@@ -29,10 +25,8 @@ use rustc_span::def_id::LOCAL_CRATE;
2925
use crate::error::{QueryOverflow, QueryOverflowNote};
3026
use crate::execution::{all_inactive, force_query};
3127
use crate::job::find_dep_kind_root;
32-
use crate::{
33-
CollectActiveJobsKind, GetQueryVTable, collect_active_jobs_from_all_queries,
34-
for_each_query_vtable,
35-
};
28+
use crate::query_impl::for_each_query_vtable;
29+
use crate::{CollectActiveJobsKind, GetQueryVTable, collect_active_jobs_from_all_queries};
3630

3731
fn depth_limit_error<'tcx>(tcx: TyCtxt<'tcx>, job: QueryJobId) {
3832
let job_map = collect_active_jobs_from_all_queries(tcx, CollectActiveJobsKind::Full);
@@ -283,256 +277,3 @@ pub(crate) fn force_from_dep_node_inner<'tcx, Q: GetQueryVTable<'tcx>>(
283277
false
284278
}
285279
}
286-
287-
macro_rules! define_queries {
288-
(
289-
// Note: `$K` and `$V` are unused but present so this can be called by
290-
// `rustc_with_all_queries`.
291-
queries {
292-
$(
293-
$(#[$attr:meta])*
294-
fn $name:ident($K:ty) -> $V:ty
295-
{
296-
// Search for (QMODLIST) to find all occurrences of this query modifier list.
297-
anon: $anon:literal,
298-
arena_cache: $arena_cache:literal,
299-
cache_on_disk: $cache_on_disk:literal,
300-
depth_limit: $depth_limit:literal,
301-
eval_always: $eval_always:literal,
302-
feedable: $feedable:literal,
303-
no_hash: $no_hash:literal,
304-
returns_error_guaranteed: $returns_error_guaranteed:literal,
305-
separate_provide_extern: $separate_provide_extern:literal,
306-
}
307-
)*
308-
}
309-
// Non-queries are unused here.
310-
non_queries { $($_:tt)* }
311-
) => {
312-
pub(crate) mod query_impl { $(pub(crate) mod $name {
313-
use super::super::*;
314-
use ::rustc_middle::query::erase::{self, Erased};
315-
316-
// It seems to be important that every query has its own monomorphic
317-
// copy of `execute_query_incr` and `execute_query_non_incr`.
318-
// Trying to inline these wrapper functions into their generic
319-
// "inner" helpers tends to break `tests/run-make/short-ice`.
320-
321-
pub(crate) mod execute_query_incr {
322-
use super::*;
323-
324-
// Adding `__rust_end_short_backtrace` marker to backtraces so that we emit the frames
325-
// when `RUST_BACKTRACE=1`, add a new mod with `$name` here is to allow duplicate naming
326-
#[inline(never)]
327-
pub(crate) fn __rust_end_short_backtrace<'tcx>(
328-
tcx: TyCtxt<'tcx>,
329-
span: Span,
330-
key: queries::$name::Key<'tcx>,
331-
mode: QueryMode,
332-
) -> Option<Erased<queries::$name::Value<'tcx>>> {
333-
#[cfg(debug_assertions)]
334-
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
335-
execution::execute_query_incr_inner(
336-
&tcx.query_system.query_vtables.$name,
337-
tcx,
338-
span,
339-
key,
340-
mode
341-
)
342-
}
343-
}
344-
345-
pub(crate) mod execute_query_non_incr {
346-
use super::*;
347-
348-
#[inline(never)]
349-
pub(crate) fn __rust_end_short_backtrace<'tcx>(
350-
tcx: TyCtxt<'tcx>,
351-
span: Span,
352-
key: queries::$name::Key<'tcx>,
353-
__mode: QueryMode,
354-
) -> Option<Erased<queries::$name::Value<'tcx>>> {
355-
Some(execution::execute_query_non_incr_inner(
356-
&tcx.query_system.query_vtables.$name,
357-
tcx,
358-
span,
359-
key,
360-
))
361-
}
362-
}
363-
364-
/// Defines an `invoke_provider` function that calls the query's provider,
365-
/// to be used as a function pointer in the query's vtable.
366-
///
367-
/// To mark a short-backtrace boundary, the function's actual name
368-
/// (after demangling) must be `__rust_begin_short_backtrace`.
369-
mod invoke_provider_fn {
370-
use super::*;
371-
use ::rustc_middle::queries::$name::{Key, Value, provided_to_erased};
372-
373-
#[inline(never)]
374-
pub(crate) fn __rust_begin_short_backtrace<'tcx>(
375-
tcx: TyCtxt<'tcx>,
376-
key: Key<'tcx>,
377-
) -> Erased<Value<'tcx>> {
378-
#[cfg(debug_assertions)]
379-
let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
380-
381-
// Call the actual provider function for this query.
382-
383-
#[cfg($separate_provide_extern)]
384-
let provided_value = if let Some(local_key) = key.as_local_key() {
385-
(tcx.query_system.local_providers.$name)(tcx, local_key)
386-
} else {
387-
(tcx.query_system.extern_providers.$name)(tcx, key)
388-
};
389-
390-
#[cfg(not($separate_provide_extern))]
391-
let provided_value = (tcx.query_system.local_providers.$name)(tcx, key);
392-
393-
rustc_middle::ty::print::with_reduced_queries!({
394-
tracing::trace!(?provided_value);
395-
});
396-
397-
// Erase the returned value, because `QueryVTable` uses erased values.
398-
// For queries with `arena_cache`, this also arena-allocates the value.
399-
provided_to_erased(tcx, provided_value)
400-
}
401-
}
402-
403-
pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
404-
-> QueryVTable<'tcx, queries::$name::Cache<'tcx>>
405-
{
406-
QueryVTable {
407-
name: stringify!($name),
408-
anon: $anon,
409-
eval_always: $eval_always,
410-
depth_limit: $depth_limit,
411-
feedable: $feedable,
412-
dep_kind: dep_graph::DepKind::$name,
413-
state: Default::default(),
414-
cache: Default::default(),
415-
416-
invoke_provider_fn: self::invoke_provider_fn::__rust_begin_short_backtrace,
417-
418-
#[cfg($cache_on_disk)]
419-
will_cache_on_disk_for_key_fn:
420-
rustc_middle::queries::_cache_on_disk_if_fns::$name,
421-
#[cfg(not($cache_on_disk))]
422-
will_cache_on_disk_for_key_fn: |_, _| false,
423-
424-
#[cfg($cache_on_disk)]
425-
try_load_from_disk_fn: |tcx, key, prev_index, index| {
426-
// Check the `cache_on_disk_if` condition for this key.
427-
if !rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) {
428-
return None;
429-
}
430-
431-
let value: queries::$name::ProvidedValue<'tcx> =
432-
$crate::plumbing::try_load_from_disk(tcx, prev_index, index)?;
433-
434-
// Arena-alloc the value if appropriate, and erase it.
435-
Some(queries::$name::provided_to_erased(tcx, value))
436-
},
437-
#[cfg(not($cache_on_disk))]
438-
try_load_from_disk_fn: |_tcx, _key, _prev_index, _index| None,
439-
440-
#[cfg($cache_on_disk)]
441-
is_loadable_from_disk_fn: |tcx, key, index| -> bool {
442-
rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) &&
443-
$crate::plumbing::loadable_from_disk(tcx, index)
444-
},
445-
#[cfg(not($cache_on_disk))]
446-
is_loadable_from_disk_fn: |_tcx, _key, _index| false,
447-
448-
// The default just emits `err` and then aborts.
449-
// `from_cycle_error::specialize_query_vtables` overwrites this default for
450-
// certain queries.
451-
value_from_cycle_error: |_tcx, _key, _cycle, err| {
452-
$crate::from_cycle_error::default(err)
453-
},
454-
455-
#[cfg($no_hash)]
456-
hash_value_fn: None,
457-
#[cfg(not($no_hash))]
458-
hash_value_fn: Some(|hcx, erased_value: &erase::Erased<queries::$name::Value<'tcx>>| {
459-
let value = erase::restore_val(*erased_value);
460-
rustc_middle::dep_graph::hash_result(hcx, &value)
461-
}),
462-
463-
format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*value)),
464-
create_tagged_key: TaggedQueryKey::$name,
465-
execute_query_fn: if incremental {
466-
query_impl::$name::execute_query_incr::__rust_end_short_backtrace
467-
} else {
468-
query_impl::$name::execute_query_non_incr::__rust_end_short_backtrace
469-
},
470-
}
471-
}
472-
473-
/// Marker type that implements [`GetQueryVTable`] for this query.
474-
pub(crate) enum VTableGetter {}
475-
476-
impl<'tcx> GetQueryVTable<'tcx> for VTableGetter {
477-
type Cache = rustc_middle::queries::$name::Cache<'tcx>;
478-
479-
#[inline(always)]
480-
fn query_vtable(tcx: TyCtxt<'tcx>) -> &'tcx QueryVTable<'tcx, Self::Cache> {
481-
&tcx.query_system.query_vtables.$name
482-
}
483-
}
484-
})*}
485-
486-
pub fn make_query_vtables<'tcx>(incremental: bool) -> queries::QueryVTables<'tcx> {
487-
queries::QueryVTables {
488-
$(
489-
$name: query_impl::$name::make_query_vtable(incremental),
490-
)*
491-
}
492-
}
493-
494-
/// Given a filter condition (e.g. `ALL` or `CACHE_ON_DISK`), a `tcx`,
495-
/// and a closure expression that accepts `&QueryVTable`, this macro
496-
/// calls that closure with each query vtable that satisfies the filter
497-
/// condition.
498-
///
499-
/// This needs to be a macro, because the vtables can have different
500-
/// key/value/cache types for different queries.
501-
///
502-
/// This macro's argument syntax is specifically intended to look like
503-
/// plain Rust code, so that `for_each_query_vtable!(..)` calls will be
504-
/// formatted by rustfmt.
505-
///
506-
/// To avoid too much nested-macro complication, filter conditions are
507-
/// implemented by hand as needed.
508-
macro_rules! for_each_query_vtable {
509-
// Call with all queries.
510-
(ALL, $tcx:expr, $closure:expr) => {{
511-
let tcx: rustc_middle::ty::TyCtxt<'_> = $tcx;
512-
$(
513-
let query: &rustc_middle::query::plumbing::QueryVTable<'_, _> =
514-
&tcx.query_system.query_vtables.$name;
515-
$closure(query);
516-
)*
517-
}};
518-
519-
// Only call with queries that can potentially cache to disk.
520-
//
521-
// This allows the use of trait bounds that only need to be satisfied
522-
// by the subset of queries that actually cache to disk.
523-
(CACHE_ON_DISK, $tcx:expr, $closure:expr) => {{
524-
let tcx: rustc_middle::ty::TyCtxt<'_> = $tcx;
525-
$(
526-
#[cfg($cache_on_disk)]
527-
{
528-
let query: &rustc_middle::query::plumbing::QueryVTable<'_, _> =
529-
&tcx.query_system.query_vtables.$name;
530-
$closure(query);
531-
}
532-
)*
533-
}}
534-
}
535-
536-
pub(crate) use for_each_query_vtable;
537-
}
538-
}

compiler/rustc_query_impl/src/profiling_support.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::query::QueryCache;
1010
use rustc_middle::query::plumbing::QueryVTable;
1111
use rustc_middle::ty::TyCtxt;
1212

13-
use crate::for_each_query_vtable;
13+
use crate::query_impl::for_each_query_vtable;
1414

1515
pub(crate) struct QueryKeyStringCache {
1616
def_id_cache: FxHashMap<DefId, StringId>,

0 commit comments

Comments
 (0)