Skip to content

Commit 737efa6

Browse files
authored
Rollup merge of rust-lang#64038 - matthewjasper:deny-mutual-impl-trait-recursion, r=varkor
Check impl trait substs when checking for recursive types closes rust-lang#64004
2 parents 5a94d57 + 877faf3 commit 737efa6

7 files changed

+100
-6
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);

src/librustc_typeck/check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>(
14201420
tcx.sess, span, E0733,
14211421
"recursion in an `async fn` requires boxing",
14221422
)
1423-
.span_label(span, "an `async fn` cannot invoke itself directly")
1424-
.note("a recursive `async fn` must be rewritten to return a boxed future.")
1423+
.span_label(span, "recursive `async fn`")
1424+
.note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
14251425
.emit();
14261426
} else {
14271427
let mut err = struct_span_err!(
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`.

src/test/ui/async-await/recursive-async-impl-trait-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ error[E0733]: recursion in an `async fn` requires boxing
22
--> $DIR/recursive-async-impl-trait-type.rs:5:40
33
|
44
LL | async fn recursive_async_function() -> () {
5-
| ^^ an `async fn` cannot invoke itself directly
5+
| ^^ recursive `async fn`
66
|
7-
= note: a recursive `async fn` must be rewritten to return a boxed future.
7+
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
88

99
error: aborting due to previous error
1010

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)