about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-01 19:07:03 +0000
committerbors <bors@rust-lang.org>2024-06-01 19:07:03 +0000
commit0038c021031ce9f1ec2329469c8d85d0e681ef8f (patch)
tree853b54354c4fef97dcbf8c5d0a3c44644836ead0 /compiler/rustc_middle/src
parenta94483a5f2bae907bc898fc7a8d9cc87db47b693 (diff)
parent333458c2cbafbea22480075decc4a827f913a020 (diff)
downloadrust-0038c021031ce9f1ec2329469c8d85d0e681ef8f.tar.gz
rust-0038c021031ce9f1ec2329469c8d85d0e681ef8f.zip
Auto merge of #125775 - compiler-errors:uplift-closure-args, r=lcnr
Uplift `{Closure,Coroutine,CoroutineClosure}Args` and friends to `rustc_type_ir`

Part of converting the new solver's `structural_traits.rs` to be interner-agnostic.

I decided against aliasing `ClosureArgs<TyCtxt<'tcx>>` to `ClosureArgs<'tcx>` because it seemed so rare. I could do so if desired, though.

r? lcnr
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/mir/query.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs5
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs69
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs7
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs22
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs12
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs731
9 files changed, 126 insertions, 730 deletions
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 9d70231be3b..46b38e4a6a6 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -1,7 +1,7 @@
 //! Values computed by queries that use MIR.
 
 use crate::mir;
-use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
+use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::LocalDefId;
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index c2219fba023..47f66c64406 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -90,7 +90,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type AdtDef = ty::AdtDef<'tcx>;
 
     type GenericArgs = ty::GenericArgsRef<'tcx>;
-    type OwnItemArgs = &'tcx [ty::GenericArg<'tcx>];
+    type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
     type GenericArg = ty::GenericArg<'tcx>;
     type Term = ty::Term<'tcx>;
 
@@ -113,7 +113,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
 
     type ErrorGuaranteed = ErrorGuaranteed;
     type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
-    type PolyFnSig = PolyFnSig<'tcx>;
     type AllocId = crate::mir::interpret::AllocId;
 
     type Pat = Pattern<'tcx>;
@@ -191,7 +190,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self,
         def_id: Self::DefId,
         args: Self::GenericArgs,
-    ) -> (rustc_type_ir::TraitRef<Self>, Self::OwnItemArgs) {
+    ) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
         assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
         let trait_def_id = self.parent(def_id);
         assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 7a516b9f2c8..c3ab755175d 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -2,9 +2,10 @@
 
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
-use crate::ty::sty::{ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs};
 use crate::ty::visit::{TypeVisitable, TypeVisitor};
-use crate::ty::{self, Lift, List, Ty, TyCtxt};
+use crate::ty::{
+    self, ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs, Lift, List, Ty, TyCtxt,
+};
 
 use rustc_ast_ir::visit::VisitorResult;
 use rustc_ast_ir::walk_visitable_list;
@@ -56,6 +57,64 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
     ) -> ty::GenericArgsRef<'tcx> {
         ty::GenericArgs::extend_with_error(tcx, def_id, original_args)
     }
