Auto merge of #97039 - cjgillot:no-rpit-hrtb, r=jackh726
Forbid nested opaque types to reference HRTB from opaque types. Avoids https://github.com/rust-lang/rust/issues/96194 Alternative to https://github.com/rust-lang/rust/pull/96970 r? `@oli-obk`
This commit is contained in:
commit
b36be12d97
@ -1025,6 +1025,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
||||
}
|
||||
if let hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy { .. }, ..
|
||||
}) = self.tcx.hir().get(parent_id)
|
||||
{
|
||||
if !self.trait_definition_only {
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
lifetime.span,
|
||||
"higher kinded lifetime bounds on nested opaque types are not supported yet",
|
||||
);
|
||||
err.span_note(self.tcx.def_span(def_id), "lifetime declared here");
|
||||
err.emit();
|
||||
}
|
||||
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
// We want to start our early-bound indices at the end of the parent scope,
|
||||
|
@ -1,5 +1,3 @@
|
||||
// check-pass
|
||||
|
||||
trait Trait<'a> {
|
||||
type Out;
|
||||
fn call(&'a self) -> Self::Out;
|
||||
@ -15,6 +13,7 @@ impl<'a> Trait<'a> for X {
|
||||
}
|
||||
|
||||
fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
X(())
|
||||
}
|
||||
|
||||
|
14
src/test/ui/impl-trait/issues/issue-54895.stderr
Normal file
14
src/test/ui/impl-trait/issues/issue-54895.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/issue-54895.rs:15:53
|
||||
|
|
||||
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-54895.rs:15:20
|
||||
|
|
||||
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,20 +0,0 @@
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-67830.rs:23:5
|
||||
|
|
||||
LL | Wrap(|a| Some(a).into_iter())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2`
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-67830.rs:23:5
|
||||
|
|
||||
LL | Wrap(|a| Some(a).into_iter())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -19,7 +19,7 @@ where
|
||||
|
||||
struct A;
|
||||
fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||
//~^ ERROR implementation of `FnOnce` is not general enough
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
Wrap(|a| Some(a).into_iter())
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
--> $DIR/issue-67830.rs:21:14
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/issue-67830.rs:21:62
|
||||
|
|
||||
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
||||
| ^^
|
||||
|
|
||||
= note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2`
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-67830.rs:21:23
|
||||
|
|
||||
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:17:5
|
||||
|
|
||||
LL | &()
|
||||
| ^^^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:17:5
|
||||
|
|
||||
LL | &()
|
||||
| ^^^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-88236-2.rs:20:5
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| -- lifetime `'b` defined here
|
||||
LL | x
|
||||
| ^ returning this value requires that `'b` must outlive `'static`
|
||||
|
|
||||
help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'b` lifetime bound
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b {
|
||||
| ++++
|
||||
help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'b` lifetime bound
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> {
|
||||
| ++++
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:20:5
|
||||
|
|
||||
LL | x
|
||||
| ^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:20:5
|
||||
|
|
||||
LL | x
|
||||
| ^ implementation of `Hrtb` is not general enough
|
||||
|
|
||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
@ -13,11 +13,16 @@ impl<'a> Hrtb<'a> for &'a () {
|
||||
}
|
||||
|
||||
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
|
||||
fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
&() //~^ ERROR implementation of `Hrtb` is not general enough
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
&()
|
||||
}
|
||||
|
||||
fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
x //~^ ERROR implementation of `Hrtb` is not general enough
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,20 +1,38 @@
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:16:38
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/issue-88236-2.rs:15:61
|
||||
|
|
||||
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-88236-2.rs:15:28
|
||||
|
|
||||
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||
| ^^
|
||||
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/issue-88236-2.rs:18:80
|
||||
|
|
||||
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough
|
||||
| ^^
|
||||
|
|
||||
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
|
||||
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-88236-2.rs:18:47
|
||||
|
|
||||
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| ^^
|
||||
|
||||
error: implementation of `Hrtb` is not general enough
|
||||
--> $DIR/issue-88236-2.rs:19:36
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/issue-88236-2.rs:23:78
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough
|
||||
| ^^
|
||||
|
|
||||
= note: `Hrtb<'1>` would have to be implemented for the type `&()`, for any lifetime `'1`...
|
||||
= note: ...but `Hrtb<'_>` is actually implemented for the type `&()`
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-88236-2.rs:23:45
|
||||
|
|
||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
// check-pass
|
||||
|
||||
// this used to cause stack overflows
|
||||
|
||||
trait Hrtb<'a> {
|
||||
@ -15,5 +13,6 @@ impl<'a> Hrtb<'a> for &'a () {
|
||||
}
|
||||
|
||||
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
|
||||
fn main() {}
|
||||
|
14
src/test/ui/impl-trait/issues/issue-88236.stderr
Normal file
14
src/test/ui/impl-trait/issues/issue-88236.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/issue-88236.rs:15:61
|
||||
|
|
||||
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/issue-88236.rs:15:28
|
||||
|
|
||||
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
64
src/test/ui/impl-trait/nested-rpit-hrtb.rs
Normal file
64
src/test/ui/impl-trait/nested-rpit-hrtb.rs
Normal file
@ -0,0 +1,64 @@
|
||||
// Test the interaction between rested RPIT and HRTB.
|
||||
|
||||
trait Foo<'a> {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl Foo<'_> for () {
|
||||
type Assoc = ();
|
||||
}
|
||||
|
||||
// Alternative version of `Foo` whose impl uses `'a`.
|
||||
trait Bar<'a> {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl<'a> Bar<'a> for () {
|
||||
type Assoc = &'a ();
|
||||
}
|
||||
|
||||
trait Qux<'a> {}
|
||||
|
||||
impl Qux<'_> for () {}
|
||||
|
||||
// This is not supported.
|
||||
fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
|
||||
// This is not supported.
|
||||
fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
|
||||
fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
|
||||
fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
|
||||
// This should pass.
|
||||
fn one_hrtb_mention_fn_trait_param<'b>() -> impl for<'a> Foo<'a, Assoc = impl Qux<'b>> {}
|
||||
|
||||
// This should pass.
|
||||
fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'b> {}
|
||||
|
||||
// This should pass.
|
||||
fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
|
||||
|
||||
// This should pass.
|
||||
fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
|
||||
|
||||
// This should pass.
|
||||
fn two_htrb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Qux<'b>> {}
|
||||
|
||||
// `'b` is not in scope for the outlives bound.
|
||||
fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
//~^ ERROR use of undeclared lifetime name `'b` [E0261]
|
||||
|
||||
// This should pass.
|
||||
fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {}
|
||||
|
||||
// `'b` is not in scope for the outlives bound.
|
||||
fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
//~^ ERROR use of undeclared lifetime name `'b` [E0261]
|
||||
|
||||
fn main() {}
|
82
src/test/ui/impl-trait/nested-rpit-hrtb.stderr
Normal file
82
src/test/ui/impl-trait/nested-rpit-hrtb.stderr
Normal file
@ -0,0 +1,82 @@
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/nested-rpit-hrtb.rs:54:77
|
||||
|
|
||||
LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | fn two_htrb_outlives() -> impl for<'b, 'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/nested-rpit-hrtb.rs:61:82
|
||||
|
|
||||
LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | fn two_htrb_outlives_uses() -> impl for<'b, 'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||
| ++++
|
||||
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/nested-rpit-hrtb.rs:25:69
|
||||
|
|
||||
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/nested-rpit-hrtb.rs:25:36
|
||||
|
|
||||
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
||||
| ^^
|
||||
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/nested-rpit-hrtb.rs:29:68
|
||||
|
|
||||
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/nested-rpit-hrtb.rs:29:39
|
||||
|
|
||||
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
||||
| ^^
|
||||
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/nested-rpit-hrtb.rs:32:74
|
||||
|
|
||||
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/nested-rpit-hrtb.rs:32:41
|
||||
|
|
||||
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||
| ^^
|
||||
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/nested-rpit-hrtb.rs:35:73
|
||||
|
|
||||
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/nested-rpit-hrtb.rs:35:44
|
||||
|
|
||||
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||
| ^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
Loading…
x
Reference in New Issue
Block a user