Skip to content

Commit b4aa629

Browse files
Ignore coroutine witness type region args in auto trait confirmation
1 parent ca77504 commit b4aa629

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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(),
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/145151>.
2+
3+
//@ edition: 2024
4+
//@ check-pass
5+
6+
async fn process<'a>() {
7+
Box::pin(process()).await;
8+
}
9+
10+
fn require_send(_: impl Send) {}
11+
12+
fn main() {
13+
require_send(process());
14+
}

0 commit comments

Comments
 (0)