Skip to content

Commit 443d831

Browse files
committed
Move the big rustc_query_impl macro into a physical query_impl.rs
Moving the macro and its expansion into the same physical file resolves a lot of tension in the current module arrangement. Code in the macro is now free to use plain imports in the same file, and there is no longer any question of whether `mod query_impl` should be declared inside the macro, or surrounding a separate expansion site.
1 parent eaf4e74 commit 443d831

5 files changed

Lines changed: 275 additions & 269 deletions

File tree

compiler/rustc_query_impl/src/execution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ use rustc_middle::verify_ich::incremental_verify_ich;
1717
use rustc_span::{DUMMY_SP, Span};
1818

1919
use crate::dep_graph::{DepNode, DepNodeIndex};
20-
use crate::for_each_query_vtable;
2120
use crate::job::{QueryJobInfo, QueryJobMap, find_cycle_in_stack, report_cycle};
2221
use crate::plumbing::{current_query_job, next_job_id, start_query};
22+
use crate::query_impl::for_each_query_vtable;
2323

2424
#[inline]
2525
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::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 & 258 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,7 +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::{GetQueryVTable, collect_active_jobs_from_all_queries, for_each_query_vtable};
28+
use crate::query_impl::for_each_query_vtable;
29+
use crate::{GetQueryVTable, collect_active_jobs_from_all_queries};
3330

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

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)