Skip to content

Commit 88a8bfc

Browse files
committed
Introduce hir::ImplItemImplKind
1 parent 5590e55 commit 88a8bfc

File tree

17 files changed

+143
-99
lines changed

17 files changed

+143
-99
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_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/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
@@ -29,7 +29,7 @@ use rustc_hir::attrs::AttributeKind;
2929
use rustc_hir::def::{DefKind, Res};
3030
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
3131
use rustc_hir::intravisit::FnKind as HirFnKind;
32-
use rustc_hir::{Body, FnDecl, PatKind, PredicateOrigin, find_attr};
32+
use rustc_hir::{Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr};
3333
use rustc_middle::bug;
3434
use rustc_middle::lint::LevelAndSource;
3535
use rustc_middle::ty::layout::LayoutOf;
@@ -1321,9 +1321,8 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
13211321
}
13221322

13231323
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
1324-
// Only lint inherent impl items.
1325-
if cx.tcx.associated_item(impl_item.owner_id).trait_item_def_id.is_none() {
1326-
self.perform_lint(cx, "item", impl_item.owner_id.def_id, impl_item.vis_span, false);
1324+
if let ImplItemImplKind::Inherent { vis_span } = impl_item.impl_kind {
1325+
self.perform_lint(cx, "item", impl_item.owner_id.def_id, vis_span, false);
13271326
}
13281327
}
13291328
}

compiler/rustc_lint/src/nonstandard_style.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ pub(crate) fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLate
3838
}
3939
}
4040

41-
fn assoc_item_in_trait_impl(cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) -> bool {
42-
let item = cx.tcx.associated_item(ii.owner_id);
43-
item.trait_item_def_id.is_some()
44-
}
45-
4641
declare_lint! {
4742
/// The `non_camel_case_types` lint detects types, variants, traits and
4843
/// type parameters that don't have camel case names.
@@ -602,7 +597,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
602597

603598
fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) {
604599
if let hir::ImplItemKind::Const(..) = ii.kind
605-
&& !assoc_item_in_trait_impl(cx, ii)
600+
&& let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind
606601
{
607602
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ii.ident);
608603
}

compiler/rustc_middle/src/ty/context.rs

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

22772277
let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
22782278
Node::Item(..) | Node::TraitItem(..) => false,
2279-
Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
2279+
Node::ImplItem(impl_item) => match impl_item.impl_kind {
2280+
// For now, we do not try to target impls of traits. This is
2281+
// because this message is going to suggest that the user
2282+
// change the fn signature, but they may not be free to do so,
2283+
// since the signature must match the trait.
2284+
//
2285+
// FIXME(#42706) -- in some cases, we could do better here.
2286+
hir::ImplItemImplKind::Trait { .. } => true,
2287+
_ => false,
2288+
},
22802289
_ => false,
22812290
};
22822291

@@ -2330,21 +2339,6 @@ impl<'tcx> TyCtxt<'tcx> {
23302339
None
23312340
}
23322341

2333-
/// Checks if the bound region is in Impl Item.
2334-
pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
2335-
let container_id = self.parent(suitable_region_binding_scope.to_def_id());
2336-
if self.impl_trait_ref(container_id).is_some() {
2337-
// For now, we do not try to target impls of traits. This is
2338-
// because this message is going to suggest that the user
2339-
// change the fn signature, but they may not be free to do so,
2340-
// since the signature must match the trait.
2341-
//
2342-
// FIXME(#42706) -- in some cases, we could do better here.
2343-
return true;
2344-
}
2345-
false
2346-
}
2347-
23482342
/// Determines whether identifiers in the assembly have strict naming rules.
23492343
/// Currently, only NVPTX* targets need it.
23502344
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
@@ -373,31 +373,27 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
373373
/// Automatically generated items marked with `rustc_trivial_field_reads`
374374
/// will be ignored for the purposes of dead code analysis (see PR #85200
375375
/// for discussion).
376-
fn should_ignore_item(&mut self, def_id: DefId) -> bool {
377-
if let Some(impl_of) = self.tcx.trait_impl_of_assoc(def_id) {
378-
if !self.tcx.is_automatically_derived(impl_of) {
379-
return false;
380-
}
381-
382-
if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
383-
&& self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
376+
fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool {
377+
if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind
378+
&& let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id())
379+
&& self.tcx.is_automatically_derived(impl_of)
380+
&& let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity()
381+
&& self.tcx.has_attr(trait_ref.def_id, sym::rustc_trivial_field_reads)
382+
{
383+
if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
384+
&& let Some(adt_def_id) = adt_def.did().as_local()
384385
{
385-
let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity();
386-
if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
387-
&& let Some(adt_def_id) = adt_def.did().as_local()
388-
{
389-
self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_of);
390-
}
391-
return true;
386+
self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_ref.def_id);
392387
}
388+
return true;
393389
}
394390

395391
false
396392
}
397393

398394
fn visit_node(&mut self, node: Node<'tcx>) {
399-
if let Node::ImplItem(hir::ImplItem { owner_id, .. }) = node
400-
&& self.should_ignore_item(owner_id.to_def_id())
395+
if let Node::ImplItem(impl_item) = node
396+
&& self.should_ignore_impl_item(impl_item)
401397
{
402398
return;
403399
}
@@ -439,7 +435,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
439435
}
440436
Node::ImplItem(impl_item) => {
441437
let item = self.tcx.local_parent(impl_item.owner_id.def_id);
442-
if self.tcx.impl_trait_ref(item).is_none() {
438+
if let hir::ImplItemImplKind::Inherent { .. } = impl_item.impl_kind {
443439
//// If it's a type whose items are live, then it's live, too.
444440
//// This is done to handle the case where, for example, the static
445441
//// 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
@@ -486,8 +486,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
486486

487487
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
488488
self.check_compatible_stability(ii.owner_id.def_id);
489-
let impl_def_id = self.tcx.hir_get_parent_item(ii.hir_id());
490-
if self.tcx.impl_trait_ref(impl_def_id).is_none() {
489+
if let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind {
491490
self.check_missing_stability(ii.owner_id.def_id);
492491
self.check_missing_const_stability(ii.owner_id.def_id);
493492
}

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
421421
})
422422
| hir::Node::ImplItem(hir::ImplItem {
423423
generics,
424-
trait_item_def_id: None,
424+
impl_kind: hir::ImplItemImplKind::Inherent { .. },
425425
kind: hir::ImplItemKind::Fn(..),
426426
..
427427
}) if finder.can_suggest_bound(generics) => {

0 commit comments

Comments
 (0)