Point out source of recursion
This commit is contained in:
parent
82a2215481
commit
199af7cef0
@ -729,16 +729,43 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "method",
|
||||
DefKind::Closure if let Some(coroutine_kind) = self.coroutine_kind(def_id) => {
|
||||
match coroutine_kind {
|
||||
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _) => {
|
||||
"async closure"
|
||||
}
|
||||
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) => {
|
||||
"async gen closure"
|
||||
}
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::Async,
|
||||
hir::CoroutineSource::Fn,
|
||||
) => "async fn",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::Async,
|
||||
hir::CoroutineSource::Block,
|
||||
) => "async block",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::Async,
|
||||
hir::CoroutineSource::Closure,
|
||||
) => "async closure",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::AsyncGen,
|
||||
hir::CoroutineSource::Fn,
|
||||
) => "async gen fn",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::AsyncGen,
|
||||
hir::CoroutineSource::Block,
|
||||
) => "async gen block",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::AsyncGen,
|
||||
hir::CoroutineSource::Closure,
|
||||
) => "async gen closure",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::Gen,
|
||||
hir::CoroutineSource::Fn,
|
||||
) => "gen fn",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::Gen,
|
||||
hir::CoroutineSource::Block,
|
||||
) => "gen block",
|
||||
hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::Gen,
|
||||
hir::CoroutineSource::Closure,
|
||||
) => "gen closure",
|
||||
hir::CoroutineKind::Coroutine(_) => "coroutine",
|
||||
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => {
|
||||
"gen closure"
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => def_kind.descr(def_id),
|
||||
|
@ -138,7 +138,8 @@ 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::Closure)
|
||||
&& let def_kind = tcx.def_kind(def_id)
|
||||
&& matches!(def_kind, DefKind::Closure)
|
||||
&& let Some(coroutine_kind) = tcx.coroutine_kind(def_id)
|
||||
{
|
||||
// FIXME: `def_span` for an fn-like coroutine will point to the fn's body
|
||||
@ -150,13 +151,56 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
|
||||
} else {
|
||||
tcx.def_span(def_id)
|
||||
};
|
||||
struct_span_err!(tcx.sess.dcx(), span, E0733, "recursion in an `async fn` requires boxing")
|
||||
.span_label(span, "recursive `async fn`")
|
||||
.note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
|
||||
.note(
|
||||
let mut diag = struct_span_err!(
|
||||
tcx.sess.dcx(),
|
||||
span,
|
||||
E0733,
|
||||
"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()),
|
||||
);
|
||||
for (i, frame) in cycle_error.cycle.iter().enumerate() {
|
||||
if frame.query.dep_kind != dep_kinds::layout_of {
|
||||
continue;
|
||||
}
|
||||
let Some(frame_def_id) = frame.query.ty_def_id else {
|
||||
continue;
|
||||
};
|
||||
let Some(frame_coroutine_kind) = tcx.coroutine_kind(frame_def_id) else {
|
||||
continue;
|
||||
};
|
||||
let frame_span = frame
|
||||
.query
|
||||
.default_span(cycle_error.cycle[(i + 1) % cycle_error.cycle.len()].span);
|
||||
if frame_span.is_dummy() {
|
||||
continue;
|
||||
}
|
||||
if i == 0 {
|
||||
diag.span_label(frame_span, "recursive call here");
|
||||
} else {
|
||||
let coroutine_span = if frame_coroutine_kind.is_fn_like() {
|
||||
tcx.def_span(tcx.parent(frame_def_id))
|
||||
} else {
|
||||
tcx.def_span(frame_def_id)
|
||||
};
|
||||
let mut multispan = MultiSpan::from_span(coroutine_span);
|
||||
multispan.push_span_label(frame_span, "...leading to this recursive call");
|
||||
diag.span_note(
|
||||
multispan,
|
||||
format!("which leads to this {}", tcx.def_descr(frame_def_id)),
|
||||
);
|
||||
}
|
||||
}
|
||||
if matches!(
|
||||
coroutine_kind,
|
||||
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::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",
|
||||
)
|
||||
.emit()
|
||||
);
|
||||
}
|
||||
diag.emit()
|
||||
} else {
|
||||
report_cycle(tcx.sess, cycle_error).emit()
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -1,10 +1,13 @@
|
||||
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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | self.foo_recursive(n - 1).await
|
||||
| ------------------------------- recursive call here
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
= 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: aborting due to 1 previous error
|
||||
|
@ -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 {
|
||||
|
@ -1,10 +1,13 @@
|
||||
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 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | self.foo_recursive(n - 1).await
|
||||
| ------------------------------- recursive call here
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
= 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: aborting due to 1 previous error
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,19 @@
|
||||
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() {
|
||||
| ^^^^^^^^^^^^^^^^ recursive `async fn`
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | rec_2().await;
|
||||
| ------------- recursive call here
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
note: which leads to this async fn
|
||||
--> $DIR/mutually-recursive-async-impl-trait-type.rs:9:1
|
||||
|
|
||||
LL | async fn rec_2() {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | rec_1().await;
|
||||
| ------------- ...leading to this recursive call
|
||||
= 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: aborting due to 1 previous error
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
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() -> () {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | recursive_async_function().await;
|
||||
| -------------------------------- recursive call here
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
= 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: aborting due to 1 previous error
|
||||
|
@ -109,14 +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 || {
|
||||
| ^^^^^^^ recursive `async fn`
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
= note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
|
||||
| ^^^^^^^
|
||||
LL |
|
||||
LL | let x = coroutine_hold();
|
||||
| - recursive call here
|
||||
|
||||
error[E0720]: cannot resolve opaque type
|
||||
--> $DIR/recursive-impl-trait-type-indirect.rs:86:26
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,19 @@
|
||||
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 | async move { recur(self).await; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
||||
| ^^^^^^^^^^^^^-----------------^^^
|
||||
| |
|
||||
| recursive call here
|
||||
|
|
||||
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
|
||||
note: which leads to this async fn
|
||||
--> $DIR/indirect-recursion-issue-112047.rs:13:1
|
||||
|
|
||||
LL | async fn recur(t: impl Recur) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | t.recur().await;
|
||||
| --------------- ...leading to this recursive call
|
||||
= 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: aborting due to 1 previous error
|
||||
|
Loading…
x
Reference in New Issue
Block a user