Skip to content

Commit

Permalink
Don't call coroutines async fns
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Nov 8, 2023
1 parent 389aee6 commit 48730f9
Show file tree
Hide file tree
Showing 15 changed files with 36 additions and 32 deletions.
16 changes: 10 additions & 6 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,13 @@ impl<'tcx> TyCtxt<'tcx> {
match def_kind {
DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "method",
DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
rustc_hir::CoroutineKind::Async(..) => "async closure",
rustc_hir::CoroutineKind::Coroutine => "coroutine",
rustc_hir::CoroutineKind::Gen(..) => "gen closure",
hir::CoroutineKind::Async(hir::CoroutineSource::Fn) => "async fn",
hir::CoroutineKind::Async(hir::CoroutineSource::Block) => "async block",
hir::CoroutineKind::Async(hir::CoroutineSource::Closure) => "async closure",
hir::CoroutineKind::Gen(hir::CoroutineSource::Fn) => "gen fn",
hir::CoroutineKind::Gen(hir::CoroutineSource::Block) => "gen block",
hir::CoroutineKind::Gen(hir::CoroutineSource::Closure) => "gen closure",
hir::CoroutineKind::Coroutine => "coroutine",
},
_ => def_kind.descr(def_id),
}
Expand All @@ -765,9 +769,9 @@ impl<'tcx> TyCtxt<'tcx> {
match def_kind {
DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "a",
DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
rustc_hir::CoroutineKind::Async(..) => "an",
rustc_hir::CoroutineKind::Coroutine => "a",
rustc_hir::CoroutineKind::Gen(..) => "a",
hir::CoroutineKind::Async(..) => "an",
hir::CoroutineKind::Coroutine => "a",
hir::CoroutineKind::Gen(..) => "a",
},
_ => def_kind.article(),
}
Expand Down
23 changes: 13 additions & 10 deletions compiler/rustc_middle/src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,11 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
let guar = if cycle_error.cycle[0].query.dep_kind == dep_kinds::layout_of
&& let Some(def_id) = cycle_error.cycle[0].query.ty_def_id
&& let Some(def_id) = def_id.as_local()
&& matches!(tcx.def_kind(def_id), DefKind::Coroutine)
&& let def_kind = tcx.def_kind(def_id)
&& matches!(def_kind, DefKind::Coroutine)
{
let hir = tcx.hir();
let coroutine_kind = hir
.body(hir.body_owned_by(def_id))
.coroutine_kind
let coroutine_kind = tcx
.coroutine_kind(def_id)
.expect("expected coroutine to have a coroutine_kind");
// FIXME: `def_span` for an fn-like coroutine will point to the fn's body
// due to interactions between the desugaring into a closure expr and the
Expand All @@ -158,12 +157,16 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
tcx.sess,
span,
E0733,
"recursion in an `async fn` requires boxing"
);
diag.note("a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future");
diag.note(
"consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
"recursion in {} {} requires boxing",
tcx.def_kind_descr_article(def_kind, def_id.to_def_id()),
tcx.def_kind_descr(def_kind, def_id.to_def_id()),
);
if matches!(coroutine_kind, hir::CoroutineKind::Async(_)) {
diag.note("a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future");
diag.note(
"consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
);
}
let mut called = false;
for (i, frame) in cycle_error.cycle.iter().enumerate() {
if frame.query.dep_kind != dep_kinds::layout_of {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/in-trait/async-recursive-generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ trait MyTrait<T> {

impl<T> MyTrait<T> for T where T: Copy {
async fn foo_recursive(&self, n: usize) -> T {
//~^ ERROR recursion in an `async fn` requires boxing
//~^ ERROR recursion in an async fn requires boxing
if n > 0 {
self.foo_recursive(n - 1).await
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0733]: recursion in an `async fn` requires boxing
error[E0733]: recursion in an async fn requires boxing
--> $DIR/async-recursive-generic.rs:8:5
|
LL | async fn foo_recursive(&self, n: usize) -> T {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/in-trait/async-recursive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ trait MyTrait {

impl MyTrait for i32 {
async fn foo_recursive(&self, n: usize) -> i32 {
//~^ ERROR recursion in an `async fn` requires boxing
//~^ ERROR recursion in an async fn requires boxing
if n > 0 {
self.foo_recursive(n - 1).await
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/in-trait/async-recursive.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0733]: recursion in an `async fn` requires boxing
error[E0733]: recursion in an async fn requires boxing
--> $DIR/async-recursive.rs:8:5
|
LL | async fn foo_recursive(&self, n: usize) -> i32 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ where
C: First,
{
async fn second(self) {
//~^ ERROR recursion in an `async fn` requires boxing
//~^ ERROR recursion in an async fn requires boxing
self.first().await.second().await;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0733]: recursion in an `async fn` requires boxing
error[E0733]: recursion in an async fn requires boxing
--> $DIR/indirect-recursion-issue-112047.rs:32:5
|
LL | async fn second(self) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Test that impl trait does not allow creating recursive types that are
// otherwise forbidden when using `async` and `await`.

async fn rec_1() { //~ ERROR recursion in an `async fn`
async fn rec_1() { //~ ERROR recursion in an async fn
rec_2().await;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0733]: recursion in an `async fn` requires boxing
error[E0733]: recursion in an async fn requires boxing
--> $DIR/mutually-recursive-async-impl-trait-type.rs:5:1
|
LL | async fn rec_1() {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/recursive-async-impl-trait-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// otherwise forbidden when using `async` and `await`.

async fn recursive_async_function() -> () {
//~^ ERROR recursion in an `async fn` requires boxing
//~^ ERROR recursion in an async fn requires boxing
recursive_async_function().await;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0733]: recursion in an `async fn` requires boxing
error[E0733]: recursion in an async fn requires boxing
--> $DIR/recursive-async-impl-trait-type.rs:5:1
|
LL | async fn recursive_async_function() -> () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,14 @@ LL |
LL | (substs_change::<&T>(),)
| ------------------------ returning here with type `(impl Sized,)`

error[E0733]: recursion in an `async fn` requires boxing
error[E0733]: recursion in a coroutine requires boxing
--> $DIR/recursive-impl-trait-type-indirect.rs:73:5
|
LL | move || {
| ^^^^^^^
LL |
LL | let x = coroutine_hold();
| - recursive call here
|
= note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future
= note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion

error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:86:26
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl Recur for () {

fn recur(self) -> Self::Recur {
async move { recur(self).await; }
//~^ ERROR recursion in an `async fn` requires boxing
//~^ ERROR recursion in an async block requires boxing
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0733]: recursion in an `async fn` requires boxing
error[E0733]: recursion in an async block requires boxing
--> $DIR/indirect-recursion-issue-112047.rs:21:9
|
LL | t.recur().await;
Expand Down

0 comments on commit 48730f9

Please sign in to comment.