Skip to content

Commit c8f7429

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 4efe3dc commit c8f7429

5 files changed

Lines changed: 271 additions & 268 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: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,23 @@
1111
use rustc_data_structures::sync::AtomicU64;
1212
use rustc_middle::dep_graph;
1313
use rustc_middle::queries::{self, 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};
@@ -33,7 +29,8 @@ use rustc_span::def_id::LOCAL_CRATE;
3329
use crate::error::{QueryOverflow, QueryOverflowNote};
3430
use crate::execution::{all_inactive, force_query};
3531
use crate::job::find_dep_kind_root;
36-
use crate::{GetQueryVTable, collect_active_jobs_from_all_queries, for_each_query_vtable};
32+
use crate::query_impl::for_each_query_vtable;
33+
use crate::{GetQueryVTable, collect_active_jobs_from_all_queries};
3734

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

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)