check RPITs for invalid args

This commit is contained in:
Ali MJ Al-Nasrawy 2024-03-18 16:03:18 +00:00
parent c337825d6d
commit ce91e46a1e
14 changed files with 137 additions and 50 deletions

View File

@ -441,12 +441,6 @@ fn check_opaque_type_parameter_valid<'tcx>(
opaque_type_key: OpaqueTypeKey<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>,
span: Span, span: Span,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
let (_parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin {
OpaqueTyOrigin::TyAlias { parent, .. } => (parent, true),
OpaqueTyOrigin::AsyncFn(parent) | OpaqueTyOrigin::FnReturn(parent) => (parent, false),
};
let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
@ -454,14 +448,10 @@ fn check_opaque_type_parameter_valid<'tcx>(
for (i, arg) in opaque_type_key.iter_captured_args(tcx) { for (i, arg) in opaque_type_key.iter_captured_args(tcx) {
let arg_is_param = match arg.unpack() { let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(lt) if is_ty_alias => { GenericArgKind::Lifetime(lt) => {
matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_))
|| (lt.is_static() && opaque_env.param_equal_static(i)) || (lt.is_static() && opaque_env.param_equal_static(i))
} }
// FIXME(#113916): we can't currently check for unique lifetime params,
// see that issue for more. We will also have to ignore unused lifetime
// params for RPIT, but that's comparatively trivial ✨
GenericArgKind::Lifetime(_) => continue,
GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)),
}; };

View File

@ -0,0 +1,12 @@
error[E0792]: expected generic lifetime parameter, found `'_`
--> $DIR/defining-use-captured-non-universal-region.rs:15:18
|
LL | fn foo<'a>() -> impl Sized + 'a {
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | let i: i32 = foo::<'_>();
| ^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0792`.

View File

@ -0,0 +1,24 @@
// This was an ICE. See #110726.
// FIXME(aliemjay): outdated due to "once modulo regions" restriction.
//@ revisions: statik infer fixed
//@ [fixed] check-pass
#![allow(unconditional_recursion)]
fn foo<'a>() -> impl Sized + 'a {
#[cfg(statik)]
let i: i32 = foo::<'static>();
//[statik]~^ ERROR opaque type used twice with different lifetimes
//[statik]~| ERROR opaque type used twice with different lifetimes
#[cfg(infer)]
let i: i32 = foo::<'_>();
//[infer]~^ ERROR expected generic lifetime parameter, found `'_`
#[cfg(fixed)]
let i: i32 = foo::<'a>();
i
}
fn main() {}

View File

@ -0,0 +1,33 @@
error: opaque type used twice with different lifetimes
--> $DIR/defining-use-captured-non-universal-region.rs:10:18
|
LL | let i: i32 = foo::<'static>();
| ^^^^^^^^^^^^^^^^ lifetime `'static` used here
...
LL | i
| - lifetime `'a` previously used here
|
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
--> $DIR/defining-use-captured-non-universal-region.rs:10:18
|
LL | let i: i32 = foo::<'static>();
| ^^^^^^^^^^^^^^^^
error: opaque type used twice with different lifetimes
--> $DIR/defining-use-captured-non-universal-region.rs:10:18
|
LL | let i: i32 = foo::<'static>();
| ^^^^^^^^^^^^^^^^ lifetime `'static` used here
...
LL | i
| - lifetime `'a` previously used here
|
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
--> $DIR/defining-use-captured-non-universal-region.rs:10:18
|
LL | let i: i32 = foo::<'static>();
| ^^^^^^^^^^^^^^^^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors

View File

@ -2,10 +2,8 @@
use std::fmt::Debug; use std::fmt::Debug;
fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
//~^ ERROR cannot resolve opaque type
|x| x |x| x
//~^ ERROR concrete type differs from previous defining opaque type use //~^ ERROR expected generic lifetime parameter, found `'_`
} }
fn _b<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) { fn _b<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) {

View File

@ -1,21 +1,11 @@
error: concrete type differs from previous defining opaque type use error[E0792]: expected generic lifetime parameter, found `'_`
--> $DIR/impl-fn-predefined-lifetimes.rs:7:9 --> $DIR/impl-fn-predefined-lifetimes.rs:5:9
|
LL | |x| x
| ^ expected `impl Debug + '_`, got `&u8`
|
note: previous use here
--> $DIR/impl-fn-predefined-lifetimes.rs:7:5
|
LL | |x| x
| ^^^^^
error[E0720]: cannot resolve opaque type
--> $DIR/impl-fn-predefined-lifetimes.rs:4:35
| |
LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
| ^^^^^^^^^^^^^^^ cannot resolve opaque type | -- this generic parameter must be used with a generic lifetime parameter
LL | |x| x
| ^
error: aborting due to 2 previous errors error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0720`. For more information about this error, try `rustc --explain E0792`.

View File

@ -5,6 +5,7 @@ trait Foo {
fn bar<'other: 'a>() -> impl Sized + 'a {} fn bar<'other: 'a>() -> impl Sized + 'a {}
//~^ ERROR use of undeclared lifetime name `'a` //~^ ERROR use of undeclared lifetime name `'a`
//~| ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a`
//~| ERROR expected generic lifetime parameter, found `'static`
} }
fn main() {} fn main() {}

View File

