Skip to content

Commit 8654867

Browse files
authored
Rollup merge of #145266 - camsteffen:reduce-queries, r=petrochenkov
Reduce some queries around associated items
2 parents 5d7b985 + d4eb094 commit 8654867

File tree

16 files changed

+79
-64
lines changed

16 files changed

+79
-64
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,12 +677,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
677677
/// - is the trait from the local crate? If not, we can't suggest changing signatures
678678
/// - `Span` of the argument in the trait definition
679679
fn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>) {
680+
let tcx = self.infcx.tcx;
680681
if self.body.local_kind(local) != LocalKind::Arg {
681682
return (false, false, None);
682683
}
683684
let my_def = self.body.source.def_id();
684685
let Some(td) =
685-
self.infcx.tcx.impl_of_assoc(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x))
686+
tcx.trait_impl_of_assoc(my_def).and_then(|id| self.infcx.tcx.trait_id_of_impl(id))
686687
else {
687688
return (false, false, None);
688689
};

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,10 +1773,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
17731773
locations,
17741774
);
17751775

1776-
assert!(!matches!(
1777-
tcx.impl_of_assoc(def_id).map(|imp| tcx.def_kind(imp)),
1778-
Some(DefKind::Impl { of_trait: true })
1779-
));
1776+
assert_eq!(tcx.trait_impl_of_assoc(def_id), None);
17801777
self.prove_predicates(
17811778
args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())),
17821779
locations,

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -533,31 +533,26 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
533533
// First, let's see if this is a method within an inherent impl. Because
534534
// if yes, we want to make the result subroutine DIE a child of the
535535
// subroutine's self-type.
536-
if let Some(impl_def_id) = cx.tcx.impl_of_assoc(instance.def_id()) {
537-
// If the method does *not* belong to a trait, proceed
538-
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
539-
let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
540-
instance.args,
541-
cx.typing_env(),
542-
cx.tcx.type_of(impl_def_id),
543-
);
544-
545-
// Only "class" methods are generally understood by LLVM,
546-
// so avoid methods on other types (e.g., `<*mut T>::null`).
547-
if let ty::Adt(def, ..) = impl_self_ty.kind()
548-
&& !def.is_box()
549-
{
550-
// Again, only create type information if full debuginfo is enabled
551-
if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param()
552-
{
553-
return (type_di_node(cx, impl_self_ty), true);
554-
} else {
555-
return (namespace::item_namespace(cx, def.did()), false);
556-
}
536+
// For trait method impls we still use the "parallel namespace"
537+
// strategy
538+
if let Some(imp_def_id) = cx.tcx.inherent_impl_of_assoc(instance.def_id()) {
539+
let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
540+
instance.args,
541+
cx.typing_env(),
542+
cx.tcx.type_of(imp_def_id),
543+
);
544+
545+
// Only "class" methods are generally understood by LLVM,
546+
// so avoid methods on other types (e.g., `<*mut T>::null`).
547+
if let ty::Adt(def, ..) = impl_self_ty.kind()
548+
&& !def.is_box()
549+
{
550+
// Again, only create type information if full debuginfo is enabled
551+
if cx.sess().opts.debuginfo == DebugInfo::Full && !impl_self_ty.has_param() {
552+
return (type_di_node(cx, impl_self_ty), true);
553+
} else {
554+
return (namespace::item_namespace(cx, def.did()), false);
557555
}
558-
} else {
559-
// For trait method impls we still use the "parallel namespace"
560-
// strategy
561556
}
562557
}
563558

