Skip to content

Commit b36be12

Browse files
committed
Auto merge of rust-lang#97039 - cjgillot:no-rpit-hrtb, r=jackh726
Forbid nested opaque types to reference HRTB from opaque types. Avoids rust-lang#96194 Alternative to rust-lang#96970 r? `@oli-obk`
2 parents 2d69117 + 872f09c commit b36be12

13 files changed

+235
-98
lines changed

compiler/rustc_resolve/src/late/lifetimes.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10251025
}
10261026
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
10271027
}
1028+
if let hir::Node::Item(hir::Item {
1029+
kind: hir::ItemKind::OpaqueTy { .. }, ..
1030+
}) = self.tcx.hir().get(parent_id)
1031+
{
1032+
if !self.trait_definition_only {
1033+
let mut err = self.tcx.sess.struct_span_err(
1034+
lifetime.span,
1035+
"higher kinded lifetime bounds on nested opaque types are not supported yet",
1036+
);
1037+
err.span_note(self.tcx.def_span(def_id), "lifetime declared here");
1038+
err.emit();
1039+
}
1040+
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
1041+
}
10281042
}
10291043

10301044
// We want to start our early-bound indices at the end of the parent scope,

src/test/ui/impl-trait/issues/issue-54895.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// check-pass
2-
31
trait Trait<'a> {
42
type Out;
53
fn call(&'a self) -> Self::Out;
@@ -15,6 +13,7 @@ impl<'a> Trait<'a> for X {
1513
}
1614

1715
fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
16+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
1817
X(())
1918
}
2019

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
2+
--> $DIR/issue-54895.rs:15:53
3+
|
4+
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
5+
| ^^
6+
|
7+
note: lifetime declared here
8+
--> $DIR/issue-54895.rs:15:20
9+
|
10+
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
11+
| ^^
12+
13+
error: aborting due to previous error
14+

src/test/ui/impl-trait/issues/issue-67830.nll.stderr

-20
This file was deleted.

src/test/ui/impl-trait/issues/issue-67830.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ where
1919

2020
struct A;
2121
fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
22-
//~^ ERROR implementation of `FnOnce` is not general enough
22+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
2323
Wrap(|a| Some(a).into_iter())
2424
}
2525

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
error: implementation of `FnOnce` is not general enough
2-
--> $DIR/issue-67830.rs:21:14
1+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
2+
--> $DIR/issue-67830.rs:21:62
33
|
44
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
5+
| ^^
66
|
7-
= note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`...
8-
= note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2`
7+
note: lifetime declared here
8+
--> $DIR/issue-67830.rs:21:23
9+
|
10+
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
11+
| ^^
912

1013
error: aborting due to previous error
1114

src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr

-55
This file was deleted.

src/test/ui/impl-trait/issues/issue-88236-2.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ impl<'a> Hrtb<'a> for &'a () {
1313
}
1414

1515
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
16+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
17+
1618
fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
17-
&() //~^ ERROR implementation of `Hrtb` is not general enough
19+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
20+
&()
1821
}
22+
1923
fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
20-
x //~^ ERROR implementation of `Hrtb` is not general enough
24+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
25+
x
2126
}
2227

2328
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,38 @@
1-
error: implementation of `Hrtb` is not general enough
2-
--> $DIR/issue-88236-2.rs:16:38
1+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
2+
--> $DIR/issue-88236-2.rs:15:61
3+
|
4+
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
5+
| ^^
6+
|
7+
note: lifetime declared here
8+
--> $DIR/issue-88236-2.rs:15:28
9+
|
10+
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
11+
| ^^
12+
13+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
14+
--> $DIR/issue-88236-2.rs:18:80
315
|
416
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough
17+
| ^^
618
|
7-
= note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
8-
= note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
19+
note: lifetime declared here
20+
--> $DIR/issue-88236-2.rs:18:47
21+
|
22+
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
23+
| ^^
924

10-
error: implementation of `Hrtb` is not general enough
11-
--> $DIR/issue-88236-2.rs:19:36
25+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
26+
--> $DIR/issue-88236-2.rs:23:78
1227
|
1328
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough
29+
| ^^
1530
|
16-
= note: `Hrtb<'1>` would have to be implemented for the type `&()`, for any lifetime `'1`...
17-
= note: ...but `Hrtb<'_>` is actually implemented for the type `&()`
31+
note: lifetime declared here
32+
--> $DIR/issue-88236-2.rs:23:45
33+
|
34+
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
35+
| ^^
1836

19-
error: aborting due to 2 previous errors
37+
error: aborting due to 3 previous errors
2038

src/test/ui/impl-trait/issues/issue-88236.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// check-pass
2-
31
// this used to cause stack overflows
42

53
trait Hrtb<'a> {
@@ -15,5 +13,6 @@ impl<'a> Hrtb<'a> for &'a () {
1513
}
1614

1715
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
16+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
1817

1918
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
2+
--> $DIR/issue-88236.rs:15:61
3+
|
4+
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
5+
| ^^
6+
|
7+
note: lifetime declared here
8+
--> $DIR/issue-88236.rs:15:28
9+
|
10+
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
11+
| ^^
12+
13+
error: aborting due to previous error
14+
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Test the interaction between rested RPIT and HRTB.
2+
3+
trait Foo<'a> {
4+
type Assoc;
5+
}
6+
7+
impl Foo<'_> for () {
8+
type Assoc = ();
9+
}
10+
11+
// Alternative version of `Foo` whose impl uses `'a`.
12+
trait Bar<'a> {
13+
type Assoc;
14+
}
15+
16+
impl<'a> Bar<'a> for () {
17+
type Assoc = &'a ();
18+
}
19+
20+
trait Qux<'a> {}
21+
22+
impl Qux<'_> for () {}
23+
24+
// This is not supported.
25+
fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
26+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
27+
28+
// This is not supported.
29+
fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
30+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
31+
32+
fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
33+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
34+
35+
fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
36+
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
37+
38+
// This should pass.
39+
fn one_hrtb_mention_fn_trait_param<'b>() -> impl for<'a> Foo<'a, Assoc = impl Qux<'b>> {}
40+
41+
// This should pass.
42+
fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'b> {}
43+
44+
// This should pass.
45+
fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
46+
47+
// This should pass.
48+
fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
49+
50+
// This should pass.
51+
fn two_htrb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Qux<'b>> {}
52+
53+
// `'b` is not in scope for the outlives bound.
54+
fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
55+
//~^ ERROR use of undeclared lifetime name `'b` [E0261]
56+
57+
// This should pass.
58+
fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {}
59+
60+
// `'b` is not in scope for the outlives bound.
61+
fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
62+
//~^ ERROR use of undeclared lifetime name `'b` [E0261]
63+
64+
fn main() {}

0 commit comments

Comments
 (0)