@ -28,6 +28,15 @@ help: consider introducing lifetime `'a` here
LL | trait Foo<'a> { LL | trait Foo<'a> {
| ++++ | ++++
error: aborting due to 2 previous errors error[E0792]: expected generic lifetime parameter, found `'static`
--> $DIR/bad-item-bound-within-rpitit-2.rs:5:45
|
LL | fn bar<'other: 'a>() -> impl Sized + 'a {}
| ------ ^^
| |
| cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
For more information about this error, try `rustc --explain E0261`. error: aborting due to 3 previous errors
Some errors have detailed explanations: E0261, E0792.
For more information about an error, try `rustc --explain E0261`.

View File

@ -5,6 +5,7 @@ fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
let true = n else { loop {} }; let true = n else { loop {} };
let _ = || { let _ = || {
let _ = identity::<&'a ()>(test(false)); let _ = identity::<&'a ()>(test(false));
//~^ ERROR expected generic lifetime parameter, found `'_`
}; };
loop {} loop {}
} }

View File

@ -1,3 +1,12 @@
error[E0792]: expected generic lifetime parameter, found `'_`
--> $DIR/early_bound.rs:7:17
|
LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a {
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | let _ = identity::<&'a ()>(test(false));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: concrete type differs from previous defining opaque type use error: concrete type differs from previous defining opaque type use
--> $DIR/early_bound.rs:3:29 --> $DIR/early_bound.rs:3:29
| |
@ -10,5 +19,6 @@ note: previous use here
LL | let _ = identity::<&'a ()>(test(false)); LL | let _ = identity::<&'a ()>(test(false));
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: aborting due to 1 previous error error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0792`.

View File

@ -1,6 +1,5 @@
// issue: #111935 // issue: #111935
// FIXME(aliemjay): outdated due to "once modulo regions" restriction. // FIXME(aliemjay): outdated due to "once modulo regions" restriction.
// FIXME(aliemjay): mod `infer` should fail.
#![allow(unconditional_recursion)] #![allow(unconditional_recursion)]
@ -22,6 +21,7 @@ mod infer {
// invalid defining use: Opaque<'_> := () // invalid defining use: Opaque<'_> := ()
fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a {
let _: () = foo(Lt::<'_>::None); let _: () = foo(Lt::<'_>::None);
//~^ ERROR expected generic lifetime parameter, found `'_`
} }
} }

View File

@ -1,5 +1,5 @@
error: opaque type used twice with different lifetimes error: opaque type used twice with different lifetimes
--> $DIR/non-defining-use-lifetimes.rs:15:16 --> $DIR/non-defining-use-lifetimes.rs:14:16
| |
LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a {
| ______________________________________________- | ______________________________________________-
@ -10,11 +10,19 @@ LL | | }
| |_____- lifetime `'a` previously used here | |_____- lifetime `'a` previously used here
| |
note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
--> $DIR/non-defining-use-lifetimes.rs:15:16 --> $DIR/non-defining-use-lifetimes.rs:14:16
| |
LL | let _: () = foo(Lt::<'static>::None); LL | let _: () = foo(Lt::<'static>::None);
| ^^ | ^^
error[E0792]: expected generic lifetime parameter, found `'_`
--> $DIR/non-defining-use-lifetimes.rs:23:16
|
LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a {
| -- this generic parameter must be used with a generic lifetime parameter
LL | let _: () = foo(Lt::<'_>::None);
| ^^
error: opaque type used twice with different lifetimes error: opaque type used twice with different lifetimes
--> $DIR/non-defining-use-lifetimes.rs:33:16 --> $DIR/non-defining-use-lifetimes.rs:33:16
| |
@ -32,5 +40,6 @@ note: if all non-lifetime generic parameters are the same, but the lifetime para
LL | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); LL | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None);
| ^^ | ^^
error: aborting due to 2 previous errors error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0792`.

View File

@ -13,6 +13,7 @@
async fn operation(_: &mut ()) -> () { async fn operation(_: &mut ()) -> () {
//~^ ERROR: concrete type differs from previous //~^ ERROR: concrete type differs from previous
call(operation).await call(operation).await
//~^ ERROR: expected generic lifetime parameter, found `'any`
} }
async fn call<F>(_f: F) async fn call<F>(_f: F)

View File

@ -6,6 +6,26 @@ LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
| |
= note: `FutNothing` must be used in combination with a concrete type within the same module = note: `FutNothing` must be used in combination with a concrete type within the same module
error[E0792]: expected generic lifetime parameter, found `'any`
--> $DIR/hkl_forbidden4.rs:15:5
|
LL | async fn operation(_: &mut ()) -> () {
| - this generic parameter must be used with a generic lifetime parameter
LL |
LL | call(operation).await
| ^^^^^^^^^^^^^^^
error[E0792]: expected generic lifetime parameter, found `'any`
--> $DIR/hkl_forbidden4.rs:22:1
|
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | / {
LL | |
LL | | }
| |_^
error: concrete type differs from previous defining opaque type use error: concrete type differs from previous defining opaque type use
--> $DIR/hkl_forbidden4.rs:13:1 --> $DIR/hkl_forbidden4.rs:13:1
| |
@ -18,17 +38,6 @@ note: previous use here
LL | call(operation).await LL | call(operation).await
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error[E0792]: expected generic lifetime parameter, found `'any` error: aborting due to 4 previous errors
--> $DIR/hkl_forbidden4.rs:21:1
|
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | / {
LL | |
LL | | }
| |_^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0792`. For more information about this error, try `rustc --explain E0792`.