compiler/rustc_const_eval/src/interpret/call.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
731731
) {
732732
let tcx = *self.tcx;
733733

734-
let trait_def_id = tcx.trait_of_assoc(def_id).unwrap();
734+
let trait_def_id = tcx.parent(def_id);
735735
let virtual_trait_ref = ty::TraitRef::from_assoc(tcx, trait_def_id, virtual_instance.args);
736736
let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
737737
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
445445
tcx: TyCtxt<'tcx>,
446446
impl_m_def_id: LocalDefId,
447447
) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
448-
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
449-
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
448+
let impl_m = tcx.associated_item(impl_m_def_id.to_def_id());
449+
let trait_m = tcx.associated_item(impl_m.trait_item_def_id.unwrap());
450450
let impl_trait_ref =
451-
tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
451+
tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).unwrap().instantiate_identity();
452452
// First, check a few of the same things as `compare_impl_method`,
453453
// just so we don't ICE during instantiation later.
454454
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,8 +2287,7 @@ fn lint_redundant_lifetimes<'tcx>(
22872287
// Proceed
22882288
}
22892289
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
2290-
let parent_def_id = tcx.local_parent(owner_id);
2291-
if matches!(tcx.def_kind(parent_def_id), DefKind::Impl { of_trait: true }) {
2290+
if tcx.trait_impl_of_assoc(owner_id.to_def_id()).is_some() {
22922291
// Don't check for redundant lifetimes for associated items of trait
22932292
// implementations, since the signature is required to be compatible
22942293
// with the trait, even if the implementation implies some lifetimes

compiler/rustc_lint/src/pass_by_value.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
2424
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
2525
match &ty.kind {
2626
TyKind::Ref(_, hir::MutTy { ty: inner_ty, mutbl: hir::Mutability::Not }) => {
27-
if let Some(impl_did) = cx.tcx.impl_of_assoc(ty.hir_id.owner.to_def_id()) {
28-
if cx.tcx.impl_trait_ref(impl_did).is_some() {
29-
return;
30-
}
27+
if cx.tcx.trait_impl_of_assoc(ty.hir_id.owner.to_def_id()).is_some() {
28+
return;
3129
}
3230
if let Some(t) = path_for_pass_by_value(cx, inner_ty) {
3331
cx.emit_span_lint(

compiler/rustc_lint/src/types.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,10 +1904,9 @@ impl InvalidAtomicOrdering {
19041904
if let ExprKind::MethodCall(method_path, _, args, _) = &expr.kind
19051905
&& recognized_names.contains(&method_path.ident.name)
19061906
&& let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
1907-
&& let Some(impl_did) = cx.tcx.impl_of_assoc(m_def_id)
1908-
&& let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def()
19091907
// skip extension traits, only lint functions from the standard library
1910-
&& cx.tcx.trait_id_of_impl(impl_did).is_none()
1908+
&& let Some(impl_did) = cx.tcx.inherent_impl_of_assoc(m_def_id)
1909+
&& let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def()
19111910
&& let parent = cx.tcx.parent(adt.did())
19121911
&& cx.tcx.is_diagnostic_item(sym::atomic_mod, parent)
19131912
&& ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did()))

compiler/rustc_middle/src/middle/privacy.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,7 @@ impl EffectiveVisibilities {
181181
// nominal visibility. For some items nominal visibility doesn't make sense so we
182182
// don't check this condition for them.
183183
let is_impl = matches!(tcx.def_kind(def_id), DefKind::Impl { .. });
184-
let is_associated_item_in_trait_impl = tcx
185-
.impl_of_assoc(def_id.to_def_id())
186-
.and_then(|impl_id| tcx.trait_id_of_impl(impl_id))
187-
.is_some();
188-
if !is_impl && !is_associated_item_in_trait_impl {
184+
if !is_impl && tcx.trait_impl_of_assoc(def_id.to_def_id()).is_none() {
189185
let nominal_vis = tcx.visibility(def_id);
190186
if !nominal_vis.is_at_least(ev.reachable, tcx) {
191187
span_bug!(

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,21 +1925,50 @@ impl<'tcx> TyCtxt<'tcx> {
19251925
self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id)
19261926
}
19271927

1928-
/// If the given `DefId` is an associated item, returns the `DefId` of the parent trait or impl.
1929-
pub fn assoc_parent(self, def_id: DefId) -> Option<DefId> {
1930-
self.def_kind(def_id).is_assoc().then(|| self.parent(def_id))
1928+
/// If the given `DefId` is an associated item, returns the `DefId` and `DefKind` of the parent trait or impl.
1929+
pub fn assoc_parent(self, def_id: DefId) -> Option<(DefId, DefKind)> {
1930+
if !self.def_kind(def_id).is_assoc() {
1931+
return None;
1932+
}
1933+
let parent = self.parent(def_id);
1934+
let def_kind = self.def_kind(parent);
1935+
Some((parent, def_kind))
19311936
}
19321937

19331938
/// If the given `DefId` is an associated item of a trait,
19341939
/// returns the `DefId` of the trait; otherwise, returns `None`.
19351940
pub fn trait_of_assoc(self, def_id: DefId) -> Option<DefId> {
1936-
self.assoc_parent(def_id).filter(|id| self.def_kind(id) == DefKind::Trait)
1941+
match self.assoc_parent(def_id) {
1942+
Some((id, DefKind::Trait)) => Some(id),
1943+
_ => None,
1944+
}
19371945
}
19381946

19391947
/// If the given `DefId` is an associated item of an impl,
19401948
/// returns the `DefId` of the impl; otherwise returns `None`.
19411949
pub fn impl_of_assoc(self, def_id: DefId) -> Option<DefId> {
1942-
self.assoc_parent(def_id).filter(|id| matches!(self.def_kind(id), DefKind::Impl { .. }))
1950+
match self.assoc_parent(def_id) {
1951+
Some((id, DefKind::Impl { .. })) => Some(id),
1952+
_ => None,
1953+
}
1954+
}
1955+
1956+
/// If the given `DefId` is an associated item of an inherent impl,
1957+
/// returns the `DefId` of the impl; otherwise, returns `None`.
1958+
pub fn inherent_impl_of_assoc(self, def_id: DefId) -> Option<DefId> {
1959+
match self.assoc_parent(def_id) {
1960+
Some((id, DefKind::Impl { of_trait: false })) => Some(id),
1961+
_ => None,
1962+
}
1963+
}
1964+
1965+
/// If the given `DefId` is an associated item of a trait impl,
1966+
/// returns the `DefId` of the impl; otherwise, returns `None`.
1967+
pub fn trait_impl_of_assoc(self, def_id: DefId) -> Option<DefId> {
1968+
match self.assoc_parent(def_id) {
1969+
Some((id, DefKind::Impl { of_trait: true })) => Some(id),
1970+
_ => None,
1971+
}
19431972
}
19441973

19451974
pub fn is_exportable(self, def_id: DefId) -> bool {

0 commit comments

Comments
 (0)