Skip to content

Commit 18b3463

Browse files
committed
Introduce hir::ImplItemImplKind
1 parent ca77504 commit 18b3463

File tree

15 files changed

+133
-91
lines changed

15 files changed

+133
-91
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
66
use rustc_hir::attrs::AttributeKind;
77
use rustc_hir::def::{DefKind, PerNS, Res};
88
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
9-
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, find_attr};
9+
use rustc_hir::{self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, find_attr};
1010
use rustc_index::{IndexSlice, IndexVec};
1111
use rustc_middle::span_bug;
1212
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -1101,16 +1101,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
11011101
owner_id: hir_id.expect_owner(),
11021102
ident: self.lower_ident(ident),
11031103
generics,
1104+
impl_kind: if is_in_trait_impl {
1105+
ImplItemImplKind::Trait {
1106+
defaultness,
1107+
trait_item_def_id: self
1108+
.resolver
1109+
.get_partial_res(i.id)
1110+
.map(|r| r.expect_full_res().opt_def_id())
1111+
.unwrap_or(None),
1112+
}
1113+
} else {
1114+
ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) }
1115+
},
11041116
kind,
1105-
vis_span: self.lower_span(i.vis.span),
11061117
span: self.lower_span(i.span),
1107-
defaultness,
11081118
has_delayed_lints: !self.delayed_lints.is_empty(),
1109-
trait_item_def_id: self
1110-
.resolver
1111-
.get_partial_res(i.id)
1112-
.map(|r| r.expect_full_res().opt_def_id())
1113-
.unwrap_or(None),
11141119
};
11151120
self.arena.alloc(item)
11161121
}

compiler/rustc_hir/src/hir.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3190,12 +3190,22 @@ pub struct ImplItem<'hir> {
31903190
pub owner_id: OwnerId,
31913191
pub generics: &'hir Generics<'hir>,
31923192
pub kind: ImplItemKind<'hir>,
3193-
pub defaultness: Defaultness,
3193+
pub impl_kind: ImplItemImplKind,
31943194
pub span: Span,
3195-
pub vis_span: Span,
31963195
pub has_delayed_lints: bool,
3197-
/// When we are in a trait impl, link to the trait-item's id.
3198-
pub trait_item_def_id: Option<DefId>,
3196+
}
3197+
3198+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
3199+
pub enum ImplItemImplKind {
3200+
Inherent {
3201+
vis_span: Span,
3202+
},
3203+
Trait {
3204+
defaultness: Defaultness,
3205+
/// Item in the trait that this item implements.
3206+
/// May be `None` if there is an error.
3207+
trait_item_def_id: Option<DefId>,
3208+
},
31993209
}
32003210

