Skip to content

Commit df89a22

Browse files
committed
Auto merge of #117213 - oli-obk:check_item_type_cleanup, r=<try>
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 9ab0749 + e1ec23b commit df89a22

File tree

67 files changed

+777
-403
lines changed

Some content is hidden

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

67 files changed

+777
-403
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 29 additions & 44 deletions
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::{DefId, LocalDefId, LocalModDefId};
11+
use rustc_hir::def_id::{DefId, LocalDefId};
1212
use rustc_hir::Node;
1313
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
1414
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
@@ -201,8 +201,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
201201

202202
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
203203
/// projections that would result in "inheriting lifetimes".
204-
fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
205-
let item = tcx.hir().item(id);
204+
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
205+
let item = tcx.hir().expect_item(def_id);
206206
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
207207
tcx.sess.delay_span_bug(item.span, "expected opaque item");
208208
return;
@@ -443,40 +443,35 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
443443
}
444444
}
445445

446-
fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
447-
debug!(
448-
"check_item_type(it.def_id={:?}, it.name={})",
449-
id.owner_id,
450-
tcx.def_path_str(id.owner_id)
451-
);
446+
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
452447
let _indenter = indenter();
453-
match tcx.def_kind(id.owner_id) {
448+
match tcx.def_kind(def_id) {
454449
DefKind::Static(..) => {
455-
tcx.ensure().typeck(id.owner_id.def_id);
456-
maybe_check_static_with_link_section(tcx, id.owner_id.def_id);
457-
check_static_inhabited(tcx, id.owner_id.def_id);
458-
check_static_linkage(tcx, id.owner_id.def_id);
450+
tcx.ensure().typeck(def_id);
451+
maybe_check_static_with_link_section(tcx, def_id);
452+
check_static_inhabited(tcx, def_id);
453+
check_static_linkage(tcx, def_id);
459454
}
460455
DefKind::Const => {
461-
tcx.ensure().typeck(id.owner_id.def_id);
456+
tcx.ensure().typeck(def_id);
462457
}
463458
DefKind::Enum => {
464-
check_enum(tcx, id.owner_id.def_id);
459+
check_enum(tcx, def_id);
465460
}
466461
DefKind::Fn => {} // entirely within check_item_body
467462
DefKind::Impl { of_trait } => {
468-
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(id.owner_id) {
463+
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(def_id) {
469464
check_impl_items_against_trait(
470465
tcx,
471-
id.owner_id.def_id,
466+
def_id,
472467
impl_trait_ref.instantiate_identity(),
473468
);
474-
check_on_unimplemented(tcx, id);
469+
check_on_unimplemented(tcx, def_id);
475470
}
476471
}
477472
DefKind::Trait => {
478-
let assoc_items = tcx.associated_items(id.owner_id);
479-
check_on_unimplemented(tcx, id);
473+
let assoc_items = tcx.associated_items(def_id);
474+
check_on_unimplemented(tcx, def_id);
480475

481476
for &assoc_item in assoc_items.in_definition_order() {
482477
match assoc_item.kind {
@@ -485,43 +480,43 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
485480
fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi);
486481
}
487482
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
488-
let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id);
483+
let trait_args = GenericArgs::identity_for_item(tcx, def_id);
489484
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
490485
tcx,
491486
assoc_item,
492487
assoc_item,
493-
ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_args),
488+
ty::TraitRef::new(tcx, def_id.to_def_id(), trait_args),
494489
);
495490
}
496491
_ => {}
497492
}
498493
}
499494
}
500495
DefKind::Struct => {
501-
check_struct(tcx, id.owner_id.def_id);
496+
check_struct(tcx, def_id);
502497
}
503498
DefKind::Union => {
504-
check_union(tcx, id.owner_id.def_id);
499+
check_union(tcx, def_id);
505500
}
506501
DefKind::OpaqueTy => {
507-
let origin = tcx.opaque_type_origin(id.owner_id.def_id);
502+
let origin = tcx.opaque_type_origin(def_id);
508503
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
509504
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
510505
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
511506
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
512507
{
513508
// Skip opaques from RPIT in traits with no default body.
514509
} else {
515-
check_opaque(tcx, id);
510+
check_opaque(tcx, def_id);
516511
}
517512
}
518513
DefKind::TyAlias => {
519-
let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
520-
let generics = tcx.generics_of(id.owner_id);
514+
let pty_ty = tcx.type_of(def_id).instantiate_identity();
515+
let generics = tcx.generics_of(def_id);
521516
check_type_params_are_used(tcx, &generics, pty_ty);
522517
}
523518
DefKind::ForeignMod => {
524-
let it = tcx.hir().item(id);
519+
let it = tcx.hir().expect_item(def_id);
525520
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
526521
return;
527522
};
@@ -592,19 +587,19 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
592587
}
593588
}
594589
DefKind::GlobalAsm => {
595-
let it = tcx.hir().item(id);
590+
let it = tcx.hir().expect_item(def_id);
596591
let hir::ItemKind::GlobalAsm(asm) = it.kind else {
597592
span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it)
598593
};
599-
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, id.owner_id.def_id);
594+
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, def_id);
600595
}
601596
_ => {}
602597
}
603598
}
604599

