Skip to content

Commit 637b50b

Browse files
committed
Auto merge of #145186 - camsteffen:assoc-impl-kind, r=petrochenkov
Make `AssocItem` aware of its impl kind The general goal is to have fewer query dependencies by making `AssocItem` aware of its parent impl kind (inherent vs. trait) without having to query the parent def_kind. See individual commits.
2 parents b50f345 + b995a55 commit 637b50b

File tree

59 files changed

+386
-404
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+386
-404
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
55
use rustc_hir::attrs::AttributeKind;
66
use rustc_hir::def::{DefKind, PerNS, Res};
77
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
8-
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, Target, find_attr};
8+
use rustc_hir::{
9+
self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr,
10+
};
911
use rustc_index::{IndexSlice, IndexVec};
1012
use rustc_middle::span_bug;
1113
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -1117,20 +1119,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
11171119
}
11181120
};
11191121

1122+
let span = self.lower_span(i.span);
11201123
let item = hir::ImplItem {
11211124
owner_id: hir_id.expect_owner(),
11221125
ident: self.lower_ident(ident),
11231126
generics,
1127+
impl_kind: if is_in_trait_impl {
1128+
ImplItemImplKind::Trait {
1129+
defaultness,
1130+
trait_item_def_id: self
1131+
.resolver
1132+
.get_partial_res(i.id)
1133+
.and_then(|r| r.expect_full_res().opt_def_id())
1134+
.ok_or_else(|| {
1135+
self.dcx().span_delayed_bug(
1136+
span,
1137+
"could not resolve trait item being implemented",
1138+
)
1139+
}),
1140+
}
1141+
} else {
1142+
ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) }
1143+
},
11241144
kind,
1125-
vis_span: self.lower_span(i.vis.span),
1126-
span: self.lower_span(i.span),
1127-
defaultness,
1145+
span,
11281146
has_delayed_lints: !self.delayed_lints.is_empty(),
1129-
trait_item_def_id: self
1130-
.resolver
1131-
.get_partial_res(i.id)
1132-
.map(|r| r.expect_full_res().opt_def_id())
1133-
.unwrap_or(None),
11341147
};
11351148
self.arena.alloc(item)
11361149
}

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
716716
return (false, false, None);
717717
};
718718

719-
let implemented_trait_item = self.infcx.tcx.associated_item(my_def).trait_item_def_id;
719+
let implemented_trait_item = self.infcx.tcx.trait_item_of(my_def);
720720

721721
(
722722
true,

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -562,15 +562,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
562562
codegen_fn_attrs
563563
}
564564

565-
/// If the provided DefId is a method in a trait impl, return the DefId of the method prototype.
566-
fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
567-
let impl_item = tcx.opt_associated_item(def_id)?;
568-
match impl_item.container {
569-
ty::AssocItemContainer::Impl => impl_item.trait_item_def_id,
570-
_ => None,
571-
}
572-
}
573-
574565
fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
575566
// Backtrack to the crate root.
576567
let mut disabled = match tcx.opt_local_parent(did) {
@@ -600,14 +591,15 @@ fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
600591
/// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
601592
/// applied to the method prototype.
602593
fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
603-
let Some(trait_item) = opt_trait_item(tcx, def_id) else { return false };
604-
tcx.codegen_fn_attrs(trait_item).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER)
594+
tcx.trait_item_of(def_id).is_some_and(|id| {
595+
tcx.codegen_fn_attrs(id).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER)
596+
})
605597
}
606598

607599
/// If the provided DefId is a method in a trait impl, return the value of the `#[align]`
608600
/// attribute on the method prototype (if any).
609601
fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
610-
tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment
602+
tcx.codegen_fn_attrs(tcx.trait_item_of(def_id)?).alignment
611603
}
612604

613605
/// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]

compiler/rustc_hir/src/hir.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,12 +3220,21 @@ pub struct ImplItem<'hir> {
32203220
pub owner_id: OwnerId,
32213221
pub generics: &'hir Generics<'hir>,
32223222
pub kind: ImplItemKind<'hir>,
3223-
pub defaultness: Defaultness,
3223+
pub impl_kind: ImplItemImplKind,
32243224
pub span: Span,
3225-
pub vis_span: Span,
32263225
pub has_delayed_lints: bool,
3227-
/// When we are in a trait impl, link to the trait-item's id.
3228-
pub trait_item_def_id: Option<DefId>,
3226+
}
3227+
3228+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
3229+
pub enum ImplItemImplKind {
3230+
Inherent {
3231+
vis_span: Span,
3232+
},
3233+
Trait {
3234+
defaultness: Defaultness,
3235+
/// Item in the trait that this item implements
3236+
trait_item_def_id: Result<DefId, ErrorGuaranteed>,
3237+
},
32293238
}
32303239

