Check variances in the non-hir wfchecker
This commit is contained in:
parent
d27c05709c
commit
ee8fa4eb16
12 changed files with 105 additions and 78 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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<(((((((...,),),),),),),)>`
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
@ -15,17 +26,6 @@ LL |
|
|||
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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
@ -21,14 +29,6 @@ LL | enum Bar<'a> {
|
|||
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
|
||||
|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue