@@ -2333,10 +2333,23 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
2333
2333
2334
2334
ty:: Coroutine ( def_id, args) => {
2335
2335
let ty = self . infcx . shallow_resolve ( args. as_coroutine ( ) . tupled_upvars_ty ( ) ) ;
2336
+ let tcx = self . tcx ( ) ;
2336
2337
let witness = Ty :: new_coroutine_witness (
2337
- self . tcx ( ) ,
2338
+ tcx,
2338
2339
def_id,
2339
- self . tcx ( ) . mk_args ( args. as_coroutine ( ) . parent_args ( ) ) ,
2340
+ ty:: GenericArgs :: for_item ( tcx, def_id, |def, _| match def. kind {
2341
+ // HACK: Coroutine witnesse types are lifetime erased, so they
2342
+ // never reference any lifetime args from the coroutine. We erase
2343
+ // the regions here since we may get into situations where a
2344
+ // coroutine is recursively contained within itself, leading to
2345
+ // witness types that differ by region args. This means that
2346
+ // cycle detection in fulfillment will not kick in, which leads
2347
+ // to unnecessary overflows in async code. See the issue:
2348
+ // <https://github.com/rust-lang/rust/issues/145151>.
2349
+ ty:: GenericParamDefKind :: Lifetime => tcx. lifetimes . re_erased . into ( ) ,
2350
+ ty:: GenericParamDefKind :: Type { .. }
2351
+ | ty:: GenericParamDefKind :: Const { .. } => args[ def. index as usize ] ,
2352
+ } ) ,
2340
2353
) ;
2341
2354
ty:: Binder :: dummy ( AutoImplConstituents {
2342
2355
types : [ ty] . into_iter ( ) . chain ( iter:: once ( witness) ) . collect ( ) ,
0 commit comments