Move lazy type alias checks to non-hir-wfck

This commit is contained in:
Oli Scherer 2025-06-04 11:32:29 +00:00
parent 28f023c751
commit 632a921479
10 changed files with 63 additions and 91 deletions

View file

@ -10,7 +10,7 @@ use rustc_errors::{EmissionGuarantee, MultiSpan};
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::{LangItem, Node, intravisit};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, ObligationCauseCode};
use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc};
use rustc_lint_defs::builtin::{
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS,
};
@ -36,7 +36,9 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir};
use super::compare_impl_item::check_type_bounds;
use super::*;
use crate::check::wfcheck::check_variances_for_type_defn;
use crate::check::wfcheck::{
check_variances_for_type_defn, check_where_clauses, enter_wf_checking_ctxt,
};
fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) {
if let ExternAbi::Cdecl { unwind } = abi {
@ -731,6 +733,7 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
let mut res = Ok(());
let generics = tcx.generics_of(def_id);
for param in &generics.own_params {
@ -837,6 +840,18 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
DefKind::TyAlias => {
check_type_alias_type_params_are_used(tcx, def_id);
if tcx.type_alias_is_lazy(def_id) {
res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
let ty = tcx.type_of(def_id).instantiate_identity();
let span = tcx.def_span(def_id);
let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty);
wfcx.register_wf_obligation(
span,
Some(WellFormedLoc::Ty(def_id)),
item_ty.into(),
);
check_where_clauses(wfcx, def_id);
Ok(())
}));
check_variances_for_type_defn(tcx, def_id);
}
}
@ -901,7 +916,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
}
_ => {}
}
Ok(())
res
}
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) {

View file

@ -83,7 +83,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
/// signature types for implied bounds when checking regions.
// FIXME(-Znext-solver): This should be removed when we compute implied outlives
// bounds using the unnormalized signature of the function we're checking.
fn deeply_normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T
pub(super) fn deeply_normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
@ -104,7 +104,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
}
}
fn register_wf_obligation(&self, span: Span, loc: Option<WellFormedLoc>, term: ty::Term<'tcx>) {
pub(super) fn register_wf_obligation(
&self,
span: Span,
loc: Option<WellFormedLoc>,
term: ty::Term<'tcx>,
) {
let cause = traits::ObligationCause::new(
span,
self.body_def_id,
@ -297,20 +302,6 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
hir::ItemKind::Enum(..) => check_type_defn(tcx, item, true),
hir::ItemKind::Trait(..) => check_trait(tcx, item),
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
hir::ItemKind::TyAlias(.., hir_ty) if tcx.type_alias_is_lazy(item.owner_id) => {
enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
let ty = tcx.type_of(def_id).instantiate_identity();
let item_ty =
wfcx.deeply_normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
wfcx.register_wf_obligation(
hir_ty.span,
Some(WellFormedLoc::Ty(def_id)),
item_ty.into(),
);
check_where_clauses(wfcx, def_id);
Ok(())
})
}
_ => Ok(()),
}
}

View file

@ -1,24 +1,24 @@
error[E0275]: overflow normalizing the type alias `X2`
--> $DIR/infinite-type-alias-mutual-recursion.rs:6:11
--> $DIR/infinite-type-alias-mutual-recursion.rs:6:1
|
LL | type X1 = X2;
| ^^
| ^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
error[E0275]: overflow normalizing the type alias `X3`
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:1
|
LL | type X2 = X3;
| ^^
| ^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
error[E0275]: overflow normalizing the type alias `X1`
--> $DIR/infinite-type-alias-mutual-recursion.rs:11:11
--> $DIR/infinite-type-alias-mutual-recursion.rs:11:1
|
LL | type X3 = X1;
| ^^
| ^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

View file

@ -1,8 +1,8 @@
error[E0275]: overflow normalizing the type alias `X`
--> $DIR/infinite-vec-type-recursion.rs:6:10
--> $DIR/infinite-vec-type-recursion.rs:6:1
|
LL | type X = Vec<X>;
| ^^^^^^
| ^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

View file

