Skip to content

Commit

Permalink
Auto merge of rust-lang#97039 - cjgillot:no-rpit-hrtb, r=jackh726
Browse files Browse the repository at this point in the history
Forbid nested opaque types to reference HRTB from opaque types.

Avoids rust-lang#96194
Alternative to rust-lang#96970

r? `@oli-obk`
  • Loading branch information
bors committed May 14, 2022
2 parents 2d69117 + 872f09c commit b36be12
Show file tree
Hide file tree
Showing 13 changed files with 235 additions and 98 deletions.
14 changes: 14 additions & 0 deletions compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions src/test/ui/impl-trait/issues/issue-54895.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// check-pass

trait Trait<'a> {
type Out;
fn call(&'a self) -> Self::Out;
Expand All @@ -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(())
}

Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/impl-trait/issues/issue-54895.stderr
Original file line number Diff line number Diff line change
@@ -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

20 changes: 0 additions & 20 deletions src/test/ui/impl-trait/issues/issue-67830.nll.stderr

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/ui/impl-trait/issues/issue-67830.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}

Expand Down
13 changes: 8 additions & 5 deletions src/test/ui/impl-trait/issues/issue-67830.stderr
Original file line number Diff line number Diff line change
@@ -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

55 changes: 0 additions & 55 deletions src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr

This file was deleted.

9 changes: 7 additions & 2 deletions src/test/ui/impl-trait/issues/issue-88236-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
40 changes: 29 additions & 11 deletions src/test/ui/impl-trait/issues/issue-88236-2.stderr
Original file line number Diff line number Diff line change
@@ -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

3 changes: 1 addition & 2 deletions src/test/ui/impl-trait/issues/issue-88236.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// check-pass

// this used to cause stack overflows

trait Hrtb<'a> {
Expand All @@ -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 changes: 14 additions & 0 deletions src/test/ui/impl-trait/issues/issue-88236.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 64 additions & 0 deletions src/test/ui/impl-trait/nested-rpit-hrtb.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Loading

0 comments on commit b36be12

Please sign in to comment.