Make typeck a tcx method which calls typeck_root query

This commit is contained in:
Daria Sukhonina
2026-03-24 14:00:46 +03:00
parent c4db0e127c
commit 94ed03acb5
5 changed files with 34 additions and 22 deletions
+10 -8
View File
@@ -82,7 +82,7 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDef
&tcx.typeck(def_id).used_trait_imports
}
fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
fn typeck_root<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
typeck_with_inspect(tcx, def_id, None)
}
@@ -95,6 +95,13 @@ pub fn inspect_typeck<'tcx>(
def_id: LocalDefId,
inspect: ObligationInspector<'tcx>,
) -> &'tcx ty::TypeckResults<'tcx> {
// Closures' typeck results come from their outermost function,
// as they are part of the same "inference environment".
let typeck_root_def_id = tcx.typeck_root_def_id_local(def_id);
if typeck_root_def_id != def_id {
return tcx.typeck(typeck_root_def_id);
}
typeck_with_inspect(tcx, def_id, Some(inspect))
}
@@ -104,12 +111,7 @@ fn typeck_with_inspect<'tcx>(
def_id: LocalDefId,
inspector: Option<ObligationInspector<'tcx>>,
) -> &'tcx ty::TypeckResults<'tcx> {
// Closures' typeck results come from their outermost function,
// as they are part of the same "inference environment".
let typeck_root_def_id = tcx.typeck_root_def_id_local(def_id);
if typeck_root_def_id != def_id {
return tcx.typeck(typeck_root_def_id);
}
assert!(!tcx.is_typeck_child(def_id.to_def_id()));
let id = tcx.local_def_id_to_hir_id(def_id);
let node = tcx.hir_node(id);
@@ -660,7 +662,7 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
pub fn provide(providers: &mut Providers) {
*providers = Providers {
method_autoderef_steps: method::probe::method_autoderef_steps,
typeck,
typeck_root,
used_trait_imports,
check_transmutes: intrinsicck::check_transmutes,
..*providers
@@ -49,7 +49,7 @@
label_strs::type_of,
// And a big part of compilation (that we eventually want to cache) is type inference
// information:
label_strs::typeck,
label_strs::typeck_root,
];
/// DepNodes for Hir, which is pretty much everything
+2 -2
View File
@@ -1222,9 +1222,9 @@
separate_provide_extern
}
query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
query typeck_root(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
desc { "type-checking `{}`", tcx.def_path_str(key) }
cache_on_disk_if { !tcx.is_typeck_child(key.to_def_id()) }
cache_on_disk_if { true }
}
query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> {
+17 -2
View File
@@ -7,14 +7,15 @@
use rustc_data_structures::sharded::Sharded;
use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal};
use rustc_errors::Diag;
use rustc_hir::def_id::LocalDefId;
use rustc_span::Span;
use crate::dep_graph::{DepKind, DepNodeIndex, QuerySideEffect, SerializedDepNodeIndex};
use crate::ich::StableHashingContext;
use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey};
use crate::query::on_disk_cache::OnDiskCache;
use crate::query::{QueryCache, QueryJob, QueryStackFrame};
use crate::ty::TyCtxt;
use crate::query::{IntoQueryKey, QueryCache, QueryJob, QueryStackFrame};
use crate::ty::{self, TyCtxt};
/// For a particular query, keeps track of "active" keys, i.e. keys whose
/// evaluation has started but has not yet finished successfully.
@@ -200,7 +201,21 @@ pub struct TyCtxtEnsureDone<'tcx> {
pub tcx: TyCtxt<'tcx>,
}
impl<'tcx> TyCtxtEnsureOk<'tcx> {
pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) {
self.typeck_root(
self.tcx.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(),
)
}
}
impl<'tcx> TyCtxt<'tcx> {
pub fn typeck(self, def_id: impl IntoQueryKey<LocalDefId>) -> &'tcx ty::TypeckResults<'tcx> {
self.typeck_root(
self.typeck_root_def_id(def_id.into_query_key().to_def_id()).expect_local(),
)
}
/// Returns a transparent wrapper for `TyCtxt` which uses
/// `span` as the location of queries performed through it.
#[inline(always)]
+4 -9
View File
@@ -309,19 +309,14 @@ pub(crate) fn create_config(
&EMPTY_SET
};
// In case typeck does end up being called, don't ICE in case there were name resolution errors
providers.queries.typeck = move |tcx, def_id| {
// Closures' tables come from their outermost function,
// as they are part of the same "inference environment".
// This avoids emitting errors for the parent twice (see similar code in `typeck_with_fallback`)
let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()).expect_local();
if typeck_root_def_id != def_id {
return tcx.typeck(typeck_root_def_id);
}
providers.queries.typeck_root = move |tcx, def_id| {
// Panic before code below breaks in case of someone calls typeck_root directly
assert!(!tcx.is_typeck_child(def_id.to_def_id()));
let body = tcx.hir_body_owned_by(def_id);
debug!("visiting body for {def_id:?}");
EmitIgnoredResolutionErrors::new(tcx).visit_body(body);
(rustc_interface::DEFAULT_QUERY_PROVIDERS.queries.typeck)(tcx, def_id)
(rustc_interface::DEFAULT_QUERY_PROVIDERS.queries.typeck_root)(tcx, def_id)
};
}),
extra_symbols: Vec::new(),