32313240
impl<'hir> ImplItem<'hir> {
@@ -3239,6 +3248,13 @@ impl<'hir> ImplItem<'hir> {
32393248
ImplItemId { owner_id: self.owner_id }
32403249
}
32413250

3251+
pub fn vis_span(&self) -> Option<Span> {
3252+
match self.impl_kind {
3253+
ImplItemImplKind::Trait { .. } => None,
3254+
ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span),
3255+
}
3256+
}
3257+
32423258
expect_methods_self_kind! {
32433259
expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
32443260
expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
@@ -4985,7 +5001,7 @@ mod size_asserts {
49855001
static_assert_size!(GenericBound<'_>, 64);
49865002
static_assert_size!(Generics<'_>, 56);
49875003
static_assert_size!(Impl<'_>, 40);
4988-
static_assert_size!(ImplItem<'_>, 96);
5004+
static_assert_size!(ImplItem<'_>, 88);
49895005
static_assert_size!(ImplItemKind<'_>, 40);
49905006
static_assert_size!(Item<'_>, 88);
49915007
static_assert_size!(ItemKind<'_>, 64);

compiler/rustc_hir/src/intravisit.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,18 +1257,21 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
12571257
owner_id: _,
12581258
ident,
12591259
ref generics,
1260+
ref impl_kind,
12601261
ref kind,
1261-
ref defaultness,
12621262
span: _,
1263-
vis_span: _,
12641263
has_delayed_lints: _,
1265-
trait_item_def_id: _,
12661264
} = *impl_item;
12671265

12681266
try_visit!(visitor.visit_ident(ident));
12691267
try_visit!(visitor.visit_generics(generics));
1270-
try_visit!(visitor.visit_defaultness(defaultness));
12711268
try_visit!(visitor.visit_id(impl_item.hir_id()));
1269+
match impl_kind {
1270+
ImplItemImplKind::Inherent { vis_span: _ } => {}
1271+
ImplItemImplKind::Trait { defaultness, trait_item_def_id: _ } => {
1272+
try_visit!(visitor.visit_defaultness(defaultness));
1273+
}
1274+
}
12721275
match *kind {
12731276
ImplItemKind::Const(ref ty, body) => {
12741277
try_visit!(visitor.visit_ty_unambig(ty));

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
10091009
res = res.and(check_associated_item(tcx, def_id));
10101010
let assoc_item = tcx.associated_item(def_id);
10111011
match assoc_item.container {
1012-
ty::AssocItemContainer::Impl => {}
1013-
ty::AssocItemContainer::Trait => {
1012+
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
1013+
ty::AssocContainer::Trait => {
10141014
res = res.and(check_trait_item(tcx, def_id));
10151015
}
10161016
}
@@ -1026,8 +1026,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
10261026
res = res.and(check_associated_item(tcx, def_id));
10271027
let assoc_item = tcx.associated_item(def_id);
10281028
match assoc_item.container {
1029-
ty::AssocItemContainer::Impl => {}
1030-
ty::AssocItemContainer::Trait => {
1029+
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
1030+
ty::AssocContainer::Trait => {
10311031
res = res.and(check_trait_item(tcx, def_id));
10321032
}
10331033
}
@@ -1043,8 +1043,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
10431043

10441044
let assoc_item = tcx.associated_item(def_id);
10451045
let has_type = match assoc_item.container {
1046-
ty::AssocItemContainer::Impl => true,
1047-
ty::AssocItemContainer::Trait => {
1046+
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
1047+
ty::AssocContainer::Trait => {
10481048
tcx.ensure_ok().explicit_item_bounds(def_id);
10491049
tcx.ensure_ok().explicit_item_self_bounds(def_id);
10501050
if tcx.is_conditionally_const(def_id) {
@@ -1177,12 +1177,9 @@ fn check_impl_items_against_trait<'tcx>(
11771177

11781178
for &impl_item in impl_item_refs {
11791179
let ty_impl_item = tcx.associated_item(impl_item);
1180-
let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id {
1181-
tcx.associated_item(trait_item_id)
1182-
} else {
1183-
// Checked in `associated_item`.
1184-
tcx.dcx().span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait");
1185-
continue;
1180+
let ty_trait_item = match ty_impl_item.expect_trait_impl() {
1181+
Ok(trait_item_id) => tcx.associated_item(trait_item_id),
1182+
Err(ErrorGuaranteed { .. }) => continue,
11861183
};
11871184

11881185
let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local());

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub(super) fn compare_impl_item(
3737
impl_item_def_id: LocalDefId,
3838
) -> Result<(), ErrorGuaranteed> {
3939
let impl_item = tcx.associated_item(impl_item_def_id);
40-
let trait_item = tcx.associated_item(impl_item.trait_item_def_id.unwrap());
40+
let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?);
4141
let impl_trait_ref =
4242
tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity();
4343
debug!(?impl_trait_ref);
@@ -446,7 +446,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
446446
impl_m_def_id: LocalDefId,
447447
) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
448448
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());
449+
let trait_m = tcx.associated_item(impl_m.expect_trait_impl()?);
450450
let impl_trait_ref =
451451
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`,
@@ -1449,8 +1449,10 @@ fn compare_self_type<'tcx>(
14491449

14501450
let self_string = |method: ty::AssocItem| {
14511451
let untransformed_self_ty = match method.container {
1452-
ty::AssocItemContainer::Impl => impl_trait_ref.self_ty(),
1453-
ty::AssocItemContainer::Trait => tcx.types.self_param,
1452+
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
1453+
impl_trait_ref.self_ty()
1454+
}
1455+
ty::AssocContainer::Trait => tcx.types.self_param,
14541456
};
14551457
let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0);
14561458
let (infcx, param_env) = tcx
@@ -2458,8 +2460,12 @@ fn param_env_with_gat_bounds<'tcx>(
24582460

24592461
for impl_ty in impl_tys_to_install {
24602462
let trait_ty = match impl_ty.container {
2461-
ty::AssocItemContainer::Trait => impl_ty,
2462-
ty::AssocItemContainer::Impl => tcx.associated_item(impl_ty.trait_item_def_id.unwrap()),
2463+
ty::AssocContainer::InherentImpl => bug!(),
2464+
ty::AssocContainer::Trait => impl_ty,
2465+
ty::AssocContainer::TraitImpl(Err(_)) => continue,
2466+
ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) => {
2467+
tcx.associated_item(trait_item_def_id)
2468+
}
24632469
};
24642470

24652471
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -944,12 +944,11 @@ pub(crate) fn check_associated_item(
944944

945945
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
946946
// other `Foo` impls are incoherent.
947-
tcx.ensure_ok()
948-
.coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
947+
tcx.ensure_ok().coherent_trait(tcx.parent(item.trait_item_or_self()?))?;
949948

950949
let self_ty = match item.container {
951-
ty::AssocItemContainer::Trait => tcx.types.self_param,
952-
ty::AssocItemContainer::Impl => {
950+
ty::AssocContainer::Trait => tcx.types.self_param,
951+
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
953952
tcx.type_of(item.container_id(tcx)).instantiate_identity()
954953
}
955954
};
@@ -978,7 +977,7 @@ pub(crate) fn check_associated_item(
978977
check_method_receiver(wfcx, hir_sig, item, self_ty)
979978
}
980979
ty::AssocKind::Type { .. } => {
981-
if let ty::AssocItemContainer::Trait = item.container {
980+
if let ty::AssocContainer::Trait = item.container {
982981
check_associated_type_bounds(wfcx, item, span)
983982
}
984983
if item.defaultness(tcx).has_value() {

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
111111
}
112112

113113
Some(ImplTraitInTraitData::Impl { fn_def_id }) => {
114-
let assoc_item = tcx.associated_item(def_id);
115-
let trait_assoc_predicates =
116-
tcx.explicit_predicates_of(assoc_item.trait_item_def_id.unwrap());
114+
let trait_item_def_id = tcx.trait_item_of(def_id).unwrap();
115+
let trait_assoc_predicates = tcx.explicit_predicates_of(trait_item_def_id);
117116

118117
let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
119118
let impl_def_id = tcx.parent(fn_def_id);

compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
125125
Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => {
126126
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
127127
Ok(map) => {
128-
let assoc_item = tcx.associated_item(def_id);
129-
return map[&assoc_item.trait_item_def_id.unwrap()];
128+
let trait_item_def_id = tcx.trait_item_of(def_id).unwrap();
129+
return map[&trait_item_def_id];
130130
}
131131
Err(_) => {
132132
return ty::EarlyBinder::bind(Ty::new_error_with_message(
@@ -198,7 +198,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
198198
}
199199
}
200200
ImplItemKind::Type(ty) => {
201-
if tcx.impl_trait_ref(tcx.hir_get_parent_item(hir_id)).is_none() {
201+
if let ImplItemImplKind::Inherent { .. } = item.impl_kind {
202202
check_feature_inherent_assoc_ty(tcx, item.span);
203203
}
204204

0 commit comments

Comments
 (0)