605-
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: hir::ItemId) {
600+
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) {
606601
// an error would be reported if this fails.
607-
let _ = OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id());
602+
let _ = OnUnimplementedDirective::of_item(tcx, def_id.to_def_id());
608603
}
609604

610605
pub(super) fn check_specialization_validity<'tcx>(
@@ -1314,16 +1309,6 @@ pub(super) fn check_type_params_are_used<'tcx>(
13141309
}
13151310
}
13161311

1317-
pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
1318-
let module = tcx.hir_module_items(module_def_id);
1319-
for id in module.items() {
1320-
check_item_type(tcx, id);
1321-
}
1322-
if module_def_id == LocalModDefId::CRATE_DEF_ID {
1323-
super::entry::check_for_entry_fn(tcx);
1324-
}
1325-
}
1326-
13271312
fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {
13281313
struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
13291314
.span_label(span, "recursive `async fn`")

compiler/rustc_hir_analysis/src/check/entry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::ops::Not;
1414
use super::check_function_signature;
1515
use crate::errors;
1616

17-
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
17+
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>, (): ()) {
1818
match tcx.entry_fn(()) {
1919
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
2020
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),

compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub use check::check_abi;
7575

7676
use std::num::NonZeroU32;
7777

78-
use check::check_mod_item_types;
78+
use entry::check_for_entry_fn;
7979
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
8080
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
8181
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -110,7 +110,7 @@ pub fn provide(providers: &mut Providers) {
110110
wfcheck::provide(providers);
111111
*providers = Providers {
112112
adt_destructor,
113-
check_mod_item_types,
113+
check_for_entry_fn,
114114
region_scope_tree,
115115
collect_return_position_impl_trait_in_trait_tys,
116116
compare_impl_const: compare_impl_item::compare_impl_const_raw,

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
171171
item.name = ? tcx.def_path_str(def_id)
172172
);
173173

174-
match item.kind {
174+
let res = match item.kind {
175175
// Right now we check that every default trait implementation
176176
// has an implementation of itself. Basically, a case like:
177177
//
@@ -268,7 +268,11 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
268268
}
269269
}
270270
_ => Ok(()),
271-
}
271+
};
272+
273+
crate::check::check::check_item_type(tcx, def_id);
274+
275+
res
272276
}
273277

274278
fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<(), ErrorGuaranteed> {

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
206206
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
207207
});
208208

209-
// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
210-
tcx.sess.time("item_types_checking", || {
211-
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
212-
});
209+
tcx.sess.time("entry_fn_checks", || tcx.ensure().check_for_entry_fn(()));
213210

214-
// HACK: `check_mod_type_wf` may spuriously emit errors due to `delay_span_bug`, even if those errors
215-
// only actually get emitted in `check_mod_item_types`.
211+
// HACK: `check_for_entry_fn` wants to report its errors even if `check_mod_type_wf` has errored.
216212
errs?;
217213

218214
if tcx.features().rustc_attrs {

compiler/rustc_middle/src/query/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,8 +935,8 @@ rustc_queries! {
935935
desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
936936
}
937937

938-
query check_mod_item_types(key: LocalModDefId) -> () {
939-
desc { |tcx| "checking item types in {}", describe_as_module(key, tcx) }
938+
query check_for_entry_fn(key: ()) -> () {
939+
desc { |_tcx| "checking entry functions" }
940940
}
941941

942942
query check_mod_privacy(key: LocalModDefId) -> () {

library/core/src/primitive_docs.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,26 +1077,6 @@ mod prim_tuple {}
10771077
#[doc(hidden)]
10781078
impl<T> (T,) {}
10791079

1080-
// Fake impl that's only really used for docs.
1081-
#[cfg(doc)]
1082-
#[stable(feature = "rust1", since = "1.0.0")]
1083-
#[doc(fake_variadic)]
1084-
/// This trait is implemented on arbitrary-length tuples.
1085-
impl<T: Clone> Clone for (T,) {
1086-
fn clone(&self) -> Self {
1087-
loop {}
1088-
}
1089-
}
1090-
1091-
// Fake impl that's only really used for docs.
1092-
#[cfg(doc)]
1093-
#[stable(feature = "rust1", since = "1.0.0")]
1094-
#[doc(fake_variadic)]
1095-
/// This trait is implemented on arbitrary-length tuples.
1096-
impl<T: Copy> Copy for (T,) {
1097-
// empty
1098-
}
1099-
11001080
#[rustc_doc_primitive = "f32"]
11011081
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
11021082
///

src/librustdoc/core.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,10 @@ pub(crate) fn run_global_ctxt(
320320
tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
321321
});
322322

323-
// NOTE: This is copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
324323
tcx.sess.time("item_types_checking", || {
325-
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
324+
tcx.hir().for_each_module(|module| {
325+
let _ = tcx.ensure().check_mod_type_wf(module);
326+
});
326327
});
327328
tcx.sess.abort_if_errors();
328329
tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx));

