Skip to content

Commit 791a53f

Browse files
committed
Auto merge of #117213 - oli-obk:check_item_type_cleanup, r=estebank
Reorder check_item_type diagnostics so they occur next to the corresponding `check_well_formed` diagnostics The first commit is just a cleanup. The second commit moves most checks from `check_mod_item_types` into `check_well_formed`, invoking the checks in lockstep per-item instead of iterating over all items twice.
2 parents f688dd6 + 5b13dc7 commit 791a53f

35 files changed

+365
-300
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+29-48
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_attr as attr;
88
use rustc_errors::{ErrorGuaranteed, MultiSpan};
99
use rustc_hir as hir;
1010
use rustc_hir::def::{CtorKind, DefKind};
11-
use rustc_hir::def_id::LocalModDefId;
11+
use rustc_hir::def_id::{DefId, LocalDefId};
1212
use rustc_hir::Node;
1313
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1414
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
@@ -198,8 +198,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
198198

199199
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
200200
/// projections that would result in "inheriting lifetimes".
201-
fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
202-
let item = tcx.hir().item(id);
201+
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
202+
let item = tcx.hir().expect_item(def_id);
203203
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
204204
tcx.dcx().span_delayed_bug(item.span, "expected opaque item");
205205
return;
@@ -440,40 +440,31 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
440440
}
441441
}
442442

443-
fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
444-
debug!(
445-
"check_item_type(it.def_id={:?}, it.name={})",
446-
id.owner_id,
447-
tcx.def_path_str(id.owner_id)
448-
);
443+
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
449444
let _indenter = indenter();
450-
match tcx.def_kind(id.owner_id) {
445+
match tcx.def_kind(def_id) {
451446
DefKind::Static(..) => {
452-
tcx.ensure().typeck(id.owner_id.def_id);
453-
maybe_check_static_with_link_section(tcx, id.owner_id.def_id);
454-
check_static_inhabited(tcx, id.owner_id.def_id);
455-
check_static_linkage(tcx, id.owner_id.def_id);
447+
tcx.ensure().typeck(def_id);
448+
maybe_check_static_with_link_section(tcx, def_id);
449+
check_static_inhabited(tcx, def_id);
450+
check_static_linkage(tcx, def_id);
456451
}
457452
DefKind::Const => {
458-
tcx.ensure().typeck(id.owner_id.def_id);
453+
tcx.ensure().typeck(def_id);
459454
}
460455
DefKind::Enum => {
461-
check_enum(tcx, id.owner_id.def_id);
456+
check_enum(tcx, def_id);
462457
}
463458
DefKind::Fn => {} // entirely within check_item_body
464459
DefKind::Impl { of_trait } => {
465-
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(id.owner_id) {
466-
check_impl_items_against_trait(
467-
tcx,
468-
id.owner_id.def_id,
469-
impl_trait_ref.instantiate_identity(),
470-
);
471-
check_on_unimplemented(tcx, id);
460+
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(def_id) {
461+
check_impl_items_against_trait(tcx, def_id, impl_trait_ref.instantiate_identity());
462+
check_on_unimplemented(tcx, def_id);
472463
}
473464
}
474465
DefKind::Trait => {
475-
let assoc_items = tcx.associated_items(id.owner_id);
476-
check_on_unimplemented(tcx, id);
466+
let assoc_items = tcx.associated_items(def_id);
467+
check_on_unimplemented(tcx, def_id);
477468

478469
for &assoc_item in assoc_items.in_definition_order() {
479470
match assoc_item.kind {
@@ -482,43 +473,43 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
482473
forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
483474
}
484475
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
485-
let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id);
476+
let trait_args = GenericArgs::identity_for_item(tcx, def_id);
486477
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
487478
tcx,
488479
assoc_item,
489480
assoc_item,
490-
ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_args),
481+
ty::TraitRef::new(tcx, def_id.to_def_id(), trait_args),
491482
);
492483
}
493484
_ => {}
494485
}
495486
}
496487
}
497488
DefKind::Struct => {
498-
check_struct(tcx, id.owner_id.def_id);
489+
check_struct(tcx, def_id);
499490
}
500491
DefKind::Union => {
501-
check_union(tcx, id.owner_id.def_id);
492+
check_union(tcx, def_id);
502493
}
503494
DefKind::OpaqueTy => {
504-
let origin = tcx.opaque_type_origin(id.owner_id.def_id);
495+
let origin = tcx.opaque_type_origin(def_id);
505496
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
506497
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
507498
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
508499
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
509500
{
510501
// Skip opaques from RPIT in traits with no default body.
511502
} else {
512-
check_opaque(tcx, id);
503+
check_opaque(tcx, def_id);
513504
}
514505
}
515506
DefKind::TyAlias => {
516-
let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
517-
let generics = tcx.generics_of(id.owner_id);
507+
let pty_ty = tcx.type_of(def_id).instantiate_identity();
508+
let generics = tcx.generics_of(def_id);
518509
check_type_params_are_used(tcx, generics, pty_ty);
519510
}
520511
DefKind::ForeignMod => {
521-
let it = tcx.hir().item(id);
512+
let it = tcx.hir().expect_item(def_id);
522513
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
523514
return;
524515
};
@@ -589,19 +580,19 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
589580
}
590581
}
591582
DefKind::GlobalAsm => {
592-
let it = tcx.hir().item(id);
583+
let it = tcx.hir().expect_item(def_id);
593584
let hir::ItemKind::GlobalAsm(asm) = it.kind else {
594585
span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it)
595586
};
596-
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, id.owner_id.def_id);
587+
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, def_id);
597588
}
598589
_ => {}
599590
}
600591
}
601592

