@@ -161,21 +161,15 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
161161 tcx.def_kind_descr_article(def_kind, def_id.to_def_id()),
162162 tcx.def_kind_descr(def_kind, def_id.to_def_id()),
163163 );
164- if matches!(coroutine_kind, hir::CoroutineKind::Async(_)) {
165- diag.note("a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future");
166- diag.note(
167- "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
168- );
169- }
170- let mut called = false;
171164 for (i, frame) in cycle_error.cycle.iter().enumerate() {
172165 if frame.query.dep_kind != dep_kinds::layout_of {
173166 continue;
174167 }
175168 let Some(frame_def_id) = frame.query.ty_def_id else {
176169 continue;
177170 };
178- if !matches!(tcx.def_kind(frame_def_id), DefKind::Coroutine) {
171+ let def_kind = tcx.def_kind(frame_def_id);
172+ if !matches!(def_kind, DefKind::Coroutine) {
179173 continue;
180174 }
181175 let frame_span = frame
@@ -184,8 +178,26 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
184178 if frame_span.is_dummy() {
185179 continue;
186180 }
187- diag.span_label(frame_span, if called { "...which calls this" } else { "recursive call here" });
188- called = true;
181+ if i == 0 {
182+ diag.span_label(frame_span, "recursive call here");
183+ } else {
184+ let coroutine_span: Span = if tcx
185+ .coroutine_kind(frame_def_id)
186+ .expect("expected coroutine to have a coroutine_kind").is_fn_like() {
187+ tcx.def_span(tcx.parent(frame_def_id))
188+ } else {
189+ tcx.def_span(frame_def_id)
190+ };
191+ let mut multispan = MultiSpan::from_span(coroutine_span);
192+ multispan.push_span_label(frame_span, "...leading to this recursive call");
193+ diag.span_note(multispan, format!("which leads to this {}", tcx.def_kind_descr(def_kind, frame_def_id)));
194+ }
195+ }
196+ if matches!(coroutine_kind, hir::CoroutineKind::Async(_)) {
197+ diag.note("a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future");
198+ diag.note(
199+ "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
200+ );
189201 }
190202 diag.emit()
191203 } else {
0 commit comments