Skip to content

Reorder check_item_type diagnostics so they occur next to the corresponding check_well_formed diagnostics #117213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 29 additions & 48 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_attr as attr;
use rustc_errors::{ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::LocalModDefId;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::Node;
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
Expand Down Expand Up @@ -198,8 +198,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {

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

fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
debug!(
"check_item_type(it.def_id={:?}, it.name={})",
id.owner_id,
tcx.def_path_str(id.owner_id)
);
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let _indenter = indenter();
match tcx.def_kind(id.owner_id) {
match tcx.def_kind(def_id) {
DefKind::Static(..) => {
tcx.ensure().typeck(id.owner_id.def_id);
maybe_check_static_with_link_section(tcx, id.owner_id.def_id);
check_static_inhabited(tcx, id.owner_id.def_id);
check_static_linkage(tcx, id.owner_id.def_id);
tcx.ensure().typeck(def_id);
maybe_check_static_with_link_section(tcx, def_id);
check_static_inhabited(tcx, def_id);
check_static_linkage(tcx, def_id);
}
DefKind::Const => {
tcx.ensure().typeck(id.owner_id.def_id);
tcx.ensure().typeck(def_id);
}
DefKind::Enum => {
check_enum(tcx, id.owner_id.def_id);
check_enum(tcx, def_id);
}
DefKind::Fn => {} // entirely within check_item_body
DefKind::Impl { of_trait } => {
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(id.owner_id) {
check_impl_items_against_trait(
tcx,
id.owner_id.def_id,
impl_trait_ref.instantiate_identity(),
);
check_on_unimplemented(tcx, id);
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(def_id) {
check_impl_items_against_trait(tcx, def_id, impl_trait_ref.instantiate_identity());
check_on_unimplemented(tcx, def_id);
}
}
DefKind::Trait => {
let assoc_items = tcx.associated_items(id.owner_id);
check_on_unimplemented(tcx, id);
let assoc_items = tcx.associated_items(def_id);
check_on_unimplemented(tcx, def_id);

for &assoc_item in assoc_items.in_definition_order() {
match assoc_item.kind {
Expand All @@ -482,43 +473,43 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
}
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id);
let trait_args = GenericArgs::identity_for_item(tcx, def_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
tcx,
assoc_item,
assoc_item,
ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_args),
ty::TraitRef::new(tcx, def_id.to_def_id(), trait_args),
);
}
_ => {}
}
}
}
DefKind::Struct => {
check_struct(tcx, id.owner_id.def_id);
check_struct(tcx, def_id);
}
DefKind::Union => {
check_union(tcx, id.owner_id.def_id);
check_union(tcx, def_id);
}
DefKind::OpaqueTy => {
let origin = tcx.opaque_type_origin(id.owner_id.def_id);
let origin = tcx.opaque_type_origin(def_id);
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
// Skip opaques from RPIT in traits with no default body.
} else {
check_opaque(tcx, id);
check_opaque(tcx, def_id);
}
}
DefKind::TyAlias => {
let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
let generics = tcx.generics_of(id.owner_id);
let pty_ty = tcx.type_of(def_id).instantiate_identity();
let generics = tcx.generics_of(def_id);
check_type_params_are_used(tcx, generics, pty_ty);
}
DefKind::ForeignMod => {
let it = tcx.hir().item(id);
let it = tcx.hir().expect_item(def_id);
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
return;
};
Expand Down Expand Up @@ -589,19 +580,19 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
}
}
DefKind::GlobalAsm => {
let it = tcx.hir().item(id);
let it = tcx.hir().expect_item(def_id);
let hir::ItemKind::GlobalAsm(asm) = it.kind else {
span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it)
};
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, id.owner_id.def_id);
InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, def_id);
}
_ => {}
}
}

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

pub(super) fn check_specialization_validity<'tcx>(
Expand Down Expand Up @@ -1309,16 +1300,6 @@ pub(super) fn check_type_params_are_used<'tcx>(
}
}

pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
let module = tcx.hir_module_items(module_def_id);
for id in module.items() {
check_item_type(tcx, id);
}
if module_def_id == LocalModDefId::CRATE_DEF_ID {
super::entry::check_for_entry_fn(tcx);
}
}

fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {
struct_span_err!(tcx.dcx(), span, E0733, "recursion in an `async fn` requires boxing")
.span_label(span, "recursive `async fn`")
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ pub use check::check_abi;

use std::num::NonZeroU32;

use check::check_mod_item_types;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::ErrorGuaranteed;
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
Expand Down Expand Up @@ -110,7 +109,6 @@ pub fn provide(providers: &mut Providers) {
wfcheck::provide(providers);
*providers = Providers {
adt_destructor,
check_mod_item_types,
region_scope_tree,
collect_return_position_impl_trait_in_trait_tys,
compare_impl_const: compare_impl_item::compare_impl_const_raw,
Expand Down
14 changes: 11 additions & 3 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
item.name = ? tcx.def_path_str(def_id)
);

match item.kind {
let res = match item.kind {
// Right now we check that every default trait implementation
// has an implementation of itself. Basically, a case like:
//
Expand Down Expand Up @@ -271,7 +271,11 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
}
}
_ => Ok(()),
}
};

crate::check::check::check_item_type(tcx, def_id);

res
}

fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<(), ErrorGuaranteed> {
Expand Down Expand Up @@ -1909,7 +1913,11 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
res = res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
res = res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)))
res = res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)));
if module == LocalModDefId::CRATE_DEF_ID {
super::entry::check_for_entry_fn(tcx);
}
res
}

fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> {
Expand Down
13 changes: 2 additions & 11 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
})?;
}

let errs = tcx.sess.time("wf_checking", || {
tcx.sess.time("wf_checking", || {
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
});

// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
tcx.sess.time("item_types_checking", || {
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
});

// HACK: `check_mod_type_wf` may spuriously emit errors due to `span_delayed_bug`, even if
// those errors only actually get emitted in `check_mod_item_types`.
errs?;
})?;

if tcx.features().rustc_attrs {
tcx.sess.track_errors(|| collect::test_opaque_hidden_types(tcx))?;
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,10 +938,6 @@ rustc_queries! {
desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
}

query check_mod_item_types(key: LocalModDefId) -> () {
desc { |tcx| "checking item types in {}", describe_as_module(key, tcx) }
}

query check_mod_privacy(key: LocalModDefId) -> () {
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,9 @@ pub(crate) fn run_global_ctxt(
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
});
tcx.sess.time("item_types_checking", || {
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
tcx.hir().for_each_module(|module| {
let _ = tcx.ensure().check_mod_type_wf(module);
});
});

tcx.dcx().abort_if_errors();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
error[E0277]: the trait bound `(T, U): Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
|
help: this trait has no implementations, consider adding one
--> $DIR/associated-types-no-suitable-supertrait.rs:12:1
|
LL | trait Get {
| ^^^^^^^^^

error[E0277]: the trait bound `(T, U): Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:22:40
|
Expand All @@ -21,18 +33,6 @@ help: consider further restricting `Self`
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
| +++++++++++++++

error[E0277]: the trait bound `(T, U): Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
|
help: this trait has no implementations, consider adding one
--> $DIR/associated-types-no-suitable-supertrait.rs:12:1
|
LL | trait Get {
| ^^^^^^^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
4 changes: 2 additions & 2 deletions tests/ui/associated-types/defaults-cyclic-fail-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ impl Tr for u32 {
// ...but not in an impl that redefines one of the types.
impl Tr for bool {
type A = Box<Self::B>;
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::A == _`
}
// (the error is shown twice for some reason)

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

fn main() {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-types/defaults-cyclic-fail-1.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
error[E0275]: overflow evaluating the requirement `<bool as Tr>::A == _`
--> $DIR/defaults-cyclic-fail-1.rs:26:14
|
LL | type A = Box<Self::B>;
| ^^^^^^^^^^^^

error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-1.rs:32:14
|
LL | type B = &'static Self::A;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-types/defaults-cyclic-fail-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ impl Tr for u32 {

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

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

fn main() {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-types/defaults-cyclic-fail-2.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
error[E0275]: overflow evaluating the requirement `<bool as Tr>::A == _`
--> $DIR/defaults-cyclic-fail-2.rs:27:14
|
LL | type A = Box<Self::B>;
| ^^^^^^^^^^^^

error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-2.rs:33:14
|
LL | type B = &'static Self::A;
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/async-await/issue-66312.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
error[E0308]: mismatched types
--> $DIR/issue-66312.rs:9:8
|
LL | if x.is_some() {
| ^^^^^^^^^^^ expected `bool`, found `()`

error[E0307]: invalid `self` parameter type: T
--> $DIR/issue-66312.rs:4:22
|
Expand All @@ -7,12 +13,6 @@ LL | fn is_some(self: T);
= note: type of `self` must be `Self` or a type that dereferences to it
= 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`)

error[E0308]: mismatched types
--> $DIR/issue-66312.rs:9:8
|
LL | if x.is_some() {
| ^^^^^^^^^^^ expected `bool`, found `()`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0307, E0308.
Expand Down
Loading