Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions compiler/rustc_middle/src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
) -> Self {
let err = Ty::new_error(tcx, guar);

let arity = if let Some(frame) = cycle_error.cycle.get(0)
&& frame.query.dep_kind == dep_kinds::fn_sig
&& let Some(def_id) = frame.query.def_id
let arity = if let Some(info) = cycle_error.cycle.get(0)
&& info.frame.dep_kind == dep_kinds::fn_sig
&& let Some(def_id) = info.frame.def_id
&& let Some(node) = tcx.hir_get_if_local(def_id)
&& let Some(sig) = node.fn_sig()
{
Expand Down Expand Up @@ -85,10 +85,10 @@ impl<'tcx> Value<TyCtxt<'tcx>> for Representability {
let mut item_and_field_ids = Vec::new();
let mut representable_ids = FxHashSet::default();
for info in &cycle_error.cycle {
if info.query.dep_kind == dep_kinds::representability
&& let Some(field_id) = info.query.def_id
if info.frame.dep_kind == dep_kinds::representability
&& let Some(field_id) = info.frame.def_id
&& let Some(field_id) = field_id.as_local()
&& let Some(DefKind::Field) = info.query.info.def_kind
&& let Some(DefKind::Field) = info.frame.info.def_kind
{
let parent_id = tcx.parent(field_id.to_def_id());
let item_id = match tcx.def_kind(parent_id) {
Expand All @@ -99,8 +99,8 @@ impl<'tcx> Value<TyCtxt<'tcx>> for Representability {
}
}
for info in &cycle_error.cycle {
if info.query.dep_kind == dep_kinds::representability_adt_ty
&& let Some(def_id) = info.query.def_id_for_ty_in_cycle
if info.frame.dep_kind == dep_kinds::representability_adt_ty
&& let Some(def_id) = info.frame.def_id_for_ty_in_cycle
&& let Some(def_id) = def_id.as_local()
&& !item_and_field_ids.iter().any(|&(id, _)| id == def_id)
{
Expand Down Expand Up @@ -141,9 +141,9 @@ impl<'tcx> Value<TyCtxt<'tcx>> for &[ty::Variance] {
search_for_cycle_permutation(
&cycle_error.cycle,
|cycle| {
if let Some(frame) = cycle.get(0)
&& frame.query.dep_kind == dep_kinds::variances_of
&& let Some(def_id) = frame.query.def_id
if let Some(info) = cycle.get(0)
&& info.frame.dep_kind == dep_kinds::variances_of
&& let Some(def_id) = info.frame.def_id
{
let n = tcx.generics_of(def_id).own_params.len();
ControlFlow::Break(vec![ty::Bivariant; n].leak())
Expand Down Expand Up @@ -189,8 +189,8 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
let diag = search_for_cycle_permutation(
&cycle_error.cycle,
|cycle| {
if cycle[0].query.dep_kind == dep_kinds::layout_of
&& let Some(def_id) = cycle[0].query.def_id_for_ty_in_cycle
if cycle[0].frame.dep_kind == dep_kinds::layout_of
&& let Some(def_id) = cycle[0].frame.def_id_for_ty_in_cycle
&& let Some(def_id) = def_id.as_local()
&& let def_kind = tcx.def_kind(def_id)
&& matches!(def_kind, DefKind::Closure)
Expand All @@ -213,18 +213,18 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
tcx.def_kind_descr_article(def_kind, def_id.to_def_id()),
tcx.def_kind_descr(def_kind, def_id.to_def_id()),
);
for (i, frame) in cycle.iter().enumerate() {
if frame.query.dep_kind != dep_kinds::layout_of {
for (i, info) in cycle.iter().enumerate() {
if info.frame.dep_kind != dep_kinds::layout_of {
continue;
}
let Some(frame_def_id) = frame.query.def_id_for_ty_in_cycle else {
let Some(frame_def_id) = info.frame.def_id_for_ty_in_cycle else {
continue;
};
let Some(frame_coroutine_kind) = tcx.coroutine_kind(frame_def_id) else {
continue;
};
let frame_span =
frame.query.info.default_span(cycle[(i + 1) % cycle.len()].span);
info.frame.info.default_span(cycle[(i + 1) % cycle.len()].span);
if frame_span.is_dummy() {
continue;
}
Expand Down
51 changes: 28 additions & 23 deletions compiler/rustc_query_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

// tidy-alphabetical-start
#![allow(internal_features)]
#![feature(adt_const_params)]
#![feature(min_specialization)]
#![feature(rustc_attrs)]
// tidy-alphabetical-end

use std::marker::ConstParamTy;

use rustc_data_structures::stable_hasher::HashStable;
use rustc_data_structures::sync::AtomicU64;
use rustc_middle::arena::Arena;
Expand Down Expand Up @@ -35,38 +38,43 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all};
mod profiling_support;
pub use self::profiling_support::alloc_self_profile_query_strings;

#[derive(ConstParamTy)] // Allow this struct to be used for const-generic values.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct QueryFlags {
/// True if this query has the `anon` modifier.
is_anon: bool,
/// True if this query has the `depth_limit` modifier.
is_depth_limit: bool,
/// True if this query has the `feedable` modifier.
is_feedable: bool,
}

/// Combines a [`QueryVTable`] with some additional compile-time booleans
/// to implement [`QueryDispatcher`], for use by code in [`rustc_query_system`].
///
/// Baking these boolean flags into the type gives a modest but measurable
/// improvement to compiler perf and compiler code size; see
/// <https://github.com/rust-lang/rust/pull/151633>.
struct SemiDynamicQueryDispatcher<
'tcx,
C: QueryCache,
const ANON: bool,
const DEPTH_LIMIT: bool,
const FEEDABLE: bool,
> {
struct SemiDynamicQueryDispatcher<'tcx, C: QueryCache, const FLAGS: QueryFlags> {
vtable: &'tcx QueryVTable<'tcx, C>,
}

// Manually implement Copy/Clone, because deriving would put trait bounds on the cache type.
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> Copy
for SemiDynamicQueryDispatcher<'tcx, C, FLAGS>
{
}
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone
for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> Clone
for SemiDynamicQueryDispatcher<'tcx, C, FLAGS>
{
fn clone(&self) -> Self {
*self
}
}

// This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`.
impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool>
QueryDispatcher<'tcx> for SemiDynamicQueryDispatcher<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE>
impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx>
for SemiDynamicQueryDispatcher<'tcx, C, FLAGS>
where
for<'a> C::Key: HashStable<StableHashingContext<'a>>,
{
Expand All @@ -86,10 +94,7 @@ where
}

#[inline(always)]
fn query_state<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a QueryState<'tcx, Self::Key>
where
QueryCtxt<'tcx>: 'a,
{
fn query_state(self, qcx: QueryCtxt<'tcx>) -> &'tcx QueryState<'tcx, Self::Key> {
// Safety:
// This is just manually doing the subfield referencing through pointer math.
unsafe {
Expand All @@ -100,7 +105,7 @@ where
}

#[inline(always)]
fn query_cache<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a Self::Cache {
fn query_cache(self, qcx: QueryCtxt<'tcx>) -> &'tcx Self::Cache {
// Safety:
// This is just manually doing the subfield referencing through pointer math.
unsafe {
Expand Down Expand Up @@ -158,7 +163,7 @@ where

#[inline(always)]
fn anon(self) -> bool {
ANON
FLAGS.is_anon
}

#[inline(always)]
Expand All @@ -168,12 +173,12 @@ where

#[inline(always)]
fn depth_limit(self) -> bool {
DEPTH_LIMIT
FLAGS.is_depth_limit
}

#[inline(always)]
fn feedable(self) -> bool {
FEEDABLE
FLAGS.is_feedable
}

#[inline(always)]
Expand Down Expand Up @@ -216,12 +221,12 @@ trait QueryDispatcherUnerased<'tcx> {
) -> Self::UnerasedValue;
}

pub fn query_system<'a>(
pub fn query_system<'tcx>(
local_providers: Providers,
extern_providers: ExternProviders,
on_disk_cache: Option<OnDiskCache>,
incremental: bool,
) -> QuerySystem<'a> {
) -> QuerySystem<'tcx> {
QuerySystem {
states: Default::default(),
arenas: Default::default(),
Expand Down
58 changes: 26 additions & 32 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ impl<'tcx> QueryCtxt<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
QueryCtxt { tcx }
}

fn depth_limit_error(self, job: QueryJobId) {
let query_map = self.collect_active_jobs(true).expect("failed to collect active queries");
let (info, depth) = job.find_dep_kind_root(query_map);

let suggested_limit = match self.tcx.recursion_limit() {
Limit(0) => Limit(2),
limit => limit * 2,
};

self.tcx.sess.dcx().emit_fatal(QueryOverflow {
span: info.job.span,
note: QueryOverflowNote { desc: info.frame.info.extract().description, depth },
suggested_limit,
crate_name: self.tcx.crate_name(LOCAL_CRATE),
});
}
}

impl<'tcx> HasDepContext for QueryCtxt<'tcx> {
Expand Down Expand Up @@ -104,13 +121,6 @@ impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> {
if complete { Ok(jobs) } else { Err(jobs) }
}

fn lift_query_info(
self,
info: &QueryStackDeferred<'tcx>,
) -> rustc_query_system::query::QueryStackFrameExtra {
info.extract()
}

// Interactions with on_disk_cache
fn load_side_effect(
self,
Expand Down Expand Up @@ -162,26 +172,6 @@ impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> {
tls::enter_context(&new_icx, compute)
})
}

fn depth_limit_error(self, job: QueryJobId) {
let query_map = self.collect_active_jobs(true).expect("failed to collect active queries");
let (info, depth) = job.find_dep_kind_root(query_map);

let suggested_limit = match self.tcx.recursion_limit() {
Limit(0) => Limit(2),
limit => limit * 2,
};

self.tcx.sess.dcx().emit_fatal(QueryOverflow {
span: info.job.span,
note: QueryOverflowNote {
desc: self.lift_query_info(&info.query.info).description,
depth,
},
suggested_limit,
crate_name: self.tcx.crate_name(LOCAL_CRATE),
});
}
}

pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool {
Expand Down Expand Up @@ -708,14 +698,18 @@ macro_rules! define_queries {
data: PhantomData<&'tcx ()>
}

const FLAGS: QueryFlags = QueryFlags {
is_anon: is_anon!([$($modifiers)*]),
is_depth_limit: depth_limit!([$($modifiers)*]),
is_feedable: feedable!([$($modifiers)*]),
};

impl<'tcx> QueryDispatcherUnerased<'tcx> for QueryType<'tcx> {
type UnerasedValue = queries::$name::Value<'tcx>;
type Dispatcher = SemiDynamicQueryDispatcher<
'tcx,
queries::$name::Storage<'tcx>,
{ is_anon!([$($modifiers)*]) },
{ depth_limit!([$($modifiers)*]) },
{ feedable!([$($modifiers)*]) },
FLAGS,
>;

const NAME: &'static &'static str = &stringify!($name);
Expand All @@ -738,14 +732,14 @@ macro_rules! define_queries {
qmap: &mut QueryMap<'tcx>,
require_complete: bool,
) -> Option<()> {
let make_query = |tcx, key| {
let make_frame = |tcx, key| {
let kind = rustc_middle::dep_graph::dep_kinds::$name;
let name = stringify!($name);
$crate::plumbing::create_query_frame(tcx, rustc_middle::query::descs::$name, key, kind, name)
};
let res = tcx.query_system.states.$name.collect_active_jobs(
tcx,
make_query,
make_frame,
qmap,
require_complete,
);
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_query_system/src/query/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type DepContextOf<'tcx, This: QueryDispatcher<'tcx>> =
/// Those types are not visible from this `rustc_query_system` crate.
///
/// "Dispatcher" should be understood as a near-synonym of "vtable".
pub trait QueryDispatcher<'tcx>: Copy {
pub trait QueryDispatcher<'tcx>: Copy + 'tcx {
fn name(self) -> &'static str;

/// Query context used by this dispatcher, i.e. `rustc_query_impl::QueryCtxt`.
Expand All @@ -41,10 +41,10 @@ pub trait QueryDispatcher<'tcx>: Copy {
fn format_value(self) -> fn(&Self::Value) -> String;

// Don't use this method to access query results, instead use the methods on TyCtxt
fn query_state<'a>(self, tcx: Self::Qcx) -> &'a QueryState<'tcx, Self::Key>;
fn query_state(self, tcx: Self::Qcx) -> &'tcx QueryState<'tcx, Self::Key>;

// Don't use this method to access query results, instead use the methods on TyCtxt
fn query_cache<'a>(self, tcx: Self::Qcx) -> &'a Self::Cache;
fn query_cache(self, tcx: Self::Qcx) -> &'tcx Self::Cache;

fn will_cache_on_disk_for_key(self, tcx: DepContextOf<'tcx, Self>, key: &Self::Key) -> bool;

Expand Down
Loading
Loading