From 5b16618a8560c7fb8b4eb6696ad9009f0d63fc85 Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Wed, 25 Mar 2026 16:10:58 +0300 Subject: [PATCH 1/3] Add typeck_root_def_id_local --- .../src/diagnostics/conflict_errors.rs | 6 ++---- compiler/rustc_borrowck/src/diagnostics/mod.rs | 9 +++------ .../rustc_borrowck/src/universal_regions.rs | 18 +++++++----------- .../rustc_hir_analysis/src/check/region.rs | 8 ++++---- .../src/collect/generics_of.rs | 12 ++++++------ compiler/rustc_hir_typeck/src/closure.rs | 2 +- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_middle/src/queries.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 8 ++------ compiler/rustc_middle/src/ty/util.rs | 14 ++++++++++++++ compiler/rustc_mir_build/src/thir/cx/expr.rs | 12 ++++++------ compiler/rustc_mir_transform/src/lib.rs | 8 ++++---- compiler/rustc_mir_transform/src/liveness.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- .../error_reporting/infer/need_type_info.rs | 6 +++--- compiler/rustc_ty_utils/src/nested_bodies.rs | 9 ++++----- 16 files changed, 60 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7bbce730c1658..a63c54a2618b7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1569,10 +1569,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let tcx = self.infcx.tcx; let generics = tcx.generics_of(self.mir_def_id()); - let Some(hir_generics) = tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| tcx.hir_get_generics(def_id)) + let Some(hir_generics) = + tcx.hir_get_generics(tcx.typeck_root_def_id_local(self.mir_def_id())) else { return; }; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 8b4bda8f7fefc..86d7119639a3f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1274,12 +1274,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let ty::Param(param_ty) = *self_ty.kind() && let generics = self.infcx.tcx.generics_of(self.mir_def_id()) && let param = generics.type_param(param_ty, self.infcx.tcx) - && let Some(hir_generics) = self - .infcx - .tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| self.infcx.tcx.hir_get_generics(def_id)) + && let Some(hir_generics) = self.infcx.tcx.hir_get_generics( + self.infcx.tcx.typeck_root_def_id_local(self.mir_def_id()), + ) && let spans = hir_generics .predicates .iter() diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index aeba5ee70cf17..e96c6c7c56f9b 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -476,12 +476,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let mut indices = self.compute_indices(fr_static, defining_ty); debug!("build: indices={:?}", indices); - let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id()); - // If this is a 'root' body (not a closure/coroutine/inline const), then // there are no extern regions, so the local regions start at the same // position as the (empty) sub-list of extern regions - let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id { + let first_local_index = if !self.infcx.tcx.is_typeck_child(self.mir_def.to_def_id()) { first_extern_index } else { // If this is a closure, coroutine, or inline-const, then the late-bound regions from the enclosing @@ -583,7 +581,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { /// see `DefiningTy` for details. fn defining_ty(&self) -> DefiningTy<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id_local(self.mir_def); match tcx.hir_body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { @@ -614,7 +612,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => { let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.to_def_id() == typeck_root_def_id { + if self.mir_def == typeck_root_def_id { let args = self.infcx.replace_free_regions_with_nll_infer_vars( NllRegionVariableOrigin::FreeRegion, identity_args, @@ -660,7 +658,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { defining_ty: DefiningTy<'tcx>, ) -> UniversalRegionIndices<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id_local(self.mir_def); let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); let renumbered_args = defining_ty.args(); @@ -948,16 +946,14 @@ fn for_each_late_bound_region_in_recursive_scope<'tcx>( mut mir_def_id: LocalDefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id()); - // Walk up the tree, collecting late-bound regions until we hit the typeck root loop { for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f); - if mir_def_id.to_def_id() == typeck_root_def_id { - break; - } else { + if tcx.is_typeck_child(mir_def_id.to_def_id()) { mir_def_id = tcx.local_parent(mir_def_id); + } else { + break; } } } diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 8865638e3af2f..e31beca390837 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -11,7 +11,7 @@ use std::mem; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt}; use rustc_index::Idx; @@ -849,13 +849,13 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { /// re-use in incremental scenarios. We may sometimes need to rerun the /// type checker even when the HIR hasn't changed, and in those cases /// we can avoid reconstructing the region scope tree. -pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { - let typeck_root_def_id = tcx.typeck_root_def_id(def_id); +pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &ScopeTree { + let typeck_root_def_id = tcx.typeck_root_def_id_local(def_id); if typeck_root_def_id != def_id { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { let mut visitor = ScopeResolutionVisitor { tcx, scope_tree: ScopeTree::default(), diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 866787a457180..ea98beb955805 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -76,12 +76,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { | Node::Ctor(..) | Node::Field(_) => { let parent_id = tcx.hir_get_parent_item(hir_id); - Some(parent_id.to_def_id()) + Some(parent_id.def_id) } // FIXME(#43408) always enable this once `lazy_normalization` is // stable enough and does not need a feature gate anymore. Node::AnonConst(_) => { - let parent_did = tcx.parent(def_id.to_def_id()); + let parent_did = tcx.local_parent(def_id); debug!(?parent_did); let mut in_param_ty = false; @@ -175,7 +175,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } Node::ConstBlock(_) | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { - Some(tcx.typeck_root_def_id(def_id.to_def_id())) + Some(tcx.typeck_root_def_id_local(def_id)) } Node::OpaqueTy(&hir::OpaqueTy { origin: @@ -188,7 +188,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } else { assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn); } - Some(fn_def_id.to_def_id()) + Some(fn_def_id) } Node::OpaqueTy(&hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty }, @@ -202,7 +202,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent); // Opaque types are always nested within another item, and // inherit the generics of the item. - Some(parent.to_def_id()) + Some(parent) } // All of these nodes have no parent from which to inherit generics. @@ -380,7 +380,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { own_params.iter().map(|param| (param.def_id, param.index)).collect(); ty::Generics { - parent: parent_def_id, + parent: parent_def_id.map(LocalDefId::to_def_id), parent_count, own_params, param_def_id_to_index, diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 82b7c578a1f25..1a9c2a21c7ef3 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?bound_sig, ?liberated_sig); let parent_args = - GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id(expr_def_id.to_def_id())); + GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id_local(expr_def_id)); let tupled_upvars_ty = self.next_ty_var(expr_span); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 734e5136f8806..6cfcdfe87480e 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -106,7 +106,7 @@ fn typeck_with_inspect<'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(def_id.to_def_id()).expect_local(); + 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); } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index ff96f5044dc14..3572e3ff35cbe 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1413,7 +1413,7 @@ rustc_queries! { /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; /// in the case of closures, this will be redirected to the enclosing function. - query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree { + query region_scope_tree(def_id: LocalDefId) -> &'tcx crate::middle::region::ScopeTree { desc { "computing drop scopes for `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 58a2edca8ecef..28688bcbfafc4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -899,12 +899,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn has_typeck_results(self, def_id: LocalDefId) -> bool { // Closures' typeck results come from their outermost function, // as they are part of the same "inference environment". - let typeck_root_def_id = self.typeck_root_def_id(def_id.to_def_id()); - if typeck_root_def_id != def_id.to_def_id() { - return self.has_typeck_results(typeck_root_def_id.expect_local()); - } - - self.hir_node_by_def_id(def_id).body_id().is_some() + let root = self.typeck_root_def_id_local(def_id); + self.hir_node_by_def_id(root).body_id().is_some() } /// Expects a body and returns its codegen attributes. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e7c7d59248700..d0cbdff366dfa 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -650,6 +650,20 @@ impl<'tcx> TyCtxt<'tcx> { def_id } + /// Given the `LocalDefId`, returns the `LocalDefId` of the innermost item that + /// has its own type-checking context or "inference environment". + /// + /// For example, a closure has its own `LocalDefId`, but it is type-checked + /// with the containing item. Therefore, when we fetch the `typeck` of the closure, + /// for example, we really wind up fetching the `typeck` of the enclosing fn item. + pub fn typeck_root_def_id_local(self, def_id: LocalDefId) -> LocalDefId { + let mut def_id = def_id; + while self.is_typeck_child(def_id.to_def_id()) { + def_id = self.local_parent(def_id); + } + def_id + } + /// Given the `DefId` and args a closure, creates the type of /// `self` argument that the closure expects. For example, for a /// `Fn` closure, this would return a reference type `&T` where diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 4256ee45f8501..7e6f30378a490 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -816,8 +816,8 @@ impl<'tcx> ThirBuildCx<'tcx> { } hir::InlineAsmOperand::Const { ref anon_const } => { let ty = self.typeck_results.node_type(anon_const.hir_id); - let did = anon_const.def_id.to_def_id(); - let typeck_root_def_id = tcx.typeck_root_def_id(did); + let did = anon_const.def_id; + let typeck_root_def_id = tcx.typeck_root_def_id_local(did); let parent_args = tcx.erase_and_anonymize_regions( GenericArgs::identity_for_item(tcx, typeck_root_def_id), ); @@ -825,7 +825,7 @@ impl<'tcx> ThirBuildCx<'tcx> { InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }) .args; - let uneval = mir::UnevaluatedConst::new(did, args); + let uneval = mir::UnevaluatedConst::new(did.to_def_id(), args); let value = mir::Const::Unevaluated(uneval, ty); InlineAsmOperand::Const { value, span: tcx.def_span(did) } } @@ -895,15 +895,15 @@ impl<'tcx> ThirBuildCx<'tcx> { hir::ExprKind::ConstBlock(ref anon_const) => { let ty = self.typeck_results.node_type(anon_const.hir_id); - let did = anon_const.def_id.to_def_id(); - let typeck_root_def_id = tcx.typeck_root_def_id(did); + let did = anon_const.def_id; + let typeck_root_def_id = tcx.typeck_root_def_id_local(did); let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item( tcx, typeck_root_def_id, )); let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args; - ExprKind::ConstBlock { did, args } + ExprKind::ConstBlock { did: did.to_def_id(), args } } // Now comes the rote stuff: hir::ExprKind::Repeat(v, _) => { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 094aae499c4b4..9273c2103d442 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -526,7 +526,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & // We only need to borrowck non-synthetic MIR. let tainted_by_errors = if !tcx.is_synthetic_mir(def) { - tcx.mir_borrowck(tcx.typeck_root_def_id(def.to_def_id()).expect_local()).err() + tcx.mir_borrowck(tcx.typeck_root_def_id_local(def)).err() } else { None }; @@ -554,14 +554,14 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & // // We do this check here and not during `mir_promoted` because that may result // in borrowck cycles if WF requires looking into an opaque hidden type. - let root = tcx.typeck_root_def_id(def.to_def_id()); + let root = tcx.typeck_root_def_id_local(def); match tcx.def_kind(root) { DefKind::Fn | DefKind::AssocFn | DefKind::Static { .. } | DefKind::Const { .. } | DefKind::AssocConst { .. } => { - if let Err(guar) = tcx.ensure_result().check_well_formed(root.expect_local()) { + if let Err(guar) = tcx.ensure_result().check_well_formed(root) { body.tainted_by_errors = Some(guar); } } @@ -840,7 +840,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den } // Don't run unused pass for #[derive] - let parent = tcx.parent(tcx.typeck_root_def_id(def_id.to_def_id())); + let parent = tcx.local_parent(tcx.typeck_root_def_id_local(def_id)); if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent) && find_attr!(tcx, parent, AutomaticallyDerived(..)) { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8bd6730ab0eba..4698e054daf6e 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1615,7 +1615,7 @@ impl<'v> RootCollector<'_, 'v> { if (self.strategy == MonoItemCollectionStrategy::Eager || is_pub_fn_coroutine) && !self .tcx - .generics_of(self.tcx.typeck_root_def_id(def_id.to_def_id())) + .generics_of(self.tcx.typeck_root_def_id_local(def_id)) .requires_monomorphization(self.tcx) { let instance = match *self.tcx.type_of(def_id).instantiate_identity().kind() { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 7fcaea3a629f1..462f014a81f24 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -507,9 +507,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, term, ty); - if let Some(body) = self.tcx.hir_maybe_body_owned_by( - self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), - ) { + if let Some(body) = + self.tcx.hir_maybe_body_owned_by(self.tcx.typeck_root_def_id_local(body_def_id)) + { let expr = body.value; local_visitor.visit_expr(expr); } diff --git a/compiler/rustc_ty_utils/src/nested_bodies.rs b/compiler/rustc_ty_utils/src/nested_bodies.rs index 11dfbad7dbb7a..874c8161453b3 100644 --- a/compiler/rustc_ty_utils/src/nested_bodies.rs +++ b/compiler/rustc_ty_utils/src/nested_bodies.rs @@ -1,27 +1,26 @@ use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::Visitor; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; fn nested_bodies_within<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx ty::List { let body = tcx.hir_body_owned_by(item); - let mut collector = - NestedBodiesVisitor { tcx, root_def_id: item.to_def_id(), nested_bodies: vec![] }; + let mut collector = NestedBodiesVisitor { tcx, root_def_id: item, nested_bodies: vec![] }; collector.visit_body(body); tcx.mk_local_def_ids(&collector.nested_bodies) } struct NestedBodiesVisitor<'tcx> { tcx: TyCtxt<'tcx>, - root_def_id: DefId, + root_def_id: LocalDefId, nested_bodies: Vec, } impl<'tcx> Visitor<'tcx> for NestedBodiesVisitor<'tcx> { fn visit_nested_body(&mut self, id: hir::BodyId) { let body_def_id = self.tcx.hir_body_owner_def_id(id); - if self.tcx.typeck_root_def_id(body_def_id.to_def_id()) == self.root_def_id { + if self.tcx.typeck_root_def_id_local(body_def_id) == self.root_def_id { // We visit nested bodies before adding the current body. This // means that nested bodies are always stored before their parent. let body = self.tcx.hir_body(id); From b20dbd9b9b384a10c2db0d881ea9a519f0a4e5af Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Wed, 25 Mar 2026 16:30:46 +0300 Subject: [PATCH 2/3] Prematurely optimize local_parent --- compiler/rustc_middle/src/ty/context.rs | 9 +++++++-- compiler/rustc_middle/src/ty/mod.rs | 11 +++++++---- compiler/rustc_privacy/src/lib.rs | 4 +++- compiler/rustc_span/src/def_id.rs | 12 ++++++------ 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 28688bcbfafc4..a94146be362d2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1168,16 +1168,21 @@ impl<'tcx> TyCtxt<'tcx> { self.features_query(()) } - pub fn def_key(self, id: impl IntoQueryKey) -> rustc_hir::definitions::DefKey { + pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey { let id = id.into_query_key(); // Accessing the DefKey is ok, since it is part of DefPathHash. if let Some(id) = id.as_local() { - self.definitions_untracked().def_key(id) + self.local_def_key(id) } else { self.cstore_untracked().def_key(id) } } + #[inline] + pub fn local_def_key(self, id: LocalDefId) -> rustc_hir::definitions::DefKey { + self.definitions_untracked().def_key(id) + } + /// Converts a `DefId` into its fully expanded `DefPath` (every /// `DefId` is really just an interned `DefPath`). /// diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 674799cb41bad..44b5b0ac2a35a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -320,15 +320,18 @@ impl TyCtxt<'_> { } #[inline] - #[track_caller] pub fn opt_local_parent(self, id: LocalDefId) -> Option { - self.opt_parent(id.to_def_id()).map(DefId::expect_local) + self.local_def_key(id).parent.map(|i| LocalDefId { local_def_index: i }) } #[inline] #[track_caller] - pub fn local_parent(self, id: impl Into) -> LocalDefId { - self.parent(id.into().to_def_id()).expect_local() + pub fn local_parent(self, id: LocalDefId) -> LocalDefId { + match self.opt_local_parent(id) { + Some(id) => id, + // not `unwrap_or_else` to avoid breaking caller tracking + None => bug!("{id:?} doesn't have a parent"), + } } pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 663f8727724e4..37559da722ae4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -535,7 +535,9 @@ impl<'tcx> EmbargoVisitor<'tcx> { if changed_reachability || module_def_id == LocalModDefId::CRATE_DEF_ID { break; } - module_def_id = LocalModDefId::new_unchecked(self.tcx.local_parent(module_def_id)); + module_def_id = LocalModDefId::new_unchecked( + self.tcx.local_parent(module_def_id.to_local_def_id()), + ); } } diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 82d455ab54f0f..269f7fab67327 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -470,9 +470,9 @@ macro_rules! typed_def_id { Self(def_id) } - #[inline] + #[inline(always)] pub fn to_def_id(self) -> DefId { - self.into() + self.0 } #[inline] @@ -494,7 +494,7 @@ macro_rules! typed_def_id { } impl From<$Name> for DefId { - #[inline] + #[inline(always)] fn from(typed: $Name) -> Self { typed.0 } @@ -507,7 +507,7 @@ macro_rules! typed_def_id { impl !PartialOrd for $LocalName {} impl $LocalName { - #[inline] + #[inline(always)] pub const fn new_unchecked(def_id: LocalDefId) -> Self { Self(def_id) } @@ -517,14 +517,14 @@ macro_rules! typed_def_id { self.0.into() } - #[inline] + #[inline(always)] pub fn to_local_def_id(self) -> LocalDefId { self.0 } } impl From<$LocalName> for LocalDefId { - #[inline] + #[inline(always)] fn from(typed: $LocalName) -> Self { typed.0 } From ec7d2722e44c2fd41d01e992830c94de4fb264cc Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Wed, 25 Mar 2026 17:45:33 +0300 Subject: [PATCH 3/3] Localize many method calls --- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 2 +- compiler/rustc_incremental/src/assert_dep_graph.rs | 2 +- compiler/rustc_incremental/src/persist/clean.rs | 2 +- compiler/rustc_lint/src/default_could_be_derived.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/dep_graph/dep_node_key.rs | 4 ++-- compiler/rustc_middle/src/ty/context.rs | 6 ++++++ compiler/rustc_middle/src/ty/mod.rs | 7 ++++++- compiler/rustc_mir_transform/src/coverage/query.rs | 2 +- compiler/rustc_passes/src/dead.rs | 4 ++-- compiler/rustc_symbol_mangling/src/legacy.rs | 4 +--- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- .../src/error_reporting/infer/need_type_info.rs | 5 ++--- .../src/error_reporting/traits/suggestions.rs | 3 +-- src/tools/clippy/clippy_lints/src/macro_use.rs | 6 +++--- .../clippy/clippy_lints/src/only_used_in_recursion.rs | 2 +- src/tools/clippy/clippy_lints/src/shadow.rs | 2 +- 17 files changed, 32 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 98999232a7435..8fd3d631962c8 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -107,7 +107,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ); return ty::GenericPredicates { - parent: Some(tcx.parent(def_id.to_def_id())), + parent: Some(tcx.local_parent(def_id).to_def_id()), predicates: tcx.arena.alloc_from_iter(predicates), }; } diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 61ddd2ca566b1..2ddb075634e20 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -107,7 +107,7 @@ struct IfThisChanged<'tcx> { impl<'tcx> IfThisChanged<'tcx> { fn process_attrs(&mut self, def_id: LocalDefId) { - let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id()); + let def_path_hash = self.tcx.local_def_path_hash(def_id); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { diff --git a/compiler/rustc_incremental/src/persist/clean.rs b/compiler/rustc_incremental/src/persist/clean.rs index ab336a69737a1..f9898cecb91aa 100644 --- a/compiler/rustc_incremental/src/persist/clean.rs +++ b/compiler/rustc_incremental/src/persist/clean.rs @@ -350,7 +350,7 @@ impl<'tcx> CleanVisitor<'tcx> { fn check_item(&mut self, item_id: LocalDefId) { let item_span = self.tcx.def_span(item_id.to_def_id()); - let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id()); + let def_path_hash = self.tcx.local_def_path_hash(item_id); let Some(clean_attrs) = find_attr!(self.tcx, item_id, RustcClean(attr) => attr) else { return; diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 9d4b79a45453a..e96b977249f62 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { } let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return }; let impl_id = cx.tcx.local_parent(impl_item.owner_id.def_id); - if cx.tcx.is_automatically_derived(impl_id.to_def_id()) { + if cx.tcx.is_automatically_derived_local(impl_id) { // We don't care about what `#[derive(Default)]` produces in this lint. return; } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e554da362f83e..8bf919dab8e79 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -727,7 +727,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { is_stub: false, }, extra_filename: tcx.sess.opts.cg.extra_filename.clone(), - stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), + stable_crate_id: tcx.stable_crate_id(LOCAL_CRATE), required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE), panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, edition: tcx.sess.edition(), diff --git a/compiler/rustc_middle/src/dep_graph/dep_node_key.rs b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs index 10e785ac6b870..3119230fb7662 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node_key.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node_key.rs @@ -109,7 +109,7 @@ impl<'tcx> DepNodeKey<'tcx> for LocalDefId { #[inline(always)] fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - self.to_def_id().to_fingerprint(tcx) + tcx.local_def_path_hash(*self).0 } #[inline(always)] @@ -207,7 +207,7 @@ impl<'tcx> DepNodeKey<'tcx> for HirId { #[inline(always)] fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { let HirId { owner, local_id } = *self; - let def_path_hash = tcx.def_path_hash(owner.to_def_id()); + let def_path_hash = tcx.local_def_path_hash(owner.def_id); Fingerprint::new( // `owner` is local, so is completely defined by the local hash def_path_hash.local_hash(), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a94146be362d2..9af47abb5d1b6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1207,6 +1207,12 @@ impl<'tcx> TyCtxt<'tcx> { } } + #[inline] + pub fn local_def_path_hash(self, def_id: LocalDefId) -> rustc_hir::definitions::DefPathHash { + // Accessing the DefPathHash is ok, it is incr. comp. stable. + self.definitions_untracked().def_path_hash(def_id) + } + #[inline] pub fn crate_types(self) -> &'tcx [CrateType] { &self.crate_types diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 44b5b0ac2a35a..d8d40430821a1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1411,7 +1411,7 @@ impl<'tcx> TyCtxt<'tcx> { // Generate a deterministically-derived seed from the item's path hash // to allow for cross-crate compilation to actually work - let mut field_shuffle_seed = self.def_path_hash(did.to_def_id()).0.to_smaller_hash(); + let mut field_shuffle_seed = self.local_def_path_hash(did).0.to_smaller_hash(); // If the user defined a custom seed for layout randomization, xor the item's // path hash with the user defined seed, this will allowing determinism while @@ -1988,6 +1988,11 @@ impl<'tcx> TyCtxt<'tcx> { find_attr!(self, def_id, AutomaticallyDerived(..)) } + /// Check if the given `DefId` is `#\[automatically_derived\]`. + pub fn is_automatically_derived_local(self, def_id: LocalDefId) -> bool { + find_attr!(self, def_id, AutomaticallyDerived(..)) + } + /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` /// with the name of the crate containing the impl. pub fn span_of_impl(self, impl_def_id: DefId) -> Result { diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 85870be912b56..94e9876810101 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -61,7 +61,7 @@ fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { // // This affects not just the associated items of an impl block, but also // any closures and other nested functions within those associated items. - if tcx.is_automatically_derived(def_id.to_def_id()) { + if tcx.is_automatically_derived_local(def_id) { return false; } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 30634c800e819..ce2ef14a5d7b4 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -380,8 +380,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { /// for discussion). fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool { if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind - && let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id()) - && self.tcx.is_automatically_derived(impl_of) + && let impl_of = self.tcx.local_parent(impl_item.owner_id.def_id) + && self.tcx.is_automatically_derived_local(impl_of) && let trait_ref = self.tcx.impl_trait_ref(impl_of).instantiate_identity() && find_attr!(self.tcx, trait_ref.def_id, RustcTrivialFieldReads) { diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index ea16231880e2c..54ecf277cd3df 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -155,9 +155,7 @@ fn get_symbol_hash<'tcx>( args.hash_stable(hcx, &mut hasher); if let Some(instantiating_crate) = instantiating_crate { - tcx.def_path_hash(instantiating_crate.as_def_id()) - .stable_crate_id() - .hash_stable(hcx, &mut hasher); + tcx.stable_crate_id(instantiating_crate).hash_stable(hcx, &mut hasher); } // We want to avoid accidental collision between different types of instances. diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 95cbb9e07ebb7..eff8cbef99541 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -841,7 +841,7 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { fn print_crate_name(&mut self, cnum: CrateNum) -> Result<(), PrintError> { self.push("C"); if !self.is_exportable { - let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); + let stable_crate_id = self.tcx.stable_crate_id(cnum); self.push_disambiguator(stable_crate_id.as_u64()); } let name = self.tcx.crate_name(cnum); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 462f014a81f24..c97a80e82ed05 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -516,9 +516,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Some(InferSource { span, kind }) = local_visitor.infer_source else { let silence = if let DefKind::AssocFn = self.tcx.def_kind(body_def_id) - && let parent = self.tcx.parent(body_def_id.into()) - && self.tcx.is_automatically_derived(parent) - && let Some(parent) = parent.as_local() + && let parent = self.tcx.local_parent(body_def_id) + && self.tcx.is_automatically_derived_local(parent) && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(parent) && let hir::ItemKind::Impl(imp) = item.kind && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = imp.self_ty.kind diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 4a6d5eb48f8f1..a16bbf20238c0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1966,10 +1966,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut span = obligation.cause.span; if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id) - && let parent = self.tcx.parent(obligation.cause.body_id.into()) + && let parent = self.tcx.local_parent(obligation.cause.body_id) && let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent) && self.tcx.asyncness(parent).is_async() - && let Some(parent) = parent.as_local() && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) | Node::TraitItem(hir::TraitItem { diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 6eda0fa257a98..6d04e0e236a22 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -153,7 +153,7 @@ impl LateLintPass<'_> for MacroUseImports { (*root).to_string(), span, hir_id.local_id, - cx.tcx.def_path_hash(hir_id.owner.def_id.into()), + cx.tcx.local_def_path_hash(hir_id.owner.def_id), )) .or_insert_with(|| (vec![], hir_id)) .0 @@ -177,7 +177,7 @@ impl LateLintPass<'_> for MacroUseImports { (*root).to_string(), span, hir_id.local_id, - cx.tcx.def_path_hash(hir_id.owner.def_id.into()), + cx.tcx.local_def_path_hash(hir_id.owner.def_id), )) .or_insert_with(|| (vec![], hir_id)) .0 @@ -189,7 +189,7 @@ impl LateLintPass<'_> for MacroUseImports { (*root).to_string(), span, hir_id.local_id, - cx.tcx.def_path_hash(hir_id.owner.def_id.into()), + cx.tcx.local_def_path_hash(hir_id.owner.def_id), )) .or_insert_with(|| (vec![], hir_id)) .0 diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 8b0743c8d9d59..6c45964da0dab 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -332,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { if let ImplItemImplKind::Trait { trait_item_def_id, .. } = impl_kind && let Ok(trait_item_id) = trait_item_def_id { - let impl_id = cx.tcx.parent(owner_id.into()); + let impl_id = cx.tcx.local_parent(owner_id.def_id); let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity(); ( trait_item_id, diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 4fa22ff0cdb5a..4ddf82773d872 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -179,7 +179,7 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { } fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool { - let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id()); + let scope_tree = cx.tcx.region_scope_tree(owner); if let Some(first_scope) = scope_tree.var_scope(first) && let Some(second_scope) = scope_tree.var_scope(second) {