Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/ty.rs')
-rw-r--r--crates/hir-ty/src/next_solver/ty.rs27
1 files changed, 27 insertions, 0 deletions
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index 92f1076e75..4794e2d604 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -4,6 +4,7 @@ use hir_def::{GenericDefId, TypeOrConstParamId, TypeParamId};
use intern::{Interned, Symbol, sym};
use rustc_abi::{Float, Integer, Size};
use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult};
+use rustc_type_ir::Interner;
use rustc_type_ir::{
BoundVar, ClosureKind, FlagComputation, Flags, FloatTy, FloatVid, InferTy, IntTy, IntVid,
TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, UintTy,
@@ -19,6 +20,7 @@ use rustc_type_ir::{
use salsa::plumbing::{AsId, FromId};
use smallvec::SmallVec;
+use crate::next_solver::GenericArg;
use crate::{
db::HirDatabase,
interner::InternedWrapperNoDebug,
@@ -645,6 +647,31 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
Ty::new(interner, TyKind::CoroutineWitness(def_id, args))
}
+ fn new_coroutine_witness_for_coroutine(
+ interner: DbInterner<'db>,
+ def_id: <DbInterner<'db> as rustc_type_ir::Interner>::DefId,
+ coroutine_args: <DbInterner<'db> as rustc_type_ir::Interner>::GenericArgs,
+ ) -> Self {
+ // HACK: Coroutine witness types are lifetime erased, so they
+ // never reference any lifetime args from the coroutine. We erase
+ // the regions here since we may get into situations where a
+ // coroutine is recursively contained within itself, leading to
+ // witness types that differ by region args. This means that
+ // cycle detection in fulfillment will not kick in, which leads
+ // to unnecessary overflows in async code. See the issue:
+ // <https://github.com/rust-lang/rust/issues/145151>.
+ let coroutine_args = interner.mk_args_from_iter(coroutine_args.iter().map(|arg| {
+ match arg {
+ GenericArg::Ty(_) | GenericArg::Const(_) => arg,
+ GenericArg::Lifetime(_) => {
+ crate::next_solver::Region::new(interner, rustc_type_ir::RegionKind::ReErased)
+ .into()
+ }
+ }
+ }));
+ Ty::new_coroutine_witness(interner, def_id, coroutine_args)
+ }
+
fn new_ptr(interner: DbInterner<'db>, ty: Self, mutbl: rustc_ast_ir::Mutability) -> Self {
Ty::new(interner, TyKind::RawPtr(ty, mutbl))
}