32013211
impl<'hir> ImplItem<'hir> {
@@ -3209,6 +3219,13 @@ impl<'hir> ImplItem<'hir> {
32093219
ImplItemId { owner_id: self.owner_id }
32103220
}
32113221

3222+
pub fn vis_span(&self) -> Option<Span> {
3223+
match self.impl_kind {
3224+
ImplItemImplKind::Trait { .. } => None,
3225+
ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span),
3226+
}
3227+
}
3228+
32123229
expect_methods_self_kind! {
32133230
expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
32143231
expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
@@ -4953,7 +4970,7 @@ mod size_asserts {
49534970
static_assert_size!(GenericBound<'_>, 64);
49544971
static_assert_size!(Generics<'_>, 56);
49554972
static_assert_size!(Impl<'_>, 80);
4956-
static_assert_size!(ImplItem<'_>, 96);
4973+
static_assert_size!(ImplItem<'_>, 88);
49574974
static_assert_size!(ImplItemKind<'_>, 40);
49584975
static_assert_size!(Item<'_>, 88);
49594976
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/collect/type_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

compiler/rustc_lint/src/builtin.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_hir::attrs::AttributeKind;
2828
use rustc_hir::def::{DefKind, Res};
2929
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
3030
use rustc_hir::intravisit::FnKind as HirFnKind;
31-
use rustc_hir::{Body, FnDecl, PatKind, PredicateOrigin, find_attr};
31+
use rustc_hir::{Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr};
3232
use rustc_middle::bug;
3333
use rustc_middle::lint::LevelAndSource;
3434
use rustc_middle::ty::layout::LayoutOf;
@@ -1310,9 +1310,8 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
13101310
}
13111311

13121312
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
1313-
// Only lint inherent impl items.
1314-
if cx.tcx.associated_item(impl_item.owner_id).trait_item_def_id.is_none() {
1315-
self.perform_lint(cx, "item", impl_item.owner_id.def_id, impl_item.vis_span, false);
1313+
if let ImplItemImplKind::Inherent { vis_span } = impl_item.impl_kind {
1314+
self.perform_lint(cx, "item", impl_item.owner_id.def_id, vis_span, false);
13161315
}
13171316
}
13181317
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,7 +2206,16 @@ impl<'tcx> TyCtxt<'tcx> {
22062206

22072207
let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
22082208
Node::Item(..) | Node::TraitItem(..) => false,
2209-
Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2209+
Node::ImplItem(impl_item) => match impl_item.impl_kind {
2210+
// For now, we do not try to target impls of traits. This is
2211+
// because this message is going to suggest that the user
2212+
// change the fn signature, but they may not be free to do so,
2213+
// since the signature must match the trait.
2214+
//
2215+
// FIXME(#42706) -- in some cases, we could do better here.
2216+
hir::ImplItemImplKind::Trait { .. } => true,
2217+
_ => false,
2218+
},
22102219
_ => false,
22112220
};
22122221

@@ -2260,21 +2269,6 @@ impl<'tcx> TyCtxt<'tcx> {
22602269
None
22612270
}
22622271

2263-
/// Checks if the bound region is in Impl Item.
2264-
pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2265-
let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2266-
if self.impl_trait_ref(container_id).is_some() {
2267-
// For now, we do not try to target impls of traits. This is
2268-
// because this message is going to suggest that the user
2269-
// change the fn signature, but they may not be free to do so,
2270-
// since the signature must match the trait.
2271-
//
2272-
// FIXME(#42706) -- in some cases, we could do better here.
2273-
return true;
2274-
}
2275-
false
2276-
}
2277-
22782272
/// Determines whether identifiers in the assembly have strict naming rules.
22792273
/// Currently, only NVPTX* targets need it.
22802274
pub fn has_strict_asm_symbol_naming(self) -> bool {

compiler/rustc_passes/src/dead.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -372,31 +372,27 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
372372
/// Automatically generated items marked with `rustc_trivial_field_reads`
373373
/// will be ignored for the purposes of dead code analysis (see PR #85200
374374
/// for discussion).
375-
fn should_ignore_item(&mut self, def_id: DefId) -> bool {
376-
if let Some(impl_of) = self.tcx.impl_of_assoc(def_id) {
377-
if !self.tcx.is_automatically_derived(impl_of) {
378-
return false;
379-
}
380-
381-
if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
382-
&& self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
375+
fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool {
376+
if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind
377+
&& let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id())
378+
&& self.tcx.is_automatically_derived(impl_of)
379+
&& let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity()
380+
&& self.tcx.has_attr(trait_ref.def_id, sym::rustc_trivial_field_reads)
381+
{
382+
if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
383+
&& let Some(adt_def_id) = adt_def.did().as_local()
383384
{
384-
let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity();
385-
if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
386-
&& let Some(adt_def_id) = adt_def.did().as_local()
387-
{
388-
self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_of);
389-
}
390-
return true;
385+
self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_ref.def_id);
391386
}
387+
return true;
392388
}
393389

394390
false
395391
}
396392

397393
fn visit_node(&mut self, node: Node<'tcx>) {
398-
if let Node::ImplItem(hir::ImplItem { owner_id, .. }) = node
399-
&& self.should_ignore_item(owner_id.to_def_id())
394+
if let Node::ImplItem(impl_item) = node
395+
&& self.should_ignore_impl_item(impl_item)
400396
{
401397
return;
402398
}
@@ -438,7 +434,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
438434
}
439435
Node::ImplItem(impl_item) => {
440436
let item = self.tcx.local_parent(impl_item.owner_id.def_id);
441-
if self.tcx.impl_trait_ref(item).is_none() {
437+
if let hir::ImplItemImplKind::Inherent { .. } = impl_item.impl_kind {
442438
//// If it's a type whose items are live, then it's live, too.
443439
//// This is done to handle the case where, for example, the static
444440
//// method of a private type is used, but the type itself is never

compiler/rustc_passes/src/stability.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
528528

529529
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
530530
self.check_compatible_stability(ii.owner_id.def_id);
531-
let impl_def_id = self.tcx.hir_get_parent_item(ii.hir_id());
532-
if self.tcx.impl_trait_ref(impl_def_id).is_none() {
531+
if let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind {
533532
self.check_missing_stability(ii.owner_id.def_id);
534533
self.check_missing_const_stability(ii.owner_id.def_id);
535534
}

compiler/rustc_ty_utils/src/assoc.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_hir::def::DefKind;
22
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
33
use rustc_hir::definitions::{DefPathData, DisambiguatorState};
44
use rustc_hir::intravisit::{self, Visitor};
5-
use rustc_hir::{self as hir, ItemKind};
5+
use rustc_hir::{self as hir, ImplItemImplKind, ItemKind};
66
use rustc_middle::query::Providers;
77
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
88
use rustc_middle::{bug, span_bug};
@@ -121,8 +121,11 @@ fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>
121121
ty::AssocItem {
122122
kind,
123123
def_id: owner_id.to_def_id(),
124-
trait_item_def_id: impl_item.trait_item_def_id,
125124
container: ty::AssocItemContainer::Impl,
125+
trait_item_def_id: match impl_item.impl_kind {
126+
ImplItemImplKind::Inherent { .. } => None,
127+
ImplItemImplKind::Trait { trait_item_def_id, .. } => trait_item_def_id,
128+
},
126129
}
127130
}
128131
struct RPITVisitor<'a, 'tcx> {
@@ -190,7 +193,10 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
190193
}
191194
let did = item.owner_id.def_id.to_def_id();
192195
let item = tcx.hir_impl_item(*item);
193-
let Some(trait_item_def_id) = item.trait_item_def_id else {
196+
let ImplItemImplKind::Trait {
197+
trait_item_def_id: Some(trait_item_def_id), ..
198+
} = item.impl_kind
199+
else {
194200
return Some((did, vec![]));
195201
};
196202
let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| {

compiler/rustc_ty_utils/src/ty.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,15 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness {
8484
kind: hir::ItemKind::Impl(hir::Impl { defaultness, of_trait: Some(_), .. }),
8585
..
8686
})
87-
| hir::Node::ImplItem(hir::ImplItem { defaultness, .. })
87+
| hir::Node::ImplItem(hir::ImplItem {
88+
impl_kind: hir::ImplItemImplKind::Trait { defaultness, .. },
89+
..
90+
})
8891
| hir::Node::TraitItem(hir::TraitItem { defaultness, .. }) => *defaultness,
92+
hir::Node::ImplItem(hir::ImplItem {
93+
impl_kind: hir::ImplItemImplKind::Inherent { .. },
94+
..
95+
}) => hir::Defaultness::Final,
8996
node => {
9097
bug!("`defaultness` called on {:?}", node);
9198
}

0 commit comments

Comments
 (0)