@@ -2333,10 +2333,23 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
23332333
23342334 ty:: Coroutine ( def_id, args) => {
23352335 let ty = self . infcx . shallow_resolve ( args. as_coroutine ( ) . tupled_upvars_ty ( ) ) ;
2336+ let tcx = self . tcx ( ) ;
23362337 let witness = Ty :: new_coroutine_witness (
2337- self . tcx ( ) ,
2338+ tcx,
23382339 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+ } ) ,
23402353 ) ;
23412354 ty:: Binder :: dummy ( AutoImplConstituents {
23422355 types : [ ty] . into_iter ( ) . chain ( iter:: once ( witness) ) . collect ( ) ,
0 commit comments