Skip to content

Commit 30a5146

Browse files
committed
Auto merge of #97040 - cjgillot:no-rpit-hrtb-beta, r=jackh726
Forbid nested opaque types to reference HRTB from opaque types. Backport version of #97039 if useful. r? `@Mark-Simulacrum`
2 parents eb1e588 + 7d0f04a commit 30a5146

13 files changed

+235
-94
lines changed

compiler/rustc_resolve/src/late/lifetimes.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10361036
}
10371037
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
10381038
}
1039+
if let hir::Node::Item(hir::Item {
1040+
kind: hir::ItemKind::OpaqueTy { .. }, ..
1041+
}) = self.tcx.hir().get(parent_id)
1042+
{
1043+
if !self.trait_definition_only {
1044+
let mut err = self.tcx.sess.struct_span_err(
1045+
lifetime.span,
1046+
"higher kinded lifetime bounds on nested opaque types are not supported yet",
1047+
);
1048+
err.span_note(self.tcx.def_span(def_id), "lifetime declared here");
1049+
err.emit();
1050+
}
1051+
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
1052+
}
10391053
}
10401054

10411055
// 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

-51
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+
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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+
//~| ERROR lifetime name `'b` shadows a lifetime name that is already in scope [E0496]
57+
58+
// This should pass.
59+
fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {}
60+
61+
// `'b` is not in scope for the outlives bound.
62+
fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
63+
//~^ ERROR use of undeclared lifetime name `'b` [E0261]
64+
//~| ERROR lifetime name `'b` shadows a lifetime name that is already in scope [E0496]
65+
66+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
2+
--> $DIR/nested-rpit-hrtb.rs:25:69
3+
|
4+
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
5+
| ^^
6+
|
7+
note: lifetime declared here
8+
--> $DIR/nested-rpit-hrtb.rs:25:36
9+
|
10+
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
11+
| ^^
12+
13+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
14+
--> $DIR/nested-rpit-hrtb.rs:29:68
15+
|
16+
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
17+
| ^^
18+
|
19+
note: lifetime declared here
20+
--> $DIR/nested-rpit-hrtb.rs:29:39
21+
|
22+
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
23+
| ^^
24+
25+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
26+
--> $DIR/nested-rpit-hrtb.rs:32:74
27+
|
28+
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
29+
| ^^
30+
|
31+
note: lifetime declared here
32+
--> $DIR/nested-rpit-hrtb.rs:32:41
33+
|
34+
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
35+
| ^^
36+
37+
error: higher kinded lifetime bounds on nested opaque types are not supported yet
38+
--> $DIR/nested-rpit-hrtb.rs:35:73
39+
|
40+
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
41+
| ^^
42+
|
43+
note: lifetime declared here
44+
--> $DIR/nested-rpit-hrtb.rs:35:44
45+
|
46+
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
47+
| ^^
48+
49+
error[E0261]: use of undeclared lifetime name `'b`
50+
--> $DIR/nested-rpit-hrtb.rs:54:77
51+
|
52+
LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
53+
| - help: consider introducing lifetime `'b` here: `<'b>` ^^ undeclared lifetime
54+
55+
error[E0496]: lifetime name `'b` shadows a lifetime name that is already in scope
56+
--> $DIR/nested-rpit-hrtb.rs:54:65
57+
|
58+
LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
59+
| ^^ -- first declared here
60+
| |
61+
| lifetime `'b` already in scope
62+
63+
error[E0261]: use of undeclared lifetime name `'b`
64+
--> $DIR/nested-rpit-hrtb.rs:62:82
65+
|
66+
LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
67+
| - help: consider introducing lifetime `'b` here: `<'b>` ^^ undeclared lifetime
68+
69+
error[E0496]: lifetime name `'b` shadows a lifetime name that is already in scope
70+
--> $DIR/nested-rpit-hrtb.rs:62:70
71+
|
72+
LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
73+
| ^^ -- first declared here
74+
| |
75+
| lifetime `'b` already in scope
76+
77+
error: aborting due to 8 previous errors
78+
79+
Some errors have detailed explanations: E0261, E0496.
80+
For more information about an error, try `rustc --explain E0261`.

0 commit comments

Comments
 (0)