602-
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: hir::ItemId) {
593+
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) {
603594
// an error would be reported if this fails.
604-
let _ = OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id());
595+
let _ = OnUnimplementedDirective::of_item(tcx, def_id.to_def_id());
605596
}
606597

607598
pub(super) fn check_specialization_validity<'tcx>(
@@ -1309,16 +1300,6 @@ pub(super) fn check_type_params_are_used<'tcx>(
13091300
}
13101301
}
13111302

1312-
pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
1313-
let module = tcx.hir_module_items(module_def_id);
1314-
for id in module.items() {
1315-
check_item_type(tcx, id);
1316-
}
1317-
if module_def_id == LocalModDefId::CRATE_DEF_ID {
1318-
super::entry::check_for_entry_fn(tcx);
1319-
}
1320-
}
1321-
13221303
fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {
13231304
struct_span_err!(tcx.dcx(), span, E0733, "recursion in an `async fn` requires boxing")
13241305
.span_label(span, "recursive `async fn`")

compiler/rustc_hir_analysis/src/check/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ pub use check::check_abi;
7575

7676
use std::num::NonZeroU32;
7777

78-
use check::check_mod_item_types;
7978
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
8079
use rustc_errors::ErrorGuaranteed;
8180
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
@@ -110,7 +109,6 @@ pub fn provide(providers: &mut Providers) {
110109
wfcheck::provide(providers);
111110
*providers = Providers {
112111
adt_destructor,
113-
check_mod_item_types,
114112
region_scope_tree,
115113
collect_return_position_impl_trait_in_trait_tys,
116114
compare_impl_const: compare_impl_item::compare_impl_const_raw,

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
172172
item.name = ? tcx.def_path_str(def_id)
173173
);
174174

175-
match item.kind {
175+
let res = match item.kind {
176176
// Right now we check that every default trait implementation
177177
// has an implementation of itself. Basically, a case like:
178178
//
@@ -271,7 +271,11 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
271271
}
272272
}
273273
_ => Ok(()),
274-
}
274+
};
275+
276+
crate::check::check::check_item_type(tcx, def_id);
277+
278+
res
275279
}
276280

277281
fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<(), ErrorGuaranteed> {
@@ -1909,7 +1913,11 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
19091913
let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
19101914
res = res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
19111915
res = res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
1912-
res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)))
1916+
res = res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
1917+
if module == LocalModDefId::CRATE_DEF_ID {
1918+
super::entry::check_for_entry_fn(tcx);
1919+
}
1920+
res
19131921
}
19141922

19151923
fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> {

compiler/rustc_hir_analysis/src/lib.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
200200
})?;
201201
}
202202

203-
let errs = tcx.sess.time("wf_checking", || {
203+
tcx.sess.time("wf_checking", || {
204204
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
205-
});
206-
207-
// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
208-
tcx.sess.time("item_types_checking", || {
209-
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
210-
});
211-
212-
// HACK: `check_mod_type_wf` may spuriously emit errors due to `span_delayed_bug`, even if
213-
// those errors only actually get emitted in `check_mod_item_types`.
214-
errs?;
205+
})?;
215206

