diff options
| author | Oli Scherer <github333195615777966@oli-obk.de> | 2025-06-04 11:16:11 +0000 |
|---|---|---|
| committer | Oli Scherer <github333195615777966@oli-obk.de> | 2025-06-30 08:45:43 +0000 |
| commit | ee8fa4eb169949600da993a0bfcb2d5fe85e6043 (patch) | |
| tree | b70e831c2d52bf6b4422d72364d6e1b0fc95635b | |
| parent | d27c05709c51d06df36388b40f94ecade488e050 (diff) | |
| download | rust-ee8fa4eb169949600da993a0bfcb2d5fe85e6043.tar.gz rust-ee8fa4eb169949600da993a0bfcb2d5fe85e6043.zip | |
Check variances in the non-hir wfchecker
12 files changed, 105 insertions, 78 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b00ef2288e9..d46528dc3fc 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -36,6 +36,7 @@ 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; fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) { if let ExternAbi::Cdecl { unwind } = abi { @@ -762,6 +763,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), DefKind::Const => {} DefKind::Enum => { check_enum(tcx, def_id); + check_variances_for_type_defn(tcx, def_id); } DefKind::Fn => { if let Some(i) = tcx.intrinsic(def_id) { @@ -802,9 +804,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), } DefKind::Struct => { check_struct(tcx, def_id); + check_variances_for_type_defn(tcx, def_id); } DefKind::Union => { check_union(tcx, def_id); + check_variances_for_type_defn(tcx, def_id); } DefKind::OpaqueTy => { check_opaque_precise_captures(tcx, def_id); @@ -832,6 +836,9 @@ 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) { + check_variances_for_type_defn(tcx, def_id); + } } DefKind::ForeignMod => { let it = tcx.hir_expect_item(def_id); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 394ac233ef6..90368f7b26c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -292,25 +292,13 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() } hir::ItemKind::Fn { ident, sig, .. } => check_item_fn(tcx, def_id, ident, sig.decl), hir::ItemKind::Const(_, _, ty, _) => check_const_item(tcx, def_id, ty.span, item.span), - hir::ItemKind::Struct(..) => { - let res = check_type_defn(tcx, item, false); - check_variances_for_type_defn(tcx, def_id); - res - } - hir::ItemKind::Union(..) => { - let res = check_type_defn(tcx, item, true); - check_variances_for_type_defn(tcx, def_id); - res - } - hir::ItemKind::Enum(..) => { - let res = check_type_defn(tcx, item, true); - check_variances_for_type_defn(tcx, def_id); - res - } + hir::ItemKind::Struct(..) => check_type_defn(tcx, item, false), + hir::ItemKind::Union(..) => check_type_defn(tcx, item, true), + 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) => { - let res = enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + 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); @@ -321,9 +309,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() ); check_where_clauses(wfcx, item.span, def_id); Ok(()) - }); - check_variances_for_type_defn(tcx, def_id); - res + }) } _ => Ok(()), } @@ -1977,7 +1963,7 @@ fn legacy_receiver_is_implemented<'tcx>( } } -fn check_variances_for_type_defn<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { +pub(super) fn check_variances_for_type_defn<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { match tcx.def_kind(def_id) { DefKind::Enum | DefKind::Struct | DefKind::Union => { // Ok diff --git a/tests/ui/generic-associated-types/static-lifetime-tip-with-default-type.stderr b/tests/ui/generic-associated-types/static-lifetime-tip-with-default-type.stderr index 7d985a9013f..786aa00350c 100644 --- a/tests/ui/generic-associated-types/static-lifetime-tip-with-default-type.stderr +++ b/tests/ui/generic-associated-types/static-lifetime-tip-with-default-type.stderr @@ -82,6 +82,14 @@ help: consider adding an explicit lifetime bound LL | struct Far<T: 'static | +++++++++ +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/static-lifetime-tip-with-default-type.rs:22:10 + | +LL | struct S<'a, K: 'a = i32>(&'static K); + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + error[E0310]: the parameter type `K` may not live long enough --> $DIR/static-lifetime-tip-with-default-type.rs:22:27 | @@ -96,14 +104,6 @@ help: consider adding an explicit lifetime bound LL | struct S<'a, K: 'a + 'static = i32>(&'static K); | +++++++++ -error[E0392]: lifetime parameter `'a` is never used - --> $DIR/static-lifetime-tip-with-default-type.rs:22:10 - | -LL | struct S<'a, K: 'a = i32>(&'static K); - | ^^ unused lifetime parameter - | - = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` - error: aborting due to 8 previous errors Some errors have detailed explanations: E0310, E0392. diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr index 85ac98f4050..ae700d67c00 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr @@ -14,6 +14,17 @@ 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 | @@ -22,6 +33,17 @@ 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 | @@ -38,6 +60,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 5 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr index e94f29de44f..6a9f1f307f7 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr @@ -16,14 +16,6 @@ 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:17 - | -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 | @@ -35,10 +27,10 @@ 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 `Poly0<(T,)> == _` - --> $DIR/inherent-impls-overflow.rs:21:17 +error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _` + --> $DIR/inherent-impls-overflow.rs:17:17 | -LL | type Poly1<T> = Poly0<(T,)>; +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`) @@ -54,6 +46,14 @@ 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 | diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs index b4a347cb098..011c8655acd 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs @@ -16,12 +16,12 @@ impl Loop {} type Poly0<T> = Poly1<(T,)>; //[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` -//[next]~^^ ERROR type parameter `T` is only used recursively -//[next]~| ERROR overflow evaluating the requirement +//~^^ 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<(((((((...,),),),),),),)>` -//[next]~^^ ERROR type parameter `T` is only used recursively -//[next]~| ERROR overflow evaluating the requirement +//~^^ ERROR type parameter `T` is only used recursively +//[next]~^^^ ERROR overflow evaluating the requirement impl Poly0<()> {} //[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs index 7bc91ef426b..df6dfd15cdd 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs @@ -4,5 +4,6 @@ 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() {} diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr index bcffa02ddd4..246ccf91a51 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr @@ -4,6 +4,17 @@ 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 | @@ -12,7 +23,7 @@ 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 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0207, E0275. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr index 534ba933ba5..4bfbe0eeff7 100644 --- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr +++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr @@ -7,12 +7,6 @@ LL | beta: [(); foo::<&'a ()>()], = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error: generic `Self` types are currently not permitted in anonymous constants - --> $DIR/issue-64173-unused-lifetimes.rs:4:28 - | -LL | array: [(); size_of::<&Self>()], - | ^^^^ - error[E0392]: lifetime parameter `'s` is never used --> $DIR/issue-64173-unused-lifetimes.rs:3:12 | @@ -21,6 +15,12 @@ LL | struct Foo<'s> { | = help: consider removing `'s`, referring to it in a field, or using a marker such as `PhantomData` +error: generic `Self` types are currently not permitted in anonymous constants + --> $DIR/issue-64173-unused-lifetimes.rs:4:28 + | +LL | array: [(); size_of::<&Self>()], + | ^^^^ + error[E0392]: lifetime parameter `'a` is never used --> $DIR/issue-64173-unused-lifetimes.rs:15:12 | diff --git a/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr b/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr index b15d2affeea..e2a5027e710 100644 --- a/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr +++ b/tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr @@ -4,6 +4,14 @@ error[E0226]: only a single explicit lifetime bound is permitted LL | z: Box<dyn Is<'a>+'b+'c>, | ^^ +error[E0392]: lifetime parameter `'c` is never used + --> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:18 + | +LL | struct Foo<'a,'b,'c> { + | ^^ unused lifetime parameter + | + = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData` + error[E0478]: lifetime bound not satisfied --> $DIR/region-bounds-on-objects-and-type-parameters.rs:21:8 | @@ -21,14 +29,6 @@ note: but lifetime parameter must outlive the lifetime `'a` as defined here LL | struct Foo<'a,'b,'c> { | ^^ -error[E0392]: lifetime parameter `'c` is never used - --> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:18 - | -LL | struct Foo<'a,'b,'c> { - | ^^ unused lifetime parameter - | - = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData` - error: aborting due to 3 previous errors Some errors have detailed explanations: E0226, E0392, E0478. diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr index e113f8382b2..b048548018a 100644 --- a/tests/ui/traits/issue-105231.stderr +++ b/tests/ui/traits/issue-105231.stderr @@ -1,3 +1,14 @@ +error: type parameter `T` is only used recursively + --> $DIR/issue-105231.rs:1:15 + | +LL | struct A<T>(B<T>); + | - ^ + | | + | type parameter must be used non-recursively in the definition + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = note: all type parameters must be used in a non-recursive way in order to constrain their variance + error[E0072]: recursive types `A` and `B` have infinite size --> $DIR/issue-105231.rs:1:1 | @@ -16,17 +27,6 @@ LL ~ struct B<T>(Box<A<A<T>>>); | error: type parameter `T` is only used recursively - --> $DIR/issue-105231.rs:1:15 - | -LL | struct A<T>(B<T>); - | - ^ - | | - | type parameter must be used non-recursively in the definition - | - = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - = note: all type parameters must be used in a non-recursive way in order to constrain their variance - -error: type parameter `T` is only used recursively --> $DIR/issue-105231.rs:4:17 | LL | struct B<T>(A<A<T>>); diff --git a/tests/ui/variance/variance-regions-unused-indirect.stderr b/tests/ui/variance/variance-regions-unused-indirect.stderr index 8cdbb3c0f5e..f942c51b05b 100644 --- a/tests/ui/variance/variance-regions-unused-indirect.stderr +++ b/tests/ui/variance/variance-regions-unused-indirect.stderr @@ -1,3 +1,11 @@ +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/variance-regions-unused-indirect.rs:3:10 + | +LL | enum Foo<'a> { + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + error[E0072]: recursive types `Foo` and `Bar` have infinite size --> $DIR/variance-regions-unused-indirect.rs:3:1 | @@ -22,14 +30,6 @@ LL ~ Bar1(Box<Foo<'a>>) | error[E0392]: lifetime parameter `'a` is never used - --> $DIR/variance-regions-unused-indirect.rs:3:10 - | -LL | enum Foo<'a> { - | ^^ unused lifetime parameter - | - = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` - -error[E0392]: lifetime parameter `'a` is never used --> $DIR/variance-regions-unused-indirect.rs:8:10 | LL | enum Bar<'a> { |