@ -1,8 +1,8 @@
error[E0275]: overflow normalizing the type alias `Loop`
--> $DIR/inherent-impls-overflow.rs:8:13
--> $DIR/inherent-impls-overflow.rs:8:1
|
LL | type Loop = Loop;
| ^^^^
| ^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
@ -14,41 +14,19 @@ LL | impl Loop {}
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
error: type parameter `T` is only used recursively
--> $DIR/inherent-impls-overflow.rs:17:24
|
LL | type Poly0<T> = Poly1<(T,)>;
| - ^
| |
| type parameter must be used non-recursively in the definition
|
= help: consider removing `T` or referring to it in the body of the type alias
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0275]: overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
--> $DIR/inherent-impls-overflow.rs:17:17
--> $DIR/inherent-impls-overflow.rs:17:1
|
LL | type Poly0<T> = Poly1<(T,)>;
| ^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
error: type parameter `T` is only used recursively
--> $DIR/inherent-impls-overflow.rs:21:24
|
LL | type Poly1<T> = Poly0<(T,)>;
| - ^
| |
| type parameter must be used non-recursively in the definition
|
= help: consider removing `T` or referring to it in the body of the type alias
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
--> $DIR/inherent-impls-overflow.rs:21:17
--> $DIR/inherent-impls-overflow.rs:21:1
|
LL | type Poly1<T> = Poly0<(T,)>;
| ^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
@ -60,6 +38,6 @@ LL | impl Poly0<()> {}
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
error: aborting due to 7 previous errors
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0275`.

View file

@ -1,8 +1,8 @@
error[E0271]: type mismatch resolving `Loop normalizes-to _`
--> $DIR/inherent-impls-overflow.rs:8:13
--> $DIR/inherent-impls-overflow.rs:8:1
|
LL | type Loop = Loop;
| ^^^^ types differ
| ^^^^^^^^^ types differ
error[E0271]: type mismatch resolving `Loop normalizes-to _`
--> $DIR/inherent-impls-overflow.rs:12:1
@ -16,6 +16,14 @@ error[E0271]: type mismatch resolving `Loop normalizes-to _`
LL | impl Loop {}
| ^^^^ types differ
error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _`
--> $DIR/inherent-impls-overflow.rs:17:1
|
LL | type Poly0<T> = Poly1<(T,)>;
| ^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
error: type parameter `T` is only used recursively
--> $DIR/inherent-impls-overflow.rs:17:24
|
@ -27,11 +35,11 @@ LL | type Poly0<T> = Poly1<(T,)>;
= help: consider removing `T` or referring to it in the body of the type alias
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _`
--> $DIR/inherent-impls-overflow.rs:17:17
error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _`
--> $DIR/inherent-impls-overflow.rs:21:1
|
LL | type Poly0<T> = Poly1<(T,)>;
| ^^^^^^^^^^^
LL | type Poly1<T> = Poly0<(T,)>;
| ^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
@ -46,14 +54,6 @@ LL | type Poly1<T> = Poly0<(T,)>;
= help: consider removing `T` or referring to it in the body of the type alias
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _`
--> $DIR/inherent-impls-overflow.rs:21:17
|
LL | type Poly1<T> = Poly0<(T,)>;
| ^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
--> $DIR/inherent-impls-overflow.rs:26:1
|

View file

@ -16,12 +16,12 @@ impl Loop {}
type Poly0<T> = Poly1<(T,)>;
//[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
//~^^ ERROR type parameter `T` is only used recursively
//[next]~^^^ ERROR overflow evaluating the requirement
//[next]~^^ ERROR type parameter `T` is only used recursively
//[next]~| ERROR overflow evaluating the requirement
type Poly1<T> = Poly0<(T,)>;
//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
//~^^ ERROR type parameter `T` is only used recursively
//[next]~^^^ ERROR overflow evaluating the requirement
//[next]~^^ ERROR type parameter `T` is only used recursively
//[next]~| ERROR overflow evaluating the requirement
impl Poly0<()> {}
//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`

View file

@ -4,6 +4,5 @@
impl<T> Loop<T> {} //~ ERROR the type parameter `T` is not constrained
type Loop<T> = Loop<T>; //~ ERROR overflow
//~^ ERROR: `T` is only used recursively
fn main() {}

View file

@ -4,26 +4,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
LL | impl<T> Loop<T> {}
| ^ unconstrained type parameter
error: type parameter `T` is only used recursively
--> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:21
|
LL | type Loop<T> = Loop<T>;
| - ^
| |
| type parameter must be used non-recursively in the definition
|
= help: consider removing `T` or referring to it in the body of the type alias
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
error[E0275]: overflow normalizing the type alias `Loop<T>`
--> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:16
--> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:1
|
LL | type Loop<T> = Loop<T>;
| ^^^^^^^
| ^^^^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0207, E0275.
For more information about an error, try `rustc --explain E0207`.

View file

@ -14,10 +14,10 @@ LL | #![feature(lazy_type_alias)]
= note: `#[warn(incomplete_features)]` on by default
error[E0277]: the trait bound `*const T: ToUnit<'a>` is not satisfied
--> $DIR/issue-118950-root-region.rs:14:21
--> $DIR/issue-118950-root-region.rs:14:1
|
LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ToUnit<'a>` is not implemented for `*const T`
| ^^^^^^^^^^^^^^^^^ the trait `ToUnit<'a>` is not implemented for `*const T`
|
help: this trait has no implementations, consider adding one
--> $DIR/issue-118950-root-region.rs:8:1