Skip to content

Commit 2a51e73

Browse files
committed
Do not fetch HIR for inherent impls.
1 parent 03dff82 commit 2a51e73

File tree

1 file changed

+36
-56
lines changed

1 file changed

+36
-56
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

Lines changed: 36 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
1414
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
1515
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
1616
use rustc_span::symbol::sym;
17-
use rustc_span::Span;
1817

1918
/// On-demand query: yields a map containing all types mapped to their inherent impls.
2019
pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls {
@@ -57,99 +56,90 @@ const ADD_ATTR: &str =
5756
"alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items";
5857

5958
impl<'tcx> InherentCollect<'tcx> {
60-
fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId, span: Span) {
61-
let impl_def_id = item.owner_id;
62-
if let Some(def_id) = def_id.as_local() {
59+
fn check_def_id(&mut self, impl_def_id: LocalDefId, self_ty: Ty<'tcx>, ty_def_id: DefId) {
60+
if let Some(ty_def_id) = ty_def_id.as_local() {
6361
// Add the implementation to the mapping from implementation to base
6462
// type def ID, if there is a base type for this implementation and
6563
// the implementation does not have any associated traits.
66-
let vec = self.impls_map.inherent_impls.entry(def_id).or_default();
64+
let vec = self.impls_map.inherent_impls.entry(ty_def_id).or_default();
6765
vec.push(impl_def_id.to_def_id());
6866
return;
6967
}
7068

7169
if self.tcx.features().rustc_attrs {
72-
let hir::ItemKind::Impl(&hir::Impl { items, .. }) = item.kind else {
73-
bug!("expected `impl` item: {:?}", item);
74-
};
70+
let items = self.tcx.associated_item_def_ids(impl_def_id);
7571

76-
if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) {
72+
if !self.tcx.has_attr(ty_def_id, sym::rustc_has_incoherent_inherent_impls) {
73+
let impl_span = self.tcx.def_span(impl_def_id);
7774
struct_span_err!(
7875
self.tcx.sess,
79-
span,
76+
impl_span,
8077
E0390,
8178
"cannot define inherent `impl` for a type outside of the crate where the type is defined",
8279
)
8380
.help(INTO_DEFINING_CRATE)
84-
.span_help(span, ADD_ATTR_TO_TY)
81+
.span_help(impl_span, ADD_ATTR_TO_TY)
8582
.emit();
8683
return;
8784
}
8885

89-
for impl_item in items {
90-
if !self
91-
.tcx
92-
.has_attr(impl_item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl)
93-
{
86+
for &impl_item in items {
87+
if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) {
88+
let impl_span = self.tcx.def_span(impl_def_id);
9489
struct_span_err!(
9590
self.tcx.sess,
96-
span,
91+
impl_span,
9792
E0390,
9893
"cannot define inherent `impl` for a type outside of the crate where the type is defined",
9994
)
10095
.help(INTO_DEFINING_CRATE)
101-
.span_help(self.tcx.hir().span(impl_item.id.hir_id()), ADD_ATTR)
96+
.span_help(self.tcx.def_span(impl_item), ADD_ATTR)
10297
.emit();
10398
return;
10499
}
105100
}
106101

107102
if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) {
108-
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id.def_id);
103+
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
109104
} else {
110105
bug!("unexpected self type: {:?}", self_ty);
111106
}
112107
} else {
108+
let impl_span = self.tcx.def_span(impl_def_id);
113109
struct_span_err!(
114110
self.tcx.sess,
115-
span,
111+
impl_span,
116112
E0116,
117113
"cannot define inherent `impl` for a type outside of the crate \
118114
where the type is defined"
119115
)
120-
.span_label(span, "impl for type defined outside of crate.")
116+
.span_label(impl_span, "impl for type defined outside of crate.")
121117
.note("define and implement a trait or new type instead")
122118
.emit();
123119
}
124120
}
125121

126-
fn check_primitive_impl(
127-
&mut self,
128-
impl_def_id: LocalDefId,
129-
ty: Ty<'tcx>,
130-
items: &[hir::ImplItemRef],
131-
span: Span,
132-
) {
122+
fn check_primitive_impl(&mut self, impl_def_id: LocalDefId, ty: Ty<'tcx>) {
123+
let items = self.tcx.associated_item_def_ids(impl_def_id);
133124
if !self.tcx.hir().rustc_coherence_is_core() {
134125
if self.tcx.features().rustc_attrs {
135-
for item in items {
136-
if !self
137-
.tcx
138-
.has_attr(item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl)
139-
{
126+
for &impl_item in items {
127+
if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) {
128+
let span = self.tcx.def_span(impl_def_id);
140129
struct_span_err!(
141130
self.tcx.sess,
142131
span,
143132
E0390,
144133
"cannot define inherent `impl` for primitive types outside of `core`",
145134
)
146135
.help(INTO_CORE)
147-
.span_help(item.span, ADD_ATTR)
136+
.span_help(self.tcx.def_span(impl_item), ADD_ATTR)
148137
.emit();
149138
return;
150139
}
151140
}
152141
} else {
142+
let span = self.tcx.def_span(impl_def_id);
153143
let mut err = struct_span_err!(
154144
self.tcx.sess,
155145
span,
@@ -181,31 +171,23 @@ impl<'tcx> InherentCollect<'tcx> {
181171
return;
182172
}
183173

184-
let item = self.tcx.hir().item(id);
185-
let impl_span = self.tcx.hir().span(id.hir_id());
186-
let hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) = item.kind else {
187-
return;
188-
};
189-
190-
let self_ty = self.tcx.type_of(item.owner_id);
174+
let id = id.owner_id.def_id;
175+
let item_span = self.tcx.def_span(id);
176+
let self_ty = self.tcx.type_of(id);
191177
match *self_ty.kind() {
192-
ty::Adt(def, _) => {
193-
self.check_def_id(item, self_ty, def.did(), impl_span);
194-
}
195-
ty::Foreign(did) => {
196-
self.check_def_id(item, self_ty, did, impl_span);
197-
}
178+
ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()),
179+
ty::Foreign(did) => self.check_def_id(id, self_ty, did),
198180
ty::Dynamic(data, ..) if data.principal_def_id().is_some() => {
199-
self.check_def_id(item, self_ty, data.principal_def_id().unwrap(), impl_span);
181+
self.check_def_id(id, self_ty, data.principal_def_id().unwrap());
200182
}
201183
ty::Dynamic(..) => {
202184
struct_span_err!(
203185
self.tcx.sess,
204-
impl_span,
186+
item_span,
205187
E0785,
206188
"cannot define inherent `impl` for a dyn auto trait"
207189
)
208-
.span_label(impl_span, "impl requires at least one non-auto trait")
190+
.span_label(item_span, "impl requires at least one non-auto trait")
209191
.note("define and implement a new trait or type instead")
210192
.emit();
211193
}
@@ -221,18 +203,16 @@ impl<'tcx> InherentCollect<'tcx> {
221203
| ty::Ref(..)
222204
| ty::Never
223205
| ty::FnPtr(_)
224-
| ty::Tuple(..) => {
225-
self.check_primitive_impl(item.owner_id.def_id, self_ty, items, impl_span)
226-
}
206+
| ty::Tuple(..) => self.check_primitive_impl(id, self_ty),
227207
ty::Alias(..) | ty::Param(_) => {
228208
let mut err = struct_span_err!(
229209
self.tcx.sess,
230-
impl_span,
210+
item_span,
231211
E0118,
232212
"no nominal type found for inherent implementation"
233213
);
234214

235-
err.span_label(impl_span, "impl requires a nominal type")
215+
err.span_label(item_span, "impl requires a nominal type")
236216
.note("either implement a trait on it or create a newtype to wrap it instead");
237217

238218
err.emit();
@@ -245,7 +225,7 @@ impl<'tcx> InherentCollect<'tcx> {
245225
| ty::Bound(..)
246226
| ty::Placeholder(_)
247227
| ty::Infer(_) => {
248-
bug!("unexpected impl self type of impl: {:?} {:?}", item.owner_id, self_ty);
228+
bug!("unexpected impl self type of impl: {:?} {:?}", id, self_ty);
249229
}
250230
ty::Error(_) => {}
251231
}

0 commit comments

Comments
 (0)