@@ -136,9 +136,9 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
136
136
_guar : ErrorGuaranteed ,
137
137
) -> Self {
138
138
let guar = if cycle_error. cycle [ 0 ] . query . dep_kind == dep_kinds:: layout_of
139
- && let Some ( def_id) = cycle_error. cycle [ 0 ] . query . ty_def_id
140
- && let Some ( def_id) = def_id. as_local ( )
141
- && matches ! ( tcx. def_kind( def_id) , DefKind :: Coroutine )
139
+ && let Some ( def_id) = cycle_error. cycle [ 0 ] . query . ty_def_id
140
+ && let Some ( def_id) = def_id. as_local ( )
141
+ && matches ! ( tcx. def_kind( def_id) , DefKind :: Coroutine )
142
142
{
143
143
let hir = tcx. hir ( ) ;
144
144
let coroutine_kind = hir
@@ -154,13 +154,37 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
154
154
} else {
155
155
tcx. def_span ( def_id)
156
156
} ;
157
- struct_span_err ! ( tcx. sess, span, E0733 , "recursion in an `async fn` requires boxing" )
158
- . span_label ( span, "recursive `async fn`" )
159
- . note ( "a recursive `async fn` must be rewritten to return a boxed `dyn Future`" )
160
- . note (
161
- "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion" ,
162
- )
163
- . emit ( )
157
+ let mut diag = struct_span_err ! (
158
+ tcx. sess,
159
+ span,
160
+ E0733 ,
161
+ "recursion in an `async fn` requires boxing"
162
+ ) ;
163
+ diag. note ( "a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future" ) ;
164
+ diag. note (
165
+ "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion" ,
166
+ ) ;
167
+ let mut called = false ;
168
+ for ( i, frame) in cycle_error. cycle . iter ( ) . enumerate ( ) {
169
+ if frame. query . dep_kind != dep_kinds:: layout_of {
170
+ continue ;
171
+ }
172
+ let Some ( frame_def_id) = frame. query . ty_def_id else {
173
+ continue ;
174
+ } ;
175
+ if !matches ! ( tcx. def_kind( frame_def_id) , DefKind :: Coroutine ) {
176
+ continue ;
177
+ }
178
+ let frame_span = frame
179
+ . query
180
+ . default_span ( cycle_error. cycle [ ( i + 1 ) % cycle_error. cycle . len ( ) ] . span ) ;
181
+ if frame_span. is_dummy ( ) {
182
+ continue ;
183
+ }
184
+ diag. span_label ( frame_span, if called { "...which calls this" } else { "recursive call here" } ) ;
185
+ called = true ;
186
+ }
187
+ diag. emit ( )
164
188
} else {
165
189
report_cycle ( tcx. sess , cycle_error) . emit ( )
166
190
} ;
0 commit comments