From f0df007ac0918e40808ccf0716582a0e5cec2910 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Mon, 11 Aug 2025 11:35:59 -0500 Subject: [PATCH] Reduce some queries around associated items --- compiler/rustc_borrowck/src/type_check/mod.rs | 6 +++--- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 7 ++++--- compiler/rustc_const_eval/src/interpret/call.rs | 2 +- .../src/check/compare_impl_item.rs | 6 +++--- compiler/rustc_hir_typeck/src/fallback.rs | 2 +- compiler/rustc_lint/src/pass_by_value.rs | 10 +++++----- compiler/rustc_lint/src/types.rs | 7 ++++--- compiler/rustc_middle/src/middle/privacy.rs | 9 ++++----- .../rustc_mir_transform/src/check_call_recursion.rs | 5 +++-- .../rustc_mir_transform/src/check_packed_ref.rs | 4 +++- compiler/rustc_mir_transform/src/shim.rs | 2 +- compiler/rustc_monomorphize/src/partitioning.rs | 13 +++++++------ .../rustc_trait_selection/src/traits/project.rs | 2 +- 13 files changed, 40 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c3aa205d5aab3..26e2a8e693ee6 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1773,10 +1773,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { locations, ); - assert!(!matches!( - tcx.impl_of_assoc(def_id).map(|imp| tcx.def_kind(imp)), + assert_ne!( + tcx.assoc_parent(def_id).map(|parent| tcx.def_kind(parent)), Some(DefKind::Impl { of_trait: true }) - )); + ); self.prove_predicates( args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())), locations, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 6cbf2dbf7d3fd..8317a228fd460 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -13,6 +13,7 @@ use rustc_codegen_ssa::mir::debuginfo::VariableKind::*; use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::*; use rustc_data_structures::unord::UnordMap; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_index::IndexVec; use rustc_middle::mir; @@ -533,13 +534,13 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. - if let Some(impl_def_id) = cx.tcx.impl_of_assoc(instance.def_id()) { + if let Some(assoc_parent) = cx.tcx.assoc_parent(instance.def_id()) { // If the method does *not* belong to a trait, proceed - if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { + if cx.tcx.def_kind(assoc_parent) == (DefKind::Impl { of_trait: false }) { let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions( instance.args, cx.typing_env(), - cx.tcx.type_of(impl_def_id), + cx.tcx.type_of(assoc_parent), ); // Only "class" methods are generally understood by LLVM, diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index a0160d1188d08..35624a67d81c2 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -731,7 +731,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) { let tcx = *self.tcx; - let trait_def_id = tcx.trait_of_assoc(def_id).unwrap(); + let trait_def_id = tcx.parent(def_id); let virtual_trait_ref = ty::TraitRef::from_assoc(tcx, trait_def_id, virtual_instance.args); let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref); let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 6767e5ed88d4d..e482725619398 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -445,10 +445,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( tcx: TyCtxt<'tcx>, impl_m_def_id: LocalDefId, ) -> Result<&'tcx DefIdMap>>, ErrorGuaranteed> { - let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap(); - let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap(); + let impl_m = tcx.associated_item(impl_m_def_id.to_def_id()); + let trait_m = tcx.associated_item(impl_m.trait_item_def_id.unwrap()); let impl_trait_ref = - tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity(); + tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).unwrap().instantiate_identity(); // First, check a few of the same things as `compare_impl_method`, // just so we don't ICE during instantiation later. check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index ef88e02fd98c2..d2434c3d9ed0c 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -695,7 +695,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { // i.e. changing `Default::default()` to `<() as Default>::default()`. if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let Res::Def(DefKind::AssocFn, def_id) = path.res - && self.fcx.tcx.trait_of_assoc(def_id).is_some() + && self.fcx.tcx.def_kind(self.fcx.tcx.parent(def_id)) == DefKind::Trait && let Some(args) = self.fcx.typeck_results.borrow().node_args_opt(expr.hir_id) && let self_ty = args.type_at(0) && let Some(vid) = self.fcx.root_vid(self_ty) diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 4f65acd8001ed..6b9101a41ff0e 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -1,5 +1,5 @@ use rustc_hir::attrs::AttributeKind; -use rustc_hir::def::Res; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind, find_attr}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -24,10 +24,10 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) { match &ty.kind { TyKind::Ref(_, hir::MutTy { ty: inner_ty, mutbl: hir::Mutability::Not }) => { - if let Some(impl_did) = cx.tcx.impl_of_assoc(ty.hir_id.owner.to_def_id()) { - if cx.tcx.impl_trait_ref(impl_did).is_some() { - return; - } + if let Some(parent) = cx.tcx.assoc_parent(ty.hir_id.owner.to_def_id()) + && cx.tcx.def_kind(parent) == (DefKind::Impl { of_trait: true }) + { + return; } if let Some(t) = path_for_pass_by_value(cx, inner_ty) { cx.emit_span_lint( diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index b0afc333ebe2f..9c65203f8b1df 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -4,6 +4,7 @@ use std::ops::ControlFlow; use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagMessage; +use rustc_hir::def::DefKind; use rustc_hir::intravisit::VisitorExt; use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem}; use rustc_middle::bug; @@ -1904,10 +1905,10 @@ impl InvalidAtomicOrdering { if let ExprKind::MethodCall(method_path, _, args, _) = &expr.kind && recognized_names.contains(&method_path.ident.name) && let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && let Some(impl_did) = cx.tcx.impl_of_assoc(m_def_id) - && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() + && let impl_did = cx.tcx.parent(m_def_id) // skip extension traits, only lint functions from the standard library - && cx.tcx.trait_id_of_impl(impl_did).is_none() + && cx.tcx.def_kind(impl_did) == (DefKind::Impl { of_trait: false }) + && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() && let parent = cx.tcx.parent(adt.did()) && cx.tcx.is_diagnostic_item(sym::atomic_mod, parent) && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did())) diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 785ddd1ee2980..3071ec15b6ab3 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -180,11 +180,10 @@ impl EffectiveVisibilities { // All effective visibilities except `reachable_through_impl_trait` are limited to // nominal visibility. For some items nominal visibility doesn't make sense so we // don't check this condition for them. - let is_impl = matches!(tcx.def_kind(def_id), DefKind::Impl { .. }); - let is_associated_item_in_trait_impl = tcx - .impl_of_assoc(def_id.to_def_id()) - .and_then(|impl_id| tcx.trait_id_of_impl(impl_id)) - .is_some(); + let def_kind = tcx.def_kind(def_id); + let is_impl = matches!(def_kind, DefKind::Impl { .. }); + let is_associated_item_in_trait_impl = def_kind.is_assoc() + && tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::Impl { of_trait: true }; if !is_impl && !is_associated_item_in_trait_impl { let nominal_vis = tcx.visibility(def_id); if !nominal_vis.is_at_least(ev.reachable, tcx) { diff --git a/compiler/rustc_mir_transform/src/check_call_recursion.rs b/compiler/rustc_mir_transform/src/check_call_recursion.rs index 6d61ac2dd8037..53ad0222fe997 100644 --- a/compiler/rustc_mir_transform/src/check_call_recursion.rs +++ b/compiler/rustc_mir_transform/src/check_call_recursion.rs @@ -43,8 +43,9 @@ impl<'tcx> MirLint<'tcx> for CheckDropRecursion { // First check if `body` is an `fn drop()` of `Drop` if let DefKind::AssocFn = tcx.def_kind(def_id) - && let Some(trait_ref) = - tcx.impl_of_assoc(def_id.to_def_id()).and_then(|def_id| tcx.impl_trait_ref(def_id)) + && let impl_id = tcx.parent(def_id.to_def_id()) + && tcx.def_kind(impl_id) == (DefKind::Impl { of_trait: true }) + && let trait_ref = tcx.impl_trait_ref(impl_id).unwrap() && tcx.is_lang_item(trait_ref.instantiate_identity().def_id, LangItem::Drop) // avoid erroneous `Drop` impls from causing ICEs below && let sig = tcx.fn_sig(def_id).instantiate_identity() diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index dcb812c78993e..e5c41e8f63ef1 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -1,3 +1,4 @@ +use rustc_hir::def::DefKind; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::span_bug; @@ -40,7 +41,8 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.typing_env, *place) { let def_id = self.body.source.instance.def_id(); - if let Some(impl_def_id) = self.tcx.impl_of_assoc(def_id) + if let Some(impl_def_id) = self.tcx.assoc_parent(def_id) + && self.tcx.def_kind(impl_def_id) == (DefKind::Impl { of_trait: true }) && self.tcx.is_builtin_derived(impl_def_id) { // If we ever reach here it means that the generated derive diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index c687036f544dc..c6760b3583f20 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -75,7 +75,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< build_call_shim(tcx, instance, Some(adjustment), CallKind::Direct(def_id)) } ty::InstanceKind::FnPtrShim(def_id, ty) => { - let trait_ = tcx.trait_of_assoc(def_id).unwrap(); + let trait_ = tcx.parent(def_id); // Supports `Fn` or `async Fn` traits. let adjustment = match tcx .fn_trait_kind_from_def_id(trait_) diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index d76b27d9970b6..df62708f84327 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -650,17 +650,18 @@ fn characteristic_def_id_of_mono_item<'tcx>( // its self-type. If the self-type does not provide a characteristic // DefId, we use the location of the impl after all. - if tcx.trait_of_assoc(def_id).is_some() { + let assoc_parent = tcx.assoc_parent(def_id).map(|id| (id, tcx.def_kind(id))); + + if let Some((_, DefKind::Trait)) = assoc_parent { let self_ty = instance.args.type_at(0); // This is a default implementation of a trait method. return characteristic_def_id_of_type(self_ty).or(Some(def_id)); } - if let Some(impl_def_id) = tcx.impl_of_assoc(def_id) { - if tcx.sess.opts.incremental.is_some() - && tcx - .trait_id_of_impl(impl_def_id) - .is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Drop)) + if let Some((impl_def_id, DefKind::Impl { of_trait })) = assoc_parent { + if of_trait + && tcx.sess.opts.incremental.is_some() + && tcx.is_lang_item(tcx.trait_id_of_impl(impl_def_id).unwrap(), LangItem::Drop) { // Put `Drop::drop` into the same cgu as `drop_in_place` // since `drop_in_place` is the only thing that can diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 581191b2036d2..884d53732fe2a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1507,7 +1507,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( let tcx = selcx.tcx(); let self_ty = obligation.predicate.self_ty(); let item_def_id = obligation.predicate.def_id; - let trait_def_id = tcx.trait_of_assoc(item_def_id).unwrap(); + let trait_def_id = tcx.parent(item_def_id); let args = tcx.mk_args(&[self_ty.into()]); let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) { let discriminant_def_id =