diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 84bacabc14e..dbf55db6e6b 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -441,12 +441,6 @@ fn check_opaque_type_parameter_valid<'tcx>( opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, ) -> 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_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); 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) { let arg_is_param = match arg.unpack() { GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), - GenericArgKind::Lifetime(lt) if is_ty_alias => { + GenericArgKind::Lifetime(lt) => { matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) || (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(_)), }; diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr new file mode 100644 index 00000000000..ec062abb2fc --- /dev/null +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr @@ -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`. diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs new file mode 100644 index 00000000000..4f72333e65e --- /dev/null +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs @@ -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() {} diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr new file mode 100644 index 00000000000..b44f9ca6944 --- /dev/null +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr @@ -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 + diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs index 15778662375..199cbbf4fcc 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs @@ -2,10 +2,8 @@ use std::fmt::Debug; fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - //~^ ERROR cannot resolve opaque type - |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) { diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index c19420bbb0c..6064b09ef09 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -1,21 +1,11 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/impl-fn-predefined-lifetimes.rs:7: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 +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/impl-fn-predefined-lifetimes.rs:5:9 | 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`. diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs index 41d5f0f6449..5b3a4eb53ff 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs @@ -5,6 +5,7 @@ trait Foo { fn bar<'other: 'a>() -> impl Sized + 'a {} //~^ ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` + //~| ERROR expected generic lifetime parameter, found `'static` } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr index b0832eb33ca..8975578dabd 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr @@ -28,6 +28,15 @@ help: consider introducing lifetime `'a` here 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`. diff --git a/tests/ui/impl-trait/rpit/early_bound.rs b/tests/ui/impl-trait/rpit/early_bound.rs index 6dda687929c..005bcea59f2 100644 --- a/tests/ui/impl-trait/rpit/early_bound.rs +++ b/tests/ui/impl-trait/rpit/early_bound.rs @@ -5,6 +5,7 @@ fn test<'a: 'a>(n: bool) -> impl Sized + 'a { let true = n else { loop {} }; let _ = || { let _ = identity::<&'a ()>(test(false)); + //~^ ERROR expected generic lifetime parameter, found `'_` }; loop {} } diff --git a/tests/ui/impl-trait/rpit/early_bound.stderr b/tests/ui/impl-trait/rpit/early_bound.stderr index 780dea4e284..b0c7bd4199c 100644 --- a/tests/ui/impl-trait/rpit/early_bound.stderr +++ b/tests/ui/impl-trait/rpit/early_bound.stderr @@ -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 --> $DIR/early_bound.rs:3:29 | @@ -10,5 +19,6 @@ note: previous use here 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`. diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs index aa60ec27e00..923b194d483 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs @@ -1,6 +1,5 @@ // issue: #111935 // FIXME(aliemjay): outdated due to "once modulo regions" restriction. -// FIXME(aliemjay): mod `infer` should fail. #![allow(unconditional_recursion)] @@ -22,6 +21,7 @@ mod infer { // invalid defining use: Opaque<'_> := () fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { let _: () = foo(Lt::<'_>::None); + //~^ ERROR expected generic lifetime parameter, found `'_` } } diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr index fe6bf71abdb..e0122d32abe 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr @@ -1,5 +1,5 @@ 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 { | ______________________________________________- @@ -10,11 +10,19 @@ LL | | } | |_____- 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/non-defining-use-lifetimes.rs:15:16 + --> $DIR/non-defining-use-lifetimes.rs:14:16 | 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 --> $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); | ^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index ef9fe604ea7..3b54fb7ea99 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -13,6 +13,7 @@ type FutNothing<'a> = impl 'a + Future; async fn operation(_: &mut ()) -> () { //~^ ERROR: concrete type differs from previous call(operation).await + //~^ ERROR: expected generic lifetime parameter, found `'any` } async fn call(_f: F) diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index cd4982b2480..c41ed0642a4 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -6,6 +6,26 @@ LL | type FutNothing<'a> = impl 'a + Future; | = 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; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | / { +LL | | +LL | | } + | |_^ + error: concrete type differs from previous defining opaque type use --> $DIR/hkl_forbidden4.rs:13:1 | @@ -18,17 +38,6 @@ note: previous use here LL | call(operation).await | ^^^^^^^^^^^^^^^ -error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:21:1 - | -LL | type FutNothing<'a> = impl 'a + Future; - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | / { -LL | | -LL | | } - | |_^ - -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0792`.