tests/rustdoc-json/enums/field_hidden.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// Regression test for <https://github.com/rust-lang/rust/issues/100529>.
22

33
#![no_core]
4-
#![feature(no_core)]
4+
#![feature(no_core, lang_items)]
5+
6+
#[lang = "sized"]
7+
trait Sized {}
58

69
// @has "$.index[*][?(@.name=='ParseError')]"
710
// @has "$.index[*][?(@.name=='UnexpectedEndTag')]"

tests/rustdoc-json/enums/kind.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// ignore-tidy-linelength
22

3-
#![feature(no_core)]
3+
#![feature(no_core, lang_items)]
44
#![no_core]
55

6+
#[lang = "sized"]
7+
trait Sized {}
8+
69
pub enum Foo {
710
// @set Unit = "$.index[*][?(@.name=='Unit')].id"
811
// @is "$.index[*][?(@.name=='Unit')].inner.variant.kind" '"plain"'

tests/rustdoc-json/enums/tuple_fields_hidden.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
#![feature(no_core)]
1+
#![feature(no_core, lang_items)]
22
#![no_core]
33

4+
#[lang = "sized"]
5+
trait Sized {}
6+
47
// @set 1.1.0 = "$.index[*][?(@.docs=='1.1.0')].id"
58
// @set 2.1.0 = "$.index[*][?(@.docs=='2.1.0')].id"
69
// @set 2.1.1 = "$.index[*][?(@.docs=='2.1.1')].id"

tests/rustdoc-json/generic-associated-types/gats.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
// ignore-tidy-linelength
22

33
#![no_core]
4-
#![feature(lang_items, no_core)]
4+
#![feature(lang_items, no_core, arbitrary_self_types)]
55

66
#[lang = "sized"]
77
pub trait Sized {}
88

9+
#[lang = "receiver"]
10+
pub trait Receiver {}
11+
912
pub trait Display {}
1013

1114
pub trait LendingIterator {

tests/rustdoc-json/impls/auto.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
#![feature(no_core, auto_traits, lang_items)]
1+
#![feature(no_core, auto_traits, lang_items, arbitrary_self_types)]
22
#![no_core]
33

44
#[lang = "sized"]
55
trait Sized {}
66

7+
#[lang = "receiver"]
8+
pub trait Receiver {}
9+
710
pub auto trait Bar {}
811

912
/// has span
@@ -12,8 +15,8 @@ impl Foo {
1215
}
1316

1417
// Testing spans, so all tests below code
15-
// @is "$.index[*][?(@.docs=='has span')].span.begin" "[10, 0]"
16-
// @is "$.index[*][?(@.docs=='has span')].span.end" "[12, 1]"
18+
// @is "$.index[*][?(@.docs=='has span')].span.begin" "[13, 0]"
19+
// @is "$.index[*][?(@.docs=='has span')].span.end" "[15, 1]"
1720
// FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91
1821
// is "$.index[*][?(@.inner.impl.synthetic==true)].span" null
1922
pub struct Foo;

tests/rustdoc-json/type/inherent_associated_type_bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ pub struct Carrier<'a>(&'a ());
1616
pub fn user(_: for<'b> fn(Carrier<'b>::Focus<i32>)) {}
1717

1818
impl<'a> Carrier<'a> {
19-
pub type Focus<T> = &'a mut T;
19+
pub type Focus<T> = &'a mut T where T: 'a;
2020
}

tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
// check-pass
2-
31
pub fn f() -> impl Sized {
42
pub enum E {
3+
//~^ ERROR: recursive type
54
V(E),
65
}
76

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0072]: recursive type `f::E` has infinite size
2+
--> $DIR/infinite-recursive-type-2.rs:2:5
3+
|
4+
LL | pub enum E {
5+
| ^^^^^^^^^^
6+
LL |
7+
LL | V(E),
8+
| - recursive without indirection
9+
|
10+
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
11+
|
12+
LL | V(Box<E>),
13+
| ++++ +
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0072`.

0 commit comments

Comments
 (0)