+
+    fn split_closure_args(self) -> ty::ClosureArgsParts<TyCtxt<'tcx>> {
+        match self[..] {
+            [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
+                ty::ClosureArgsParts {
+                    parent_args,
+                    closure_kind_ty: closure_kind_ty.expect_ty(),
+                    closure_sig_as_fn_ptr_ty: closure_sig_as_fn_ptr_ty.expect_ty(),
+                    tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
+                }
+            }
+            _ => bug!("closure args missing synthetics"),
+        }
+    }
+
+    fn split_coroutine_closure_args(self) -> ty::CoroutineClosureArgsParts<TyCtxt<'tcx>> {
+        match self[..] {
+            [
+                ref parent_args @ ..,
+                closure_kind_ty,
+                signature_parts_ty,
+                tupled_upvars_ty,
+                coroutine_captures_by_ref_ty,
+                coroutine_witness_ty,
+            ] => ty::CoroutineClosureArgsParts {
+                parent_args,
+                closure_kind_ty: closure_kind_ty.expect_ty(),
+                signature_parts_ty: signature_parts_ty.expect_ty(),
+                tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
+                coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
+                coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
+            },
+            _ => bug!("closure args missing synthetics"),
+        }
+    }
+
+    fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
+        match self[..] {
+            [
+                ref parent_args @ ..,
+                kind_ty,
+                resume_ty,
+                yield_ty,
+                return_ty,
+                witness,
+                tupled_upvars_ty,
+            ] => ty::CoroutineArgsParts {
+                parent_args,
+                kind_ty: kind_ty.expect_ty(),
+                resume_ty: resume_ty.expect_ty(),
+                yield_ty: yield_ty.expect_ty(),
+                return_ty: return_ty.expect_ty(),
+                witness: witness.expect_ty(),
+                tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
+            },
+            _ => bug!("coroutine args missing synthetics"),
+        }
+    }
 }
 
 impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> {
@@ -295,7 +354,7 @@ impl<'tcx> GenericArgs<'tcx> {
     /// Closure args have a particular structure controlled by the
     /// compiler that encodes information like the signature and closure kind;
     /// see `ty::ClosureArgs` struct for more comments.
-    pub fn as_closure(&'tcx self) -> ClosureArgs<'tcx> {
+    pub fn as_closure(&'tcx self) -> ClosureArgs<TyCtxt<'tcx>> {
         ClosureArgs { args: self }
     }
 
@@ -303,7 +362,7 @@ impl<'tcx> GenericArgs<'tcx> {
     /// Coroutine-closure args have a particular structure controlled by the
     /// compiler that encodes information like the signature and closure kind;
     /// see `ty::CoroutineClosureArgs` struct for more comments.
-    pub fn as_coroutine_closure(&'tcx self) -> CoroutineClosureArgs<'tcx> {
+    pub fn as_coroutine_closure(&'tcx self) -> CoroutineClosureArgs<TyCtxt<'tcx>> {
         CoroutineClosureArgs { args: self }
     }
 
@@ -311,7 +370,7 @@ impl<'tcx> GenericArgs<'tcx> {
     /// Coroutine args have a particular structure controlled by the
     /// compiler that encodes information like the signature and coroutine kind;
     /// see `ty::CoroutineArgs` struct for more comments.
-    pub fn as_coroutine(&'tcx self) -> CoroutineArgs<'tcx> {
+    pub fn as_coroutine(&'tcx self) -> CoroutineArgs<TyCtxt<'tcx>> {
         CoroutineArgs { args: self }
     }
 
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 71030febf76..a2df90b2c0f 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -2,7 +2,7 @@ use crate::error::UnsupportedFnAbi;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::query::TyCtxtAt;
 use crate::ty::normalize_erasing_regions::NormalizationError;
-use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt};
 use rustc_error_messages::DiagMessage;
 use rustc_errors::{
     Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 90c154233da..2643ce976de 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -113,10 +113,8 @@ pub use self::region::{
 pub use self::rvalue_scopes::RvalueScopes;
 pub use self::sty::{
     AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
-    ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs,
-    CoroutineClosureArgsParts, CoroutineClosureSignature, EarlyBinder, FnSig, GenSig,
-    InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut,
-    UpvarArgs, VarianceDiagInfo,
+    CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst,
+    ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
 };
 pub use self::trait_def::TraitDef;
 pub use self::typeck_results::{
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 83790db9926..126da2f5a7c 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1938,7 +1938,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         Ok(())
     }
 
-    fn pretty_closure_as_impl(&mut self, closure: ty::ClosureArgs<'tcx>) -> Result<(), PrintError> {
+    fn pretty_closure_as_impl(
+        &mut self,
+        closure: ty::ClosureArgs<TyCtxt<'tcx>>,
+    ) -> Result<(), PrintError> {
         let sig = closure.sig();
         let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
 
@@ -2973,7 +2976,7 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
 
 #[derive(Debug, Copy, Clone, Lift)]
 pub struct PrintClosureAsImpl<'tcx> {
-    pub closure: ty::ClosureArgs<'tcx>,
+    pub closure: ty::ClosureArgs<TyCtxt<'tcx>>,
 }
 
 macro_rules! forward_display_to_print {
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index f02b4849f83..b4179858890 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -756,28 +756,6 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
     }
 }
 
-impl<'tcx> Relate<'tcx> for ty::ClosureArgs<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: ty::ClosureArgs<'tcx>,
-        b: ty::ClosureArgs<'tcx>,
-    ) -> RelateResult<'tcx, ty::ClosureArgs<'tcx>> {
-        let args = relate_args_invariantly(relation, a.args, b.args)?;
-        Ok(ty::ClosureArgs { args })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::CoroutineArgs<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: ty::CoroutineArgs<'tcx>,
-        b: ty::CoroutineArgs<'tcx>,
-    ) -> RelateResult<'tcx, ty::CoroutineArgs<'tcx>> {
-        let args = relate_args_invariantly(relation, a.args, b.args)?;
-        Ok(ty::CoroutineArgs { args })
-    }
-}
-
 impl<'tcx> Relate<'tcx> for GenericArgsRef<'tcx> {
     fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index af3aa3b56f7..90791bdd20d 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -259,18 +259,6 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for Region<'tcx> {
     }
 }
 
-impl<'tcx, T: DebugWithInfcx<TyCtxt<'tcx>>> DebugWithInfcx<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
-    fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
-        this: WithInfcx<'_, Infcx, &Self>,
-        f: &mut core::fmt::Formatter<'_>,
-    ) -> core::fmt::Result {
-        f.debug_tuple("Binder")
-            .field(&this.map(|data| data.as_ref().skip_binder()))
-            .field(&this.data.bound_vars())
-            .finish()
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Atomic structs
 //
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 5f7385fccc9..879396b0678 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -16,7 +16,7 @@ use rustc_errors::{ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
-use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable};
+use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
@@ -30,7 +30,6 @@ use ty::util::{AsyncDropGlueMorphology, IntTypeExt};
 use rustc_type_ir::TyKind::*;
 use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
 
-use super::fold::FnMutDelegate;
 use super::GenericParamDefKind;
 
 // Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
@@ -60,670 +59,14 @@ impl<'tcx> Article for TyKind<'tcx> {
     }
 }
 
-/// A closure can be modeled as a struct that looks like:
-/// ```ignore (illustrative)
-/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U);
-/// ```
-/// where:
-///
-/// - 'l0...'li and T0...Tj are the generic parameters
-///   in scope on the function that defined the closure,
-/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
-///   is rather hackily encoded via a scalar type. See
-///   `Ty::to_opt_closure_kind` for details.
-/// - CS represents the *closure signature*, representing as a `fn()`
-///   type. For example, `fn(u32, u32) -> u32` would mean that the closure
-///   implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
-///   specified above.
-/// - U is a type parameter representing the types of its upvars, tupled up
-///   (borrowed, if appropriate; that is, if a U field represents a by-ref upvar,
-///    and the up-var has the type `Foo`, then that field of U will be `&Foo`).
-///
-/// So, for example, given this function:
-/// ```ignore (illustrative)
-/// fn foo<'a, T>(data: &'a mut T) {
-///      do(|| data.count += 1)
-/// }
-/// ```
-/// the type of the closure would be something like:
-/// ```ignore (illustrative)
-/// struct Closure<'a, T, U>(...U);
-/// ```
-/// Note that the type of the upvar is not specified in the struct.
-/// You may wonder how the impl would then be able to use the upvar,
-/// if it doesn't know it's type? The answer is that the impl is
-/// (conceptually) not fully generic over Closure but rather tied to
-/// instances with the expected upvar types:
-/// ```ignore (illustrative)
-/// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> {
-///     ...
-/// }
-/// ```
-/// You can see that the *impl* fully specified the type of the upvar
-/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
-/// (Here, I am assuming that `data` is mut-borrowed.)
-///
-/// Now, the last question you may ask is: Why include the upvar types
-/// in an extra type parameter? The reason for this design is that the
-/// upvar types can reference lifetimes that are internal to the
-/// creating function. In my example above, for example, the lifetime
-/// `'b` represents the scope of the closure itself; this is some
-/// subset of `foo`, probably just the scope of the call to the to
-/// `do()`. If we just had the lifetime/type parameters from the
-/// enclosing function, we couldn't name this lifetime `'b`. Note that
-/// there can also be lifetimes in the types of the upvars themselves,
-/// if one of them happens to be a reference to something that the
-/// creating fn owns.
-///
-/// OK, you say, so why not create a more minimal set of parameters
-/// that just includes the extra lifetime parameters? The answer is
-/// primarily that it would be hard --- we don't know at the time when
-/// we create the closure type what the full types of the upvars are,
-/// nor do we know which are borrowed and which are not. In this
-/// design, we can just supply a fresh type parameter and figure that
-/// out later.
-///
-/// All right, you say, but why include the type parameters from the
-/// original function then? The answer is that codegen may need them
-/// when monomorphizing, and they may not appear in the upvars. A
-/// closure could capture no variables but still make use of some
-/// in-scope type parameter with a bound (e.g., if our example above
-/// had an extra `U: Default`, and the closure called `U::default()`).
-///
-/// There is another reason. This design (implicitly) prohibits
-/// closures from capturing themselves (except via a trait
-/// object). This simplifies closure inference considerably, since it
-/// means that when we infer the kind of a closure or its upvars, we
-/// don't have to handle cycles where the decisions we make for
-/// closure C wind up influencing the decisions we ought to make for
-/// closure C (which would then require fixed point iteration to
-/// handle). Plus it fixes an ICE. :P
-///
-/// ## Coroutines
-///
-/// Coroutines are handled similarly in `CoroutineArgs`. The set of
-/// type parameters is similar, but `CK` and `CS` are replaced by the
-/// following type parameters:
-///
-/// * `GS`: The coroutine's "resume type", which is the type of the
-///   argument passed to `resume`, and the type of `yield` expressions
-///   inside the coroutine.
-/// * `GY`: The "yield type", which is the type of values passed to
-///   `yield` inside the coroutine.
-/// * `GR`: The "return type", which is the type of value returned upon
-///   completion of the coroutine.
-/// * `GW`: The "coroutine witness".
-#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
-pub struct ClosureArgs<'tcx> {
-    /// Lifetime and type parameters from the enclosing function,
-    /// concatenated with a tuple containing the types of the upvars.
-    ///
-    /// These are separated out because codegen wants to pass them around
-    /// when monomorphizing.
-    pub args: GenericArgsRef<'tcx>,
-}
-
-/// Struct returned by `split()`.
-pub struct ClosureArgsParts<'tcx> {
-    /// This is the args of the typeck root.
-    pub parent_args: &'tcx [GenericArg<'tcx>],
-    /// Represents the maximum calling capability of the closure.
-    pub closure_kind_ty: Ty<'tcx>,
-    /// Captures the closure's signature. This closure signature is "tupled", and
-    /// thus has a peculiar signature of `extern "rust-call" fn((Args, ...)) -> Ty`.
-    pub closure_sig_as_fn_ptr_ty: Ty<'tcx>,
-    /// The upvars captured by the closure. Remains an inference variable
-    /// until the upvar analysis, which happens late in HIR typeck.
-    pub tupled_upvars_ty: Ty<'tcx>,
-}
-
-impl<'tcx> ClosureArgs<'tcx> {
-    /// Construct `ClosureArgs` from `ClosureArgsParts`, containing `Args`
-    /// for the closure parent, alongside additional closure-specific components.
-    pub fn new(tcx: TyCtxt<'tcx>, parts: ClosureArgsParts<'tcx>) -> ClosureArgs<'tcx> {
-        ClosureArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
-                parts.closure_kind_ty.into(),
-                parts.closure_sig_as_fn_ptr_ty.into(),
-                parts.tupled_upvars_ty.into(),
-            ])),
-        }
-    }
-
-    /// Divides the closure args into their respective components.
-    /// The ordering assumed here must match that used by `ClosureArgs::new` above.
-    fn split(self) -> ClosureArgsParts<'tcx> {
-        match self.args[..] {
-            [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
-                ClosureArgsParts {
-                    parent_args,
-                    closure_kind_ty: closure_kind_ty.expect_ty(),
-                    closure_sig_as_fn_ptr_ty: closure_sig_as_fn_ptr_ty.expect_ty(),
-                    tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
-                }
-            }
-            _ => bug!("closure args missing synthetics"),
-        }
-    }
-
-    /// Returns the generic parameters of the closure's parent.
-    pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
-        self.split().parent_args
-    }
-
-    /// Returns an iterator over the list of types of captured paths by the closure.
-    /// In case there was a type error in figuring out the types of the captured path, an
-    /// empty iterator is returned.
-    #[inline]
-    pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
-        match *self.tupled_upvars_ty().kind() {
-            TyKind::Error(_) => ty::List::empty(),
-            TyKind::Tuple(tys) => tys,
-            TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
-            ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
-        }
-    }
-
-    /// Returns the tuple type representing the upvars for this closure.
-    #[inline]
-    pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
-        self.split().tupled_upvars_ty
-    }
-
-    /// Returns the closure kind for this closure; may return a type
-    /// variable during inference. To get the closure kind during
-    /// inference, use `infcx.closure_kind(args)`.
-    pub fn kind_ty(self) -> Ty<'tcx> {
-        self.split().closure_kind_ty
-    }
-
-    /// Returns the `fn` pointer type representing the closure signature for this
-    /// closure.
-    // FIXME(eddyb) this should be unnecessary, as the shallowly resolved
-    // type is known at the time of the creation of `ClosureArgs`,
-    // see `rustc_hir_analysis::check::closure`.
-    pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> {
-        self.split().closure_sig_as_fn_ptr_ty
-    }
-
-    /// Returns the closure kind for this closure; only usable outside
-    /// of an inference context, because in that context we know that
-    /// there are no type variables.
-    ///
-    /// If you have an inference context, use `infcx.closure_kind()`.
-    pub fn kind(self) -> ty::ClosureKind {
-        self.kind_ty().to_opt_closure_kind().unwrap()
-    }
-
-    /// Extracts the signature from the closure.
-    pub fn sig(self) -> ty::PolyFnSig<'tcx> {
-        match *self.sig_as_fn_ptr_ty().kind() {
-            ty::FnPtr(sig) => sig,
-            ty => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"),
-        }
-    }
-
-    pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> {
-        ty::print::PrintClosureAsImpl { closure: self }
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
-pub struct CoroutineClosureArgs<'tcx> {
-    pub args: GenericArgsRef<'tcx>,
-}
-
-/// See docs for explanation of how each argument is used.
-///
-/// See [`CoroutineClosureSignature`] for how these arguments are put together
-/// to make a callable [`FnSig`] suitable for typeck and borrowck.
-pub struct CoroutineClosureArgsParts<'tcx> {
-    /// This is the args of the typeck root.
-    pub parent_args: &'tcx [GenericArg<'tcx>],
-    /// Represents the maximum calling capability of the closure.
-    pub closure_kind_ty: Ty<'tcx>,
-    /// Represents all of the relevant parts of the coroutine returned by this
-    /// coroutine-closure. This signature parts type will have the general
-    /// shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where
-    /// `resume_ty`, `return_ty`, and `yield_ty` are the respective types for the
-    /// coroutine returned by the coroutine-closure.
-    ///
-    /// Use `coroutine_closure_sig` to break up this type rather than using it
-    /// yourself.
-    pub signature_parts_ty: Ty<'tcx>,
-    /// The upvars captured by the closure. Remains an inference variable
-    /// until the upvar analysis, which happens late in HIR typeck.
-    pub tupled_upvars_ty: Ty<'tcx>,
-    /// a function pointer that has the shape `for<'env> fn() -> (&'env T, ...)`.
-    /// This allows us to represent the binder of the self-captures of the closure.
-    ///
-    /// For example, if the coroutine returned by the closure borrows `String`
-    /// from the closure's upvars, this will be `for<'env> fn() -> (&'env String,)`,
-    /// while the `tupled_upvars_ty`, representing the by-move version of the same
-    /// captures, will be `(String,)`.
-    pub coroutine_captures_by_ref_ty: Ty<'tcx>,
-    /// Witness type returned by the generator produced by this coroutine-closure.
-    pub coroutine_witness_ty: Ty<'tcx>,
-}
-
-impl<'tcx> CoroutineClosureArgs<'tcx> {
-    pub fn new(
-        tcx: TyCtxt<'tcx>,
-        parts: CoroutineClosureArgsParts<'tcx>,
-    ) -> CoroutineClosureArgs<'tcx> {
-        CoroutineClosureArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
-                parts.closure_kind_ty.into(),
-                parts.signature_parts_ty.into(),
-                parts.tupled_upvars_ty.into(),
-                parts.coroutine_captures_by_ref_ty.into(),
-                parts.coroutine_witness_ty.into(),
-            ])),
-        }
-    }
-
-    fn split(self) -> CoroutineClosureArgsParts<'tcx> {
-        match self.args[..] {
-            [
-                ref parent_args @ ..,
-                closure_kind_ty,
-                signature_parts_ty,
-                tupled_upvars_ty,
-                coroutine_captures_by_ref_ty,
-                coroutine_witness_ty,
-            ] => CoroutineClosureArgsParts {
-                parent_args,
-                closure_kind_ty: closure_kind_ty.expect_ty(),
-                signature_parts_ty: signature_parts_ty.expect_ty(),
-                tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
-                coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
-                coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
-            },
-            _ => bug!("closure args missing synthetics"),
-        }
-    }
-
-    pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
-        self.split().parent_args
-    }
-
-    #[inline]
-    pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
-        match self.tupled_upvars_ty().kind() {
-            TyKind::Error(_) => ty::List::empty(),
-            TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
-            TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
-            ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
-        }
-    }
-
-    #[inline]
-    pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
-        self.split().tupled_upvars_ty
-    }
-
-    pub fn kind_ty(self) -> Ty<'tcx> {
-        self.split().closure_kind_ty
-    }
-
-    pub fn kind(self) -> ty::ClosureKind {
-        self.kind_ty().to_opt_closure_kind().unwrap()
-    }
-
-    pub fn signature_parts_ty(self) -> Ty<'tcx> {
-        self.split().signature_parts_ty
-    }
-
-    pub fn coroutine_closure_sig(self) -> Binder<'tcx, CoroutineClosureSignature<'tcx>> {
-        let interior = self.coroutine_witness_ty();
-        let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { bug!() };
-        sig.map_bound(|sig| {
-            let [resume_ty, tupled_inputs_ty] = *sig.inputs() else {
-                bug!();
-            };
-            let [yield_ty, return_ty] = **sig.output().tuple_fields() else { bug!() };
-            CoroutineClosureSignature {
-                interior,
-                tupled_inputs_ty,
-                resume_ty,
-                yield_ty,
-                return_ty,
-                c_variadic: sig.c_variadic,
-                safety: sig.safety,
-                abi: sig.abi,
-            }
-        })
-    }
-
-    pub fn coroutine_captures_by_ref_ty(self) -> Ty<'tcx> {
-        self.split().coroutine_captures_by_ref_ty
-    }
-
-    pub fn coroutine_witness_ty(self) -> Ty<'tcx> {
-        self.split().coroutine_witness_ty
-    }
-
-    pub fn has_self_borrows(&self) -> bool {
-        match self.coroutine_captures_by_ref_ty().kind() {
-            ty::FnPtr(sig) => sig
-                .skip_binder()
-                .visit_with(&mut HasRegionsBoundAt { binder: ty::INNERMOST })
-                .is_break(),
-            ty::Error(_) => true,
-            _ => bug!(),
-        }
-    }
-}
-/// Unlike `has_escaping_bound_vars` or `outermost_exclusive_binder`, this will
-/// detect only regions bound *at* the debruijn index.
-struct HasRegionsBoundAt {
-    binder: ty::DebruijnIndex,
-}
-// FIXME: Could be optimized to not walk into components with no escaping bound vars.
-impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasRegionsBoundAt {
-    type Result = ControlFlow<()>;
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
-        &mut self,
-        t: &ty::Binder<'tcx, T>,
-    ) -> Self::Result {
-        self.binder.shift_in(1);
-        t.super_visit_with(self)?;
-        self.binder.shift_out(1);
-        ControlFlow::Continue(())
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
-        if let ty::ReBound(binder, _) = *r
-            && self.binder == binder
-        {
-            ControlFlow::Break(())
-        } else {
-            ControlFlow::Continue(())
-        }
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
-pub struct CoroutineClosureSignature<'tcx> {
-    pub interior: Ty<'tcx>,
-    pub tupled_inputs_ty: Ty<'tcx>,
-    pub resume_ty: Ty<'tcx>,
-    pub yield_ty: Ty<'tcx>,
-    pub return_ty: Ty<'tcx>,
-
-    // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types
-    // never actually differ. But we save them rather than recreating them
-    // from scratch just for good measure.
-    /// Always false
-    pub c_variadic: bool,
-    /// Always [`hir::Safety::Safe`]
-    pub safety: hir::Safety,
-    /// Always [`abi::Abi::RustCall`]
-    pub abi: abi::Abi,
-}
-
-impl<'tcx> CoroutineClosureSignature<'tcx> {
-    /// Construct a coroutine from the closure signature. Since a coroutine signature
-    /// is agnostic to the type of generator that is returned (by-ref/by-move),
-    /// the caller must specify what "flavor" of generator that they'd like to
-    /// create. Additionally, they must manually compute the upvars of the closure.
-    ///
-    /// This helper is not really meant to be used directly except for early on
-    /// during typeck, when we want to put inference vars into the kind and upvars tys.
-    /// When the kind and upvars are known, use the other helper functions.
-    pub fn to_coroutine(
-        self,
-        tcx: TyCtxt<'tcx>,
-        parent_args: &'tcx [GenericArg<'tcx>],
-        coroutine_kind_ty: Ty<'tcx>,
-        coroutine_def_id: DefId,
-        tupled_upvars_ty: Ty<'tcx>,
-    ) -> Ty<'tcx> {
-        let coroutine_args = ty::CoroutineArgs::new(
-            tcx,
-            ty::CoroutineArgsParts {
-                parent_args,
-                kind_ty: coroutine_kind_ty,
-                resume_ty: self.resume_ty,
-                yield_ty: self.yield_ty,
-                return_ty: self.return_ty,
-                witness: self.interior,
-                tupled_upvars_ty,
-            },
-        );
-
-        Ty::new_coroutine(tcx, coroutine_def_id, coroutine_args.args)
-    }
-
-    /// Given known upvars and a [`ClosureKind`](ty::ClosureKind), compute the coroutine
-    /// returned by that corresponding async fn trait.
-    ///
-    /// This function expects the upvars to have been computed already, and doesn't check
-    /// that the `ClosureKind` is actually supported by the coroutine-closure.
-    pub fn to_coroutine_given_kind_and_upvars(
-        self,
-        tcx: TyCtxt<'tcx>,
-        parent_args: &'tcx [GenericArg<'tcx>],
-        coroutine_def_id: DefId,
-        goal_kind: ty::ClosureKind,
-        env_region: ty::Region<'tcx>,
-        closure_tupled_upvars_ty: Ty<'tcx>,
-        coroutine_captures_by_ref_ty: Ty<'tcx>,
-    ) -> Ty<'tcx> {
-        let tupled_upvars_ty = Self::tupled_upvars_by_closure_kind(
-            tcx,
-            goal_kind,
-            self.tupled_inputs_ty,
-            closure_tupled_upvars_ty,
-            coroutine_captures_by_ref_ty,
-            env_region,
-        );
-
-        self.to_coroutine(
-            tcx,
-            parent_args,
-            Ty::from_coroutine_closure_kind(tcx, goal_kind),
-            coroutine_def_id,
-            tupled_upvars_ty,
-        )
-    }
-
-    /// Compute the tupled upvars that a coroutine-closure's output coroutine
-    /// would return for the given `ClosureKind`.
-    ///
-    /// When `ClosureKind` is `FnMut`/`Fn`, then this will use the "captures by ref"
-    /// to return a set of upvars which are borrowed with the given `env_region`.
-    ///
-    /// This ensures that the `AsyncFn::call` will return a coroutine whose upvars'
-    /// lifetimes are related to the lifetime of the borrow on the closure made for
-    /// the call. This allows borrowck to enforce the self-borrows correctly.
-    pub fn tupled_upvars_by_closure_kind(
-        tcx: TyCtxt<'tcx>,
-        kind: ty::ClosureKind,
-        tupled_inputs_ty: Ty<'tcx>,
-        closure_tupled_upvars_ty: Ty<'tcx>,
-        coroutine_captures_by_ref_ty: Ty<'tcx>,
-        env_region: ty::Region<'tcx>,
-    ) -> Ty<'tcx> {
-        match kind {
-            ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
-                let ty::FnPtr(sig) = *coroutine_captures_by_ref_ty.kind() else {
-                    bug!();
-                };
-                let coroutine_captures_by_ref_ty = tcx.replace_escaping_bound_vars_uncached(
-                    sig.output().skip_binder(),
-                    FnMutDelegate {
-                        consts: &mut |c, t| ty::Const::new_bound(tcx, ty::INNERMOST, c, t),
-                        types: &mut |t| Ty::new_bound(tcx, ty::INNERMOST, t),
-                        regions: &mut |_| env_region,
-                    },
-                );
-                Ty::new_tup_from_iter(
-                    tcx,
-                    tupled_inputs_ty
-                        .tuple_fields()
-                        .iter()
-                        .chain(coroutine_captures_by_ref_ty.tuple_fields()),
-                )
-            }
-            ty::ClosureKind::FnOnce => Ty::new_tup_from_iter(
-                tcx,
-                tupled_inputs_ty
-                    .tuple_fields()
-                    .iter()
-                    .chain(closure_tupled_upvars_ty.tuple_fields()),
-            ),
-        }
-    }
-}
-/// Similar to `ClosureArgs`; see the above documentation for more.
-#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
-pub struct CoroutineArgs<'tcx> {
-    pub args: GenericArgsRef<'tcx>,
-}
-
-pub struct CoroutineArgsParts<'tcx> {
-    /// This is the args of the typeck root.
-    pub parent_args: &'tcx [GenericArg<'tcx>],
-
-    /// The coroutines returned by a coroutine-closure's `AsyncFnOnce`/`AsyncFnMut`
-    /// implementations must be distinguished since the former takes the closure's
-    /// upvars by move, and the latter takes the closure's upvars by ref.
-    ///
-    /// This field distinguishes these fields so that codegen can select the right
-    /// body for the coroutine. This has the same type representation as the closure
-    /// kind: `i8`/`i16`/`i32`.
-    ///
-    /// For regular coroutines, this field will always just be `()`.
-    pub kind_ty: Ty<'tcx>,
-
-    pub resume_ty: Ty<'tcx>,
-    pub yield_ty: Ty<'tcx>,
-    pub return_ty: Ty<'tcx>,
-
-    /// The interior type of the coroutine.
-    /// Represents all types that are stored in locals
-    /// in the coroutine's body.
-    pub witness: Ty<'tcx>,
-
-    /// The upvars captured by the closure. Remains an inference variable
-    /// until the upvar analysis, which happens late in HIR typeck.
-    pub tupled_upvars_ty: Ty<'tcx>,
-}
-
-impl<'tcx> CoroutineArgs<'tcx> {
-    /// Construct `CoroutineArgs` from `CoroutineArgsParts`, containing `Args`
-    /// for the coroutine parent, alongside additional coroutine-specific components.
-    pub fn new(tcx: TyCtxt<'tcx>, parts: CoroutineArgsParts<'tcx>) -> CoroutineArgs<'tcx> {
-        CoroutineArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
-                parts.kind_ty.into(),
-                parts.resume_ty.into(),
-                parts.yield_ty.into(),
-                parts.return_ty.into(),
-                parts.witness.into(),
-                parts.tupled_upvars_ty.into(),
-            ])),
-        }
-    }
-
-    /// Divides the coroutine args into their respective components.
-    /// The ordering assumed here must match that used by `CoroutineArgs::new` above.
-    fn split(self) -> CoroutineArgsParts<'tcx> {
-        match self.args[..] {
-            [
-                ref parent_args @ ..,
-                kind_ty,
-                resume_ty,
-                yield_ty,
-                return_ty,
-                witness,
-                tupled_upvars_ty,
-            ] => CoroutineArgsParts {
-                parent_args,
-                kind_ty: kind_ty.expect_ty(),
-                resume_ty: resume_ty.expect_ty(),
-                yield_ty: yield_ty.expect_ty(),
-                return_ty: return_ty.expect_ty(),
-                witness: witness.expect_ty(),
-                tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
-            },
-            _ => bug!("coroutine args missing synthetics"),
-        }
-    }
-
-    /// Returns the generic parameters of the coroutine's parent.
-    pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
-        self.split().parent_args
-    }
-
-    // Returns the kind of the coroutine. See docs on the `kind_ty` field.
-    pub fn kind_ty(self) -> Ty<'tcx> {
-        self.split().kind_ty
-    }
-
-    /// This describes the types that can be contained in a coroutine.
-    /// It will be a type variable initially and unified in the last stages of typeck of a body.
-    /// It contains a tuple of all the types that could end up on a coroutine frame.
-    /// The state transformation MIR pass may only produce layouts which mention types
-    /// in this tuple. Upvars are not counted here.
-    pub fn witness(self) -> Ty<'tcx> {
-        self.split().witness
-    }
-
-    /// Returns an iterator over the list of types of captured paths by the coroutine.
-    /// In case there was a type error in figuring out the types of the captured path, an
-    /// empty iterator is returned.
-    #[inline]
-    pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
-        match *self.tupled_upvars_ty().kind() {
-            TyKind::Error(_) => ty::List::empty(),
-            TyKind::Tuple(tys) => tys,
-            TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
-            ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
-        }
-    }
-
-    /// Returns the tuple type representing the upvars for this coroutine.
-    #[inline]
-    pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
-        self.split().tupled_upvars_ty
-    }
-
-    /// Returns the type representing the resume type of the coroutine.
-    pub fn resume_ty(self) -> Ty<'tcx> {
-        self.split().resume_ty
-    }
-
-    /// Returns the type representing the yield type of the coroutine.
-    pub fn yield_ty(self) -> Ty<'tcx> {
-        self.split().yield_ty
-    }
-
-    /// Returns the type representing the return type of the coroutine.
-    pub fn return_ty(self) -> Ty<'tcx> {
-        self.split().return_ty
-    }
-
-    /// Returns the "coroutine signature", which consists of its resume, yield
-    /// and return types.
-    pub fn sig(self) -> GenSig<'tcx> {
-        let parts = self.split();
-        ty::GenSig {
-            resume_ty: parts.resume_ty,
-            yield_ty: parts.yield_ty,
-            return_ty: parts.return_ty,
-        }
-    }
-}
-
-impl<'tcx> CoroutineArgs<'tcx> {
+#[extension(pub trait CoroutineArgsExt<'tcx>)]
+impl<'tcx> ty::CoroutineArgs<TyCtxt<'tcx>> {
     /// Coroutine has not been resumed yet.
-    pub const UNRESUMED: usize = 0;
+    const UNRESUMED: usize = 0;
     /// Coroutine has returned or is completed.
-    pub const RETURNED: usize = 1;
+    const RETURNED: usize = 1;
     /// Coroutine has been poisoned.
-    pub const POISONED: usize = 2;
+    const POISONED: usize = 2;
 
     const UNRESUMED_NAME: &'static str = "Unresumed";
     const RETURNED_NAME: &'static str = "Returned";
@@ -731,7 +74,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
 
     /// The valid variant indices of this coroutine.
     #[inline]
-    pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
+    fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
         // FIXME requires optimized MIR
         FIRST_VARIANT
             ..tcx.coroutine_layout(def_id, tcx.types.unit).unwrap().variant_fields.next_index()
@@ -740,7 +83,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
     /// The discriminant for the given variant. Panics if the `variant_index` is
     /// out of range.
     #[inline]
-    pub fn discriminant_for_variant(
+    fn discriminant_for_variant(
         &self,
         def_id: DefId,
         tcx: TyCtxt<'tcx>,
@@ -755,7 +98,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
     /// The set of all discriminants for the coroutine, enumerated with their
     /// variant indices.
     #[inline]
-    pub fn discriminants(
+    fn discriminants(
         self,
         def_id: DefId,
         tcx: TyCtxt<'tcx>,
@@ -767,7 +110,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
 
     /// Calls `f` with a reference to the name of the enumerator for the given
     /// variant `v`.
-    pub fn variant_name(v: VariantIdx) -> Cow<'static, str> {
+    fn variant_name(v: VariantIdx) -> Cow<'static, str> {
         match v.as_usize() {
             Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),
             Self::RETURNED => Cow::from(Self::RETURNED_NAME),
@@ -778,7 +121,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
 
     /// The type of the state discriminant used in the coroutine type.
     #[inline]
-    pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+    fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         tcx.types.u32
     }
 
@@ -789,7 +132,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
     /// The locals are grouped by their variant number. Note that some locals may
     /// be repeated in multiple variants.
     #[inline]
-    pub fn state_tys(
+    fn state_tys(
         self,
         def_id: DefId,
         tcx: TyCtxt<'tcx>,
@@ -805,7 +148,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
     /// This is the types of the fields of a coroutine which are not stored in a
     /// variant.
     #[inline]
-    pub fn prefix_tys(self) -> &'tcx List<Ty<'tcx>> {
+    fn prefix_tys(self) -> &'tcx List<Ty<'tcx>> {
         self.upvar_tys()
     }
 }
@@ -859,7 +202,7 @@ impl<'tcx> UpvarArgs<'tcx> {
 ///
 /// When the inline const is instantiated, `R` is instantiated as the actual inferred
 /// type of the constant. The reason that `R` is represented as an extra type parameter
-/// is the same reason that [`ClosureArgs`] have `CS` and `U` as type parameters:
+/// is the same reason that [`ty::ClosureArgs`] have `CS` and `U` as type parameters:
 /// inline const can reference lifetimes that are internal to the creating function.
 #[derive(Copy, Clone, Debug)]
 pub struct InlineConstArgs<'tcx> {
@@ -938,13 +281,6 @@ impl BoundVariableKind {
     }
 }
 
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
-pub struct GenSig<'tcx> {
-    pub resume_ty: Ty<'tcx>,
-    pub yield_ty: Ty<'tcx>,
-    pub return_ty: Ty<'tcx>,
-}
-
 pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>;
 pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>;
 
@@ -1451,6 +787,41 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
     ) -> Self {
         Ty::new_alias(interner, kind, alias_ty)
     }
+
+    fn new_coroutine(
+        interner: TyCtxt<'tcx>,
+        def_id: DefId,
+        args: ty::GenericArgsRef<'tcx>,
+    ) -> Self {
+        Ty::new_coroutine(interner, def_id, args)
+    }
+
+    fn new_tup_from_iter<It, T>(interner: TyCtxt<'tcx>, iter: It) -> T::Output
+    where
+        It: Iterator<Item = T>,
+        T: CollectAndApply<Self, Self>,
+    {
+        Ty::new_tup_from_iter(interner, iter)
+    }
+
+    fn tuple_fields(self) -> &'tcx ty::List<Ty<'tcx>> {
+        self.tuple_fields()
+    }
+
+    fn to_opt_closure_kind(self) -> Option<ty::ClosureKind> {
+        self.to_opt_closure_kind()
+    }
+
+    fn from_closure_kind(interner: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Self {
+        Ty::from_closure_kind(interner, kind)
+    }
+
+    fn from_coroutine_closure_kind(
+        interner: TyCtxt<'tcx>,
+        kind: rustc_type_ir::ClosureKind,
+    ) -> Self {
+        Ty::from_coroutine_closure_kind(interner, kind)
+    }
 }
 
 /// Type utilities
@@ -2169,8 +1540,8 @@ impl<'tcx> Ty<'tcx> {
     /// }
     /// ```
     ///
-    /// After upvar analysis, you should instead use [`ClosureArgs::kind()`]
-    /// or [`CoroutineClosureArgs::kind()`] to assert that the `ClosureKind`
+    /// After upvar analysis, you should instead use [`ty::ClosureArgs::kind()`]
+    /// or [`ty::CoroutineClosureArgs::kind()`] to assert that the `ClosureKind`
     /// has been constrained instead of manually calling this method.
     ///
     /// ```rust,ignore (snippet of compiler code)