Skip to content

Run wfcheck in one big loop instead of per module #141968

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 1 commit into from
Jun 5, 2025
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
13 changes: 6 additions & 7 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{AmbigArg, ItemKind};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
Expand Down Expand Up @@ -2402,8 +2402,8 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
}
}

fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
let items = tcx.hir_module_items(module);
fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
let items = tcx.hir_crate_items(());
let res = items
.par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))
.and(items.par_impl_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)))
Expand All @@ -2412,9 +2412,8 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)),
)
.and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item)));
if module == LocalModDefId::CRATE_DEF_ID {
super::entry::check_for_entry_fn(tcx);
}
super::entry::check_for_entry_fn(tcx);

res
}

Expand Down Expand Up @@ -2552,5 +2551,5 @@ struct RedundantLifetimeArgsLint<'tcx> {
}

pub fn provide(providers: &mut Providers) {
*providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
*providers = Providers { check_type_wf, check_well_formed, ..*providers };
}
4 changes: 1 addition & 3 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
// what we are intending to discard, to help future type-based refactoring.
type R = Result<(), ErrorGuaranteed>;

tcx.par_hir_for_each_module(|module| {
let _: R = tcx.ensure_ok().check_mod_type_wf(module);
});
let _: R = tcx.ensure_ok().check_type_wf(());

for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
let _: R = tcx.ensure_ok().coherent_trait(trait_def_id);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,8 +1148,8 @@ rustc_queries! {
desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
}

query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
query check_type_wf(key: ()) -> Result<(), ErrorGuaranteed> {
desc { "checking that types are well-formed" }
return_result_from_ensure_ok
}

Expand Down
4 changes: 1 addition & 3 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,7 @@ pub(crate) fn run_global_ctxt(
// (see `override_queries` in the `config`)

// NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
let _ = tcx.sess.time("wf_checking", || {
tcx.try_par_hir_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module))
});
let _ = tcx.sess.time("wf_checking", || tcx.ensure_ok().check_type_wf(()));

tcx.dcx().abort_if_errors();

Expand Down
16 changes: 8 additions & 8 deletions tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ note: required by a bound in `compare_ty::Trait::Ty`
LL | type Ty: IntoIterator<Item = ()>;
| ^^^^^^^^^ required by this bound in `Trait::Ty`

error: unconstrained opaque type
--> $DIR/in-assoc-type-unconstrained.rs:8:26
|
LL | type Ty = Option<impl Sized>;
| ^^^^^^^^^^
|
= note: `Ty` must be used in combination with a concrete type within the same impl

error[E0053]: method `method` has an incompatible type for trait
--> $DIR/in-assoc-type-unconstrained.rs:22:24
|
Expand All @@ -42,6 +34,14 @@ LL - fn method() -> () {}
LL + fn method() -> <() as compare_method::Trait>::Ty {}
|

error: unconstrained opaque type
--> $DIR/in-assoc-type-unconstrained.rs:8:26
|
LL | type Ty = Option<impl Sized>;
| ^^^^^^^^^^
|
= note: `Ty` must be used in combination with a concrete type within the same impl

error: unconstrained opaque type
--> $DIR/in-assoc-type-unconstrained.rs:20:19
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,6 @@ LL - fn eq(&self, _other: &(Foo, i32)) -> bool {
LL + fn eq(&self, _other: &(a::Bar, i32)) -> bool {
|

error: item does not constrain `a::Foo::{opaque#0}`
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
| ^^
|
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0053]: method `eq` has an incompatible type for trait
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:30
|
Expand All @@ -50,6 +37,19 @@ LL - fn eq(&self, _other: &(Bar, i32)) -> bool {
LL + fn eq(&self, _other: &(b::Foo, i32)) -> bool {
|

error: item does not constrain `a::Foo::{opaque#0}`
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
| ^^
|
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: unconstrained opaque type
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
|
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/privacy/privacy3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ error[E0432]: unresolved import `bar::gpriv`
LL | use bar::gpriv;
| ^^^^^^^^^^ no `gpriv` in `bar`

error: requires `sized` lang_item
--> $DIR/privacy3.rs:13:20
|
LL | fn gpriv() {}
| ^^

error: requires `sized` lang_item
--> $DIR/privacy3.rs:18:14
|
Expand All @@ -28,12 +34,6 @@ error: requires `sized` lang_item
LL | fn main() {}
| ^^

error: requires `sized` lang_item
--> $DIR/privacy3.rs:13:20
|
LL | fn gpriv() {}
| ^^

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0432`.
52 changes: 26 additions & 26 deletions tests/ui/type-alias-impl-trait/constrain_inputs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,6 @@ LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter

error: item does not constrain `lifetime_params::Ty::{opaque#0}`
--> $DIR/constrain_inputs.rs:8:8
|
LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
| ^^^^^^^
|
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
--> $DIR/constrain_inputs.rs:4:19
|
LL | type Ty<'a> = impl Sized;
| ^^^^^^^^^^

error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:23:31
|
Expand All @@ -47,19 +34,6 @@ LL | fn execute(ty: Ty<'_>) -> &str { ty() }
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter

error: item does not constrain `lifetime_params_2::Ty::{opaque#0}`
--> $DIR/constrain_inputs.rs:23:8
|
LL | fn execute(ty: Ty<'_>) -> &str { ty() }
| ^^^^^^^
|
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
--> $DIR/constrain_inputs.rs:19:19
|
LL | type Ty<'a> = impl FnOnce() -> &'a str;
| ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
--> $DIR/constrain_inputs.rs:34:37
|
Expand All @@ -78,6 +52,32 @@ LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
= note: lifetimes appearing in an associated or opaque type are not considered constrained
= note: consider introducing a named lifetime parameter

error: item does not constrain `lifetime_params::Ty::{opaque#0}`
--> $DIR/constrain_inputs.rs:8:8
|
LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
| ^^^^^^^
|
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
--> $DIR/constrain_inputs.rs:4:19
|
LL | type Ty<'a> = impl Sized;
| ^^^^^^^^^^

error: item does not constrain `lifetime_params_2::Ty::{opaque#0}`
--> $DIR/constrain_inputs.rs:23:8
|
LL | fn execute(ty: Ty<'_>) -> &str { ty() }
| ^^^^^^^
|
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
--> $DIR/constrain_inputs.rs:19:19
|
LL | type Ty<'a> = impl FnOnce() -> &'a str;
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 8 previous errors

Some errors have detailed explanations: E0581, E0582.
Expand Down
Loading