diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5cf4b1546320f..08c063654272e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -988,7 +988,6 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( &hir_arena, untracked, dep_graph, - rustc_query_impl::make_dep_kind_vtables(&arena), rustc_query_impl::query_system( providers.queries, providers.extern_queries, diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 49ad6bbf85773..17b4ffd25f377 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -47,8 +47,8 @@ //! //! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html -use std::fmt; use std::hash::Hash; +use std::{fmt, mem}; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::stable_hasher::{StableHasher, StableOrd, ToStableHashKey}; @@ -66,11 +66,23 @@ use crate::ty::{TyCtxt, tls}; impl DepKind { #[inline] pub(crate) fn from_u16(u: u16) -> Self { + // Statically assert that every u16 up to `DepKind::MAX` can be transmuted + // into a `DepKind` that round-trips back to that number. + const _: () = { + assert!(DepKind::MAX as usize + 1 == DepKind::NUM_VARIANTS); + let mut i = 0; + while i <= DepKind::MAX { + let dep_kind = unsafe { mem::transmute::(i) }; + assert!(dep_kind as u16 == i); + i += 1; + } + }; + if u > Self::MAX { panic!("Invalid DepKind {u}"); } - // SAFETY: See comment on DEP_KIND_NUM_VARIANTS - unsafe { std::mem::transmute(u) } + // SAFETY: See the static assertion above. + unsafe { mem::transmute(u) } } #[inline] @@ -85,7 +97,7 @@ impl DepKind { /// This is the highest value a `DepKind` can have. It's used during encoding to /// pack information into the unused bits. - pub(crate) const MAX: u16 = DEP_KIND_NUM_VARIANTS - 1; + pub(crate) const MAX: u16 = (DepKind::NUM_VARIANTS - 1) as u16; } /// Combination of a [`DepKind`] and a key fingerprint that uniquely identifies @@ -293,24 +305,10 @@ macro_rules! define_dep_nodes { $( $(#[$q_attr])* $q_name, )* } - // This computes the number of dep kind variants. Along the way, it sanity-checks that the - // discriminants of the variants have been assigned consecutively from 0 so that they can - // be used as a dense index, and that all discriminants fit in a `u16`. - pub(crate) const DEP_KIND_NUM_VARIANTS: u16 = { - let deps = &[ - $(DepKind::$nq_name,)* - $(DepKind::$q_name,)* - ]; - let mut i = 0; - while i < deps.len() { - if i != deps[i].as_usize() { - panic!(); - } - i += 1; - } - assert!(deps.len() <= u16::MAX as usize); - deps.len() as u16 - }; + impl DepKind { + /// The total number of variants in [`DepKind`]. + pub const NUM_VARIANTS: usize = ${count($nq_name)} + ${count($q_name)}; + } pub(super) fn dep_kind_from_label_string(label: &str) -> Result { match label { diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 9787a998d6371..2213ac3b8a7ab 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -82,7 +82,7 @@ where impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn dep_kind_vtable(self, dk: DepKind) -> &'tcx DepKindVTable<'tcx> { - &self.dep_kind_vtables[dk.as_usize()] + &self.query_system.dep_kind_vtables[dk.as_usize()] } fn with_reduced_queries(self, f: impl FnOnce() -> T) -> T { diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index c8702c42c47f6..4ab8a00ef5f13 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -42,6 +42,7 @@ #![feature(extern_types)] #![feature(file_buffered)] #![feature(gen_blocks)] +#![feature(macro_metavar_expr)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index e88c20f02537b..1856da6bc16f2 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -11,7 +11,7 @@ use rustc_hir::hir_id::OwnerId; use rustc_span::{Span, Spanned}; pub use sealed::IntoQueryParam; -use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex}; +use crate::dep_graph::{DepKind, DepKindVTable, DepNodeIndex, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey}; use crate::query::on_disk_cache::OnDiskCache; @@ -159,6 +159,7 @@ impl<'tcx, C: QueryCache> fmt::Debug for QueryVTable<'tcx, C> { pub struct QuerySystem<'tcx> { pub arenas: WorkerLocal>, pub query_vtables: QueryVTables<'tcx>, + pub dep_kind_vtables: [DepKindVTable<'tcx>; DepKind::NUM_VARIANTS], /// This provides access to the incremental compilation on-disk cache for query results. /// Do not access this directly. It is only meant to be used by diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 037ee835c382f..ad638c45c7387 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -52,7 +52,7 @@ use tracing::{debug, instrument}; use crate::arena::Arena; use crate::dep_graph::dep_node::make_metadata; -use crate::dep_graph::{DepGraph, DepKindVTable, DepNodeIndex}; +use crate::dep_graph::{DepGraph, DepNodeIndex}; use crate::ich::StableHashingContext; use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind}; use crate::lint::emit_lint_base; @@ -795,7 +795,6 @@ pub struct GlobalCtxt<'tcx> { untracked: Untracked, pub query_system: QuerySystem<'tcx>, - pub(crate) dep_kind_vtables: &'tcx [DepKindVTable<'tcx>], // Internal caches for metadata decoding. No need to track deps on this. pub ty_rcache: Lock>>, @@ -1018,7 +1017,6 @@ impl<'tcx> TyCtxt<'tcx> { hir_arena: &'tcx WorkerLocal>, untracked: Untracked, dep_graph: DepGraph, - dep_kind_vtables: &'tcx [DepKindVTable<'tcx>], query_system: QuerySystem<'tcx>, hooks: crate::hooks::Providers, current_gcx: CurrentGcx, @@ -1048,7 +1046,6 @@ impl<'tcx> TyCtxt<'tcx> { consts: common_consts, untracked, query_system, - dep_kind_vtables, ty_rcache: Default::default(), selection_cache: Default::default(), evaluation_cache: Default::default(), diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs index 597c8b2a9e742..a9bb0f111e102 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -1,6 +1,5 @@ -use rustc_middle::arena::Arena; use rustc_middle::bug; -use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, KeyFingerprintStyle}; +use rustc_middle::dep_graph::{DepKind, DepKindVTable, DepNodeKey, KeyFingerprintStyle}; use rustc_middle::query::QueryCache; use crate::GetQueryVTable; @@ -152,15 +151,13 @@ macro_rules! define_dep_kind_vtables { )* } ) => {{ - // The small number of non-query vtables: `Null`, `Red`, etc. - let nq_vtables = [ + [ + // The small number of non-query vtables: `Null`, `Red`, etc. $( non_query::$nq_name(), )* - ]; - // The large number of query vtables. - let q_vtables: [DepKindVTable<'tcx>; _] = [ + // The large number of query vtables. $( $crate::dep_kind_vtables::make_dep_kind_vtable_for_query::< $crate::query_impl::$name::VTableGetter, @@ -170,17 +167,11 @@ macro_rules! define_dep_kind_vtables { $eval_always, ) ),* - ]; - - (nq_vtables, q_vtables) + ] }} } // Create an array of vtables, one for each dep kind (non-query and query). -pub fn make_dep_kind_vtables<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindVTable<'tcx>] { - let (nq_vtables, q_vtables) = - rustc_middle::queries::rustc_with_all_queries! { define_dep_kind_vtables! }; - - // Non-query vtables must come before query vtables, to match the order of `DepKind`. - arena.alloc_from_iter(nq_vtables.into_iter().chain(q_vtables.into_iter())) +pub(crate) fn make_dep_kind_vtables<'tcx>() -> [DepKindVTable<'tcx>; DepKind::NUM_VARIANTS] { + rustc_middle::queries::rustc_with_all_queries! { define_dep_kind_vtables! } } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 2f69082db66e9..dbecf86928084 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -15,7 +15,6 @@ use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_middle::query::{QueryCache, QuerySystem, QueryVTable}; use rustc_middle::ty::TyCtxt; -pub use crate::dep_kind_vtables::make_dep_kind_vtables; pub use crate::execution::{CollectActiveJobsKind, collect_active_query_jobs}; pub use crate::job::{QueryJobMap, break_query_cycles, print_query_stack}; @@ -53,6 +52,7 @@ pub fn query_system<'tcx>( QuerySystem { arenas: Default::default(), query_vtables, + dep_kind_vtables: dep_kind_vtables::make_dep_kind_vtables(), on_disk_cache, local_providers, extern_providers,