216207
if tcx.features().rustc_attrs {
217208
tcx.sess.track_errors(|| collect::test_opaque_hidden_types(tcx))?;

compiler/rustc_middle/src/query/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -938,10 +938,6 @@ rustc_queries! {
938938
desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
939939
}
940940

941-
query check_mod_item_types(key: LocalModDefId) -> () {
942-
desc { |tcx| "checking item types in {}", describe_as_module(key, tcx) }
943-
}
944-
945941
query check_mod_privacy(key: LocalModDefId) -> () {
946942
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
947943
}

src/librustdoc/core.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,9 @@ pub(crate) fn run_global_ctxt(
323323
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
324324
});
325325
tcx.sess.time("item_types_checking", || {
326-
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
326+
tcx.hir().for_each_module(|module| {
327+
let _ = tcx.ensure().check_mod_type_wf(module);
328+
});
327329
});
328330

329331
tcx.dcx().abort_if_errors();

tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
error[E0277]: the trait bound `(T, U): Get` is not satisfied
2+
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5
3+
|
4+
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
6+
|
7+
help: this trait has no implementations, consider adding one
8+
--> $DIR/associated-types-no-suitable-supertrait.rs:12:1
9+
|
10+
LL | trait Get {
11+
| ^^^^^^^^^
12+
113
error[E0277]: the trait bound `(T, U): Get` is not satisfied
214
--> $DIR/associated-types-no-suitable-supertrait.rs:22:40
315
|
@@ -21,18 +33,6 @@ help: consider further restricting `Self`
2133
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
2234
| +++++++++++++++
2335

24-
error[E0277]: the trait bound `(T, U): Get` is not satisfied
25-
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5
26-
|
27-
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
28-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
29-
|
30-
help: this trait has no implementations, consider adding one
31-
--> $DIR/associated-types-no-suitable-supertrait.rs:12:1
32-
|
33-
LL | trait Get {
34-
| ^^^^^^^^^
35-
3636
error: aborting due to 3 previous errors
3737

3838
For more information about this error, try `rustc --explain E0277`.

tests/ui/associated-types/defaults-cyclic-fail-1.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ impl Tr for u32 {
2424
// ...but not in an impl that redefines one of the types.
2525
impl Tr for bool {
2626
type A = Box<Self::B>;
27-
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
27+
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::A == _`
2828
}
2929
// (the error is shown twice for some reason)
3030

3131
impl Tr for usize {
3232
type B = &'static Self::A;
33-
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
33+
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::B == _`
3434
}
3535

3636
fn main() {

tests/ui/associated-types/defaults-cyclic-fail-1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
1+
error[E0275]: overflow evaluating the requirement `<bool as Tr>::A == _`
22
--> $DIR/defaults-cyclic-fail-1.rs:26:14
33
|
44
LL | type A = Box<Self::B>;
55
| ^^^^^^^^^^^^
66

7-
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
7+
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B == _`
88
--> $DIR/defaults-cyclic-fail-1.rs:32:14
99
|
1010
LL | type B = &'static Self::A;

tests/ui/associated-types/defaults-cyclic-fail-2.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ impl Tr for u32 {
2525

2626
impl Tr for bool {
2727
type A = Box<Self::B>;
28-
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
28+
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::A == _`
2929
}
3030
// (the error is shown twice for some reason)
3131

3232
impl Tr for usize {
3333
type B = &'static Self::A;
34-
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
34+
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::B == _`
3535
}
3636

3737
fn main() {

tests/ui/associated-types/defaults-cyclic-fail-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
1+
error[E0275]: overflow evaluating the requirement `<bool as Tr>::A == _`
22
--> $DIR/defaults-cyclic-fail-2.rs:27:14
33
|
44
LL | type A = Box<Self::B>;
55
| ^^^^^^^^^^^^
66

7-
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
7+
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B == _`
88
--> $DIR/defaults-cyclic-fail-2.rs:33:14
99
|
1010
LL | type B = &'static Self::A;

tests/ui/async-await/issue-66312.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-66312.rs:9:8
3+
|
4+
LL | if x.is_some() {
5+
| ^^^^^^^^^^^ expected `bool`, found `()`
6+
17
error[E0307]: invalid `self` parameter type: T
28
--> $DIR/issue-66312.rs:4:22
39
|
@@ -7,12 +13,6 @@ LL | fn is_some(self: T);
713
= note: type of `self` must be `Self` or a type that dereferences to it
814
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
915

10-
error[E0308]: mismatched types
11-
--> $DIR/issue-66312.rs:9:8
12-
|
13-
LL | if x.is_some() {
14-
| ^^^^^^^^^^^ expected `bool`, found `()`
15-
1616
error: aborting due to 2 previous errors
1717

1818
Some errors have detailed explanations: E0307, E0308.

0 commit comments

Comments
 (0)