about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <github333195615777966@oli-obk.de>2025-06-04 11:16:11 +0000
committerOli Scherer <github333195615777966@oli-obk.de>2025-06-30 08:45:43 +0000
commitee8fa4eb169949600da993a0bfcb2d5fe85e6043 (patch)
treeb70e831c2d52bf6b4422d72364d6e1b0fc95635b
parentd27c05709c51d06df36388b40f94ecade488e050 (diff)
downloadrust-ee8fa4eb169949600da993a0bfcb2d5fe85e6043.tar.gz
rust-ee8fa4eb169949600da993a0bfcb2d5fe85e6043.zip
Check variances in the non-hir wfchecker
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs26
-rw-r--r--tests/ui/generic-associated-types/static-lifetime-tip-with-default-type.stderr16
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr24
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr22
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.rs8
-rw-r--r--tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs1
-rw-r--r--tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr13
-rw-r--r--tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr12
-rw-r--r--tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr16
-rw-r--r--tests/ui/traits/issue-105231.stderr22
-rw-r--r--tests/ui/variance/variance-regions-unused-indirect.stderr16
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> {