Skip to content

Commit 877faf3

Browse files
committed
Check impl trait substs when checking for recursive types
This prevents mutual `async fn` recursion
1 parent 7bb2d8b commit 877faf3

5 files changed

+96
-2
lines changed

src/librustc/ty/util.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
709709
substs: SubstsRef<'tcx>,
710710
) -> Option<Ty<'tcx>> {
711711
if self.found_recursion {
712-
None
713-
} else if self.seen_opaque_tys.insert(def_id) {
712+
return None;
713+
}
714+
let substs = substs.fold_with(self);
715+
if self.seen_opaque_tys.insert(def_id) {
714716
let generic_ty = self.tcx.type_of(def_id);
715717
let concrete_ty = generic_ty.subst(self.tcx, substs);
716718
let expanded_ty = self.fold_ty(concrete_ty);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// edition:2018
2+
// Test that impl trait does not allow creating recursive types that are
3+
// otherwise forbidden when using `async` and `await`.
4+
5+
async fn rec_1() { //~ ERROR recursion in an `async fn`
6+
rec_2().await;
7+
}
8+
9+
async fn rec_2() { //~ ERROR recursion in an `async fn`
10+
rec_1().await;
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0733]: recursion in an `async fn` requires boxing
2+
--> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18
3+
|
4+
LL | async fn rec_1() {
5+
| ^ recursive `async fn`
6+
|
7+
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
8+
9+
error[E0733]: recursion in an `async fn` requires boxing
10+
--> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
11+
|
12+
LL | async fn rec_2() {
13+
| ^ recursive `async fn`
14+
|
15+
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0733`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Test that impl trait does not allow creating recursive types that are
2+
// otherwise forbidden. Even when there's an opaque type in another crate
3+
// hiding this.
4+
5+
fn id<T>(t: T) -> impl Sized { t }
6+
7+
fn recursive_id() -> impl Sized { //~ ERROR opaque type expands to a recursive type
8+
id(recursive_id2())
9+
}
10+
11+
fn recursive_id2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
12+
id(recursive_id())
13+
}
14+
15+
fn wrap<T>(t: T) -> impl Sized { (t,) }
16+
17+
fn recursive_wrap() -> impl Sized { //~ ERROR opaque type expands to a recursive type
18+
wrap(recursive_wrap2())
19+
}
20+
21+
fn recursive_wrap2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
22+
wrap(recursive_wrap())
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0720]: opaque type expands to a recursive type
2+
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:7:22
3+
|
4+
LL | fn recursive_id() -> impl Sized {
5+
| ^^^^^^^^^^ expands to a recursive type
6+
|
7+
= note: type resolves to itself
8+
9+
error[E0720]: opaque type expands to a recursive type
10+
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:11:23
11+
|
12+
LL | fn recursive_id2() -> impl Sized {
13+
| ^^^^^^^^^^ expands to a recursive type
14+
|
15+
= note: type resolves to itself
16+
17+
error[E0720]: opaque type expands to a recursive type
18+
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:17:24
19+
|
20+
LL | fn recursive_wrap() -> impl Sized {
21+
| ^^^^^^^^^^ expands to a recursive type
22+
|
23+
= note: expanded type is `((impl Sized,),)`
24+
25+
error[E0720]: opaque type expands to a recursive type
26+
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:21:25
27+
|
28+
LL | fn recursive_wrap2() -> impl Sized {
29+
| ^^^^^^^^^^ expands to a recursive type
30+
|
31+
= note: expanded type is `((impl Sized,),)`
32+
33+
error: aborting due to 4 previous errors
34+
35+
For more information about this error, try `rustc --explain E0720`.

0 commit comments

Comments
 (0)