about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs43
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs3
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs7
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs1
-rw-r--r--compiler/rustc_const_eval/src/lib.rs7
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs3
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0698.md4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs22
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs62
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs601
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs92
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs96
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs306
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs242
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/mod.rs723
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs6
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/at.rs23
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs1
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs20
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs35
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs10
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs2
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs19
-rw-r--r--compiler/rustc_interface/src/interface.rs6
-rw-r--r--compiler/rustc_interface/src/lib.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs37
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint/src/types.rs1
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs1
-rw-r--r--compiler/rustc_metadata/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs20
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs11
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs6
-rw-r--r--compiler/rustc_middle/src/hooks/mod.rs65
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs17
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs1
-rw-r--r--compiler/rustc_middle/src/ty/context.rs7
-rw-r--r--compiler/rustc_middle/src/ty/error.rs5
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs13
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs6
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs1
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs5
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs4
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs5
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs14
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs8
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs18
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs70
-rw-r--r--compiler/rustc_middle/src/ty/util.rs22
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs5
-rw-r--r--compiler/rustc_middle/src/util/mod.rs24
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs6
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs34
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs110
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs5
-rw-r--r--compiler/rustc_privacy/src/lib.rs3
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs58
-rw-r--r--compiler/rustc_session/src/options.rs6
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs6
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs8
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs3
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs56
-rw-r--r--compiler/rustc_target/src/spec/armv7_apple_ios.rs21
-rw-r--r--compiler/rustc_target/src/spec/armv7s_apple_ios.rs4
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_darwin.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs12
-rw-r--r--compiler/rustc_trait_selection/src/solve/canonicalize.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs212
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs53
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs1
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs6
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs28
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs8
-rw-r--r--compiler/rustc_type_ir/src/sty.rs66
113 files changed, 552 insertions, 3084 deletions
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 697ae015fed..ce7e31682f1 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -80,7 +80,7 @@ use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMes
 use rustc_fluent_macro::fluent_messages;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
-use rustc_middle::query::Providers;
+use rustc_middle::util::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{Lto, OptLevel, OutputFilenames};
 use rustc_session::Session;
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index ac199624e34..fe87446f5c3 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -39,8 +39,8 @@ use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, Subd
 use rustc_fluent_macro::fluent_messages;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
-use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
+use rustc_middle::util::Providers;
 use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest};
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 5b869bed0a0..9cd4394108a 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -11,10 +11,10 @@ use rustc_middle::middle::exported_symbols::{
     metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
 };
 use rustc_middle::query::LocalCrate;
-use rustc_middle::query::{ExternProviders, Providers};
 use rustc_middle::ty::Instance;
 use rustc_middle::ty::{self, SymbolName, TyCtxt};
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
+use rustc_middle::util::Providers;
 use rustc_session::config::{CrateType, OomStrategy};
 use rustc_target::spec::SanitizerSet;
 
@@ -457,11 +457,9 @@ pub fn provide(providers: &mut Providers) {
     providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
     providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
     providers.wasm_import_module_map = wasm_import_module_map;
-}
-
-pub fn provide_extern(providers: &mut ExternProviders) {
-    providers.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
-    providers.upstream_monomorphizations_for = upstream_monomorphizations_for_provider;
+    providers.extern_queries.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
+    providers.extern_queries.upstream_monomorphizations_for =
+        upstream_monomorphizations_for_provider;
 }
 
 fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel {
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index a2190293c0b..989df448a31 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -426,7 +426,6 @@ fn push_debuginfo_type_name<'tcx>(
         | ty::Placeholder(..)
         | ty::Alias(..)
         | ty::Bound(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::GeneratorWitness(..) => {
             bug!(
                 "debuginfo: Trying to create type name for \
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 7bed3fa6150..7ebaca9b0bc 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -31,7 +31,7 @@ use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::dependency_format::Dependencies;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
-use rustc_middle::query::{ExternProviders, Providers};
+use rustc_middle::util::Providers;
 use rustc_serialize::opaque::{FileEncoder, MemDecoder};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
@@ -190,10 +190,6 @@ pub fn provide(providers: &mut Providers) {
     crate::codegen_attrs::provide(providers);
 }
 
-pub fn provide_extern(providers: &mut ExternProviders) {
-    crate::back::symbol_export::provide_extern(providers);
-}
-
 /// Checks if the given filename ends with the `.rcgu.o` extension that `rustc`
 /// uses for the object files it generates.
 pub fn looks_like_rust_object_file(filename: &str) -> bool {
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index d1560114763..0dc30d21c5b 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -158,8 +158,7 @@ fn calculate_debuginfo_offset<
     L: DebugInfoOffsetLocation<'tcx, Bx>,
 >(
     bx: &mut Bx,
-    local: mir::Local,
-    var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
+    projection: &[mir::PlaceElem<'tcx>],
     base: L,
 ) -> DebugInfoOffset<L> {
     let mut direct_offset = Size::ZERO;
@@ -167,7 +166,7 @@ fn calculate_debuginfo_offset<
     let mut indirect_offsets = vec![];
     let mut place = base;
 
-    for elem in &var.projection[..] {
+    for elem in projection {
         match *elem {
             mir::ProjectionElem::Deref => {
                 indirect_offsets.push(Size::ZERO);
@@ -188,11 +187,7 @@ fn calculate_debuginfo_offset<
             } => {
                 let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
                 let FieldsShape::Array { stride, count: _ } = place.layout().fields else {
-                    span_bug!(
-                        var.source_info.span,
-                        "ConstantIndex on non-array type {:?}",
-                        place.layout()
-                    )
+                    bug!("ConstantIndex on non-array type {:?}", place.layout())
                 };
                 *offset += stride * index;
                 place = place.project_constant_index(bx, index);
@@ -200,11 +195,7 @@ fn calculate_debuginfo_offset<
             _ => {
                 // Sanity check for `can_use_in_debuginfo`.
                 debug_assert!(!elem.can_use_in_debuginfo());
-                span_bug!(
-                    var.source_info.span,
-                    "unsupported var debuginfo place `{:?}`",
-                    mir::Place { local, projection: var.projection },
-                )
+                bug!("unsupported var debuginfo projection `{:?}`", projection)
             }
         }
     }
@@ -407,7 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
 
         let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
-            calculate_debuginfo_offset(bx, local, &var, base.layout);
+            calculate_debuginfo_offset(bx, &var.projection, base.layout);
 
         // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
         // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
@@ -425,7 +416,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         if should_create_individual_allocas {
             let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
-                calculate_debuginfo_offset(bx, local, &var, base);
+                calculate_debuginfo_offset(bx, &var.projection, base);
 
             // Create a variable which will be a pointer to the actual value
             let ptr_ty = Ty::new_ptr(
@@ -532,23 +523,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let fragment = if let Some(ref fragment) = var.composite {
                 let var_layout = self.cx.layout_of(var_ty);
 
-                let mut fragment_start = Size::ZERO;
-                let mut fragment_layout = var_layout;
-
-                for elem in &fragment.projection {
-                    match *elem {
-                        mir::ProjectionElem::Field(field, _) => {
-                            let i = field.index();
-                            fragment_start += fragment_layout.fields.offset(i);
-                            fragment_layout = fragment_layout.field(self.cx, i);
-                        }
-                        _ => span_bug!(
-                            var.source_info.span,
-                            "unsupported fragment projection `{:?}`",
-                            elem,
-                        ),
-                    }
-                }
+                let DebugInfoOffset { direct_offset, indirect_offsets, result: fragment_layout } =
+                    calculate_debuginfo_offset(bx, &fragment.projection, var_layout);
+                debug_assert!(indirect_offsets.is_empty());
 
                 if fragment_layout.size == Size::ZERO {
                     // Fragment is a ZST, so does not represent anything. Avoid generating anything
@@ -559,7 +536,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     // DWARF is concerned, it's not really a fragment.
                     None
                 } else {
-                    Some(fragment_start..fragment_start + fragment_layout.size)
+                    Some(direct_offset..direct_offset + fragment_layout.size)
                 }
             } else {
                 None
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 0a02ca6b317..ac8123bc1be 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -11,9 +11,9 @@ use rustc_data_structures::sync::{DynSend, DynSync};
 use rustc_errors::ErrorGuaranteed;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
-use rustc_middle::query::{ExternProviders, Providers};
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_middle::util::Providers;
 use rustc_session::{
     config::{self, OutputFilenames, PrintRequest},
     cstore::MetadataLoaderDyn,
@@ -85,7 +85,6 @@ pub trait CodegenBackend {
     }
 
     fn provide(&self, _providers: &mut Providers) {}
-    fn provide_extern(&self, _providers: &mut ExternProviders) {}
     fn codegen_crate<'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 886d7972a15..bcbe996be7d 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -4,6 +4,7 @@ use crate::errors::MaxNumNodesInConstErr;
 use crate::interpret::{intern_const_alloc_recursive, InternKind, InterpCx, Scalar};
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
+use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
 
@@ -86,17 +87,17 @@ pub(crate) fn eval_to_valtree<'tcx>(
 
 #[instrument(skip(tcx), level = "debug")]
 pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
-    tcx: TyCtxt<'tcx>,
+    tcx: TyCtxtAt<'tcx>,
     val: mir::ConstValue<'tcx>,
     ty: Ty<'tcx>,
 ) -> Option<mir::DestructuredConstant<'tcx>> {
     let param_env = ty::ParamEnv::reveal_all();
-    let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
+    let ecx = mk_eval_cx(tcx.tcx, tcx.span, param_env, CanAccessStatics::No);
     let op = ecx.const_val_to_op(val, ty, None).ok()?;
 
     // We go to `usize` as we cannot allocate anything bigger anyway.
     let (field_count, variant, down) = match ty.kind() {
-        ty::Array(_, len) => (len.eval_target_usize(tcx, param_env) as usize, None, op),
+        ty::Array(_, len) => (len.eval_target_usize(tcx.tcx, param_env) as usize, None, op),
         ty::Adt(def, _) if def.variants().is_empty() => {
             return None;
         }
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 2fba7455cb2..7436ea6ae57 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -152,7 +152,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
         // FIXME(oli-obk): we can probably encode closures just like structs
         | ty::Closure(..)
         | ty::Generator(..)
-        | ty::GeneratorWitness(..) |ty::GeneratorWitnessMIR(..)=> Err(ValTreeCreationError::NonSupportedType),
+        | ty::GeneratorWitness(..) => Err(ValTreeCreationError::NonSupportedType),
     }
 }
 
@@ -280,7 +280,6 @@ pub fn valtree_to_const_value<'tcx>(
         | ty::Closure(..)
         | ty::Generator(..)
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::FnPtr(_)
         | ty::RawPtr(_)
         | ty::Str
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 83f2052d0f8..7c743a21d93 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -963,7 +963,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 | ty::Ref(..)
                 | ty::Generator(..)
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Array(..)
                 | ty::Closure(..)
                 | ty::Never
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 2b26dbbba98..2c0ba9b2673 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -100,8 +100,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
             | ty::Dynamic(_, _, _)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(_, _)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 8e2b35fd5b6..3e023a89648 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -583,7 +583,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
             | ty::Bound(..)
             | ty::Param(..)
             | ty::Alias(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
         }
     }
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index c126f749bf3..8bb409cea08 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -38,8 +38,7 @@ pub use errors::ReportErrorExt;
 
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
-use rustc_middle::query::Providers;
-use rustc_middle::ty;
+use rustc_middle::{ty, util::Providers};
 
 fluent_messages! { "../messages.ftl" }
 
@@ -52,8 +51,8 @@ pub fn provide(providers: &mut Providers) {
         let (param_env, raw) = param_env_and_value.into_parts();
         const_eval::eval_to_valtree(tcx, param_env, raw)
     };
-    providers.try_destructure_mir_constant_for_diagnostics =
-        |tcx, (cv, ty)| const_eval::try_destructure_mir_constant_for_diagnostics(tcx, cv, ty);
+    providers.hooks.try_destructure_mir_constant_for_diagnostics =
+        const_eval::try_destructure_mir_constant_for_diagnostics;
     providers.valtree_to_const_val = |tcx, (ty, valtree)| {
         const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
     };
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index 14a840ad1b1..a924afda6f0 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -64,8 +64,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
 
             ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
             ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
-            ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
-            ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"),
+            ty::GeneratorWitness(..) => bug!("type_name: unexpected `GeneratorWitness`"),
         }
     }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0698.md b/compiler/rustc_error_codes/src/error_codes/E0698.md
index 3ba992a8476..9bc652e642f 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0698.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0698.md
@@ -1,9 +1,11 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 When using generators (or async) all type variables must be bound so a
 generator can be constructed.
 
 Erroneous code example:
 
-```edition2018,compile_fail,E0698
+```edition2018,compile_fail,E0282
 async fn bar<T>() -> () {}
 
 async fn foo() {
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 116222ba56e..564206f9e4b 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1579,13 +1579,7 @@ fn opaque_type_cycle_error(
                         label_match(capture.place.ty(), capture.get_path_span(tcx));
                     }
                     // Label any generator locals that capture the opaque
-                    for interior_ty in
-                        typeck_results.generator_interior_types.as_ref().skip_binder()
-                    {
-                        label_match(interior_ty.ty, interior_ty.span);
-                    }
-                    if tcx.sess.opts.unstable_opts.drop_tracking_mir
-                        && let DefKind::Generator = tcx.def_kind(closure_def_id)
+                    if let DefKind::Generator = tcx.def_kind(closure_def_id)
                         && let Some(generator_layout) = tcx.mir_generator_witnesses(closure_def_id)
                     {
                         for interior_ty in &generator_layout.field_tys {
@@ -1603,7 +1597,6 @@ fn opaque_type_cycle_error(
 }
 
 pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    debug_assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
     debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Generator));
 
     let typeck = tcx.typeck(def_id);
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 7be18a36d63..ba58f0d57ad 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1134,7 +1134,10 @@ fn report_trait_method_mismatch<'tcx>(
         &mut diag,
         &cause,
         trait_err_span.map(|sp| (sp, Cow::from("type in trait"))),
-        Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })),
+        Some(infer::ValuePairs::PolySigs(ExpectedFound {
+            expected: ty::Binder::dummy(trait_sig),
+            found: ty::Binder::dummy(impl_sig),
+        })),
         terr,
         false,
         false,
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 0cf3cee66b5..88c98fa979e 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -573,10 +573,7 @@ pub fn check_function_signature<'tcx>(
     let norm_cause = ObligationCause::misc(cause.span, local_id);
     let actual_sig = ocx.normalize(&norm_cause, param_env, actual_sig);
 
-    let expected_ty = Ty::new_fn_ptr(tcx, expected_sig);
-    let actual_ty = Ty::new_fn_ptr(tcx, actual_sig);
-
-    match ocx.eq(&cause, param_env, expected_ty, actual_ty) {
+    match ocx.eq(&cause, param_env, expected_sig, actual_sig) {
         Ok(()) => {
             let errors = ocx.select_all_or_error();
             if !errors.is_empty() {
@@ -595,9 +592,9 @@ pub fn check_function_signature<'tcx>(
                 &mut diag,
                 &cause,
                 None,
-                Some(infer::ValuePairs::Sigs(ExpectedFound {
-                    expected: tcx.liberate_late_bound_regions(fn_id, expected_sig),
-                    found: tcx.liberate_late_bound_regions(fn_id, actual_sig),
+                Some(infer::ValuePairs::PolySigs(ExpectedFound {
+                    expected: expected_sig,
+                    found: actual_sig,
                 })),
                 err,
                 false,
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index b97e0a80fe6..00a684f2963 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1755,6 +1755,8 @@ fn check_variances_for_type_defn<'tcx>(
             .collect::<FxHashSet<_>>()
     });
 
+    let ty_generics = tcx.generics_of(item.owner_id);
+
     for (index, _) in variances.iter().enumerate() {
         let parameter = Parameter(index as u32);
 
@@ -1762,13 +1764,27 @@ fn check_variances_for_type_defn<'tcx>(
             continue;
         }
 
-        let param = &hir_generics.params[index];
+        let ty_param = &ty_generics.params[index];
+        let hir_param = &hir_generics.params[index];
+
+        if ty_param.def_id != hir_param.def_id.into() {
+            // valid programs always have lifetimes before types in the generic parameter list
+            // ty_generics are normalized to be in this required order, and variances are built
+            // from ty generics, not from hir generics. but we need hir generics to get
+            // a span out
+            //
+            // if they aren't in the same order, then the user has written invalid code, and already
+            // got an error about it (or I'm wrong about this)
+            tcx.sess
+                .delay_span_bug(hir_param.span, "hir generics and ty generics in different order");
+            continue;
+        }
 
-        match param.name {
+        match hir_param.name {
             hir::ParamName::Error => {}
             _ => {
                 let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
-                report_bivariance(tcx, param, has_explicit_bounds);
+                report_bivariance(tcx, hir_param, has_explicit_bounds);
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index aa7c9e504c1..0042d683b19 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -157,7 +157,6 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Bound(..)
             | ty::Placeholder(_)
             | ty::Infer(_) => {
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index bbdb108c59b..69020b1f11d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -245,7 +245,6 @@ fn do_orphan_check_impl<'tcx>(
             ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Bound(..)
             | ty::Placeholder(..)
             | ty::Infer(..) => {
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 8a40509d7cc..9aac7160f2e 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -314,11 +314,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 // types, where we use Error as the Self type
             }
 
-            ty::Placeholder(..)
-            | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
-            | ty::Bound(..)
-            | ty::Infer(..) => {
+            ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Bound(..) | ty::Infer(..) => {
                 bug!("unexpected type encountered in variance inference: {}", ty);
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 3319b52e246..81fe0cc489e 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -2,6 +2,7 @@ use crate::coercion::{AsCoercionSite, CoerceMany};
 use crate::{Diverges, Expectation, FnCtxt, Needs};
 use rustc_errors::Diagnostic;
 use rustc_hir::{self as hir, ExprKind};
+use rustc_hir_pretty::ty_to_string;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::traits::Obligation;
 use rustc_middle::ty::{self, Ty};
@@ -252,7 +253,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     {
         // If this `if` expr is the parent's function return expr,
         // the cause of the type coercion is the return type, point at it. (#25228)
-        let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
+        let hir_id = self.tcx.hir().parent_id(self.tcx.hir().parent_id(then_expr.hir_id));
+        let ret_reason = self.maybe_get_coercion_reason(hir_id, span);
         let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
         let mut error = false;
         coercion.coerce_forced_unit(
@@ -275,11 +277,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         error
     }
 
-    fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> {
-        let node = {
-            let rslt = self.tcx.hir().parent_id(self.tcx.hir().parent_id(hir_id));
-            self.tcx.hir().get(rslt)
-        };
+    pub fn maybe_get_coercion_reason(
+        &self,
+        hir_id: hir::HirId,
+        sp: Span,
+    ) -> Option<(Span, String)> {
+        let node = self.tcx.hir().get(hir_id);
         if let hir::Node::Block(block) = node {
             // check that the body's parent is an fn
             let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id));
@@ -289,9 +292,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // check that the `if` expr without `else` is the fn body's expr
                 if expr.span == sp {
                     return self.get_fn_decl(hir_id).and_then(|(_, fn_decl, _)| {
-                        let span = fn_decl.output.span();
-                        let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
-                        Some((span, format!("expected `{snippet}` because of this return type")))
+                        let (ty, span) = match fn_decl.output {
+                            hir::FnRetTy::DefaultReturn(span) => ("()".to_string(), span),
+                            hir::FnRetTy::Return(ty) => (ty_to_string(ty), ty.span),
+                        };
+                        Some((span, format!("expected `{ty}` because of this return type")))
                     });
                 }
             }
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 57cd88afcdc..2b1ac7f3537 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -129,7 +129,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             | ty::Float(_)
             | ty::Array(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::RawPtr(_)
             | ty::Ref(..)
             | ty::FnDef(..)
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 2c16f21b491..c08629a5269 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -83,6 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         self.annotate_expected_due_to_let_ty(err, expr, error);
+        self.annotate_loop_expected_due_to_inference(err, expr, error);
 
         // FIXME(#73154): For now, we do leak check when coercing function
         // pointers in typeck, instead of only during borrowck. This can lead
@@ -527,6 +528,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         false
     }
 
+    // When encountering a type error on the value of a `break`, try to point at the reason for the
+    // expected type.
+    fn annotate_loop_expected_due_to_inference(
+        &self,
+        err: &mut Diagnostic,
+        expr: &hir::Expr<'_>,
+        error: Option<TypeError<'tcx>>,
+    ) {
+        let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
+            return;
+        };
+        let mut parent_id = self.tcx.hir().parent_id(expr.hir_id);
+        loop {
+            // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement.
+            let Some(hir::Node::Expr(parent)) = self.tcx.hir().find(parent_id) else {
+                break;
+            };
+            parent_id = self.tcx.hir().parent_id(parent.hir_id);
+            let hir::ExprKind::Break(destination, _) = parent.kind else {
+                continue;
+            };
+            let mut parent_id = parent.hir_id;
+            loop {
+                // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
+                let parent = match self.tcx.hir().find(parent_id) {
+                    Some(hir::Node::Expr(&ref parent)) => {
+                        parent_id = self.tcx.hir().parent_id(parent.hir_id);
+                        parent
+                    }
+                    Some(hir::Node::Stmt(hir::Stmt {
+                        hir_id,
+                        kind: hir::StmtKind::Semi(&ref parent) | hir::StmtKind::Expr(&ref parent),
+                        ..
+                    })) => {
+                        parent_id = self.tcx.hir().parent_id(*hir_id);
+                        parent
+                    }
+                    Some(hir::Node::Block(hir::Block { .. })) => {
+                        parent_id = self.tcx.hir().parent_id(parent_id);
+                        parent
+                    }
+                    _ => break,
+                };
+                if let hir::ExprKind::Loop(_, label, _, span) = parent.kind
+                    && destination.label == label
+                {
+                    if let Some((reason_span, message)) =
+                        self.maybe_get_coercion_reason(parent_id, parent.span)
+                    {
+                        err.span_label(reason_span, message);
+                        err.span_label(
+                            span,
+                            format!("this loop is expected to be of type `{expected}`"),
+                        );
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
     fn annotate_expected_due_to_let_ty(
         &self,
         err: &mut Diagnostic,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index fea726ff8ca..415920221f5 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -509,28 +509,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         typeck_results.rvalue_scopes = rvalue_scopes;
     }
 
-    pub(in super::super) fn resolve_generator_interiors(&self, def_id: DefId) {
-        if self.tcx.sess.opts.unstable_opts.drop_tracking_mir {
-            self.save_generator_interior_predicates(def_id);
-            return;
-        }
-
-        self.select_obligations_where_possible(|_| {});
-
-        let mut generators = self.deferred_generator_interiors.borrow_mut();
-        for (generator_def_id, body_id, interior, kind) in generators.drain(..) {
-            crate::generator_interior::resolve_interior(
-                self,
-                def_id,
-                generator_def_id,
-                body_id,
-                interior,
-                kind,
-            );
-            self.select_obligations_where_possible(|_| {});
-        }
-    }
-
     /// Unify the inference variables corresponding to generator witnesses, and save all the
     /// predicates that were stalled on those inference variables.
     ///
@@ -540,7 +518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// We must not attempt to select obligations after this method has run, or risk query cycle
     /// ICE.
     #[instrument(level = "debug", skip(self))]
-    fn save_generator_interior_predicates(&self, def_id: DefId) {
+    pub(in super::super) fn resolve_generator_interiors(&self, def_id: DefId) {
         // Try selecting all obligations that are not blocked on inference variables.
         // Once we start unifying generator witnesses, trying to select obligations on them will
         // trigger query cycle ICEs, as doing so requires MIR.
@@ -557,7 +535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx,
                 self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
             );
-            let witness = Ty::new_generator_witness_mir(self.tcx, expr_def_id.to_def_id(), args);
+            let witness = Ty::new_generator_witness(self.tcx, expr_def_id.to_def_id(), args);
 
             // Unify `interior` with `witness` and collect all the resulting obligations.
             let span = self.tcx.hir().body(body_id).value.span;
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
deleted file mode 100644
index cfedcee9956..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
+++ /dev/null
@@ -1,601 +0,0 @@
-use super::{
-    for_each_consumable, record_consumed_borrow::ConsumedAndBorrowedPlaces, DropRangesBuilder,
-    NodeInfo, PostOrderId, TrackedValue, TrackedValueIndex,
-};
-use hir::{
-    intravisit::{self, Visitor},
-    Body, Expr, ExprKind, Guard, HirId, LoopIdError,
-};
-use rustc_data_structures::unord::{UnordMap, UnordSet};
-use rustc_hir as hir;
-use rustc_index::IndexVec;
-use rustc_infer::infer::InferCtxt;
-use rustc_middle::{
-    hir::map::Map,
-    ty::{ParamEnv, TyCtxt, TypeVisitableExt, TypeckResults},
-};
-use std::mem::swap;
-
-/// Traverses the body to find the control flow graph and locations for the
-/// relevant places are dropped or reinitialized.
-///
-/// The resulting structure still needs to be iterated to a fixed point, which
-/// can be done with propagate_to_fixpoint in cfg_propagate.
-pub(super) fn build_control_flow_graph<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    typeck_results: &TypeckResults<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    consumed_borrowed_places: ConsumedAndBorrowedPlaces,
-    body: &'tcx Body<'tcx>,
-    num_exprs: usize,
-) -> (DropRangesBuilder, UnordSet<HirId>) {
-    let mut drop_range_visitor = DropRangeVisitor::new(
-        infcx,
-        typeck_results,
-        param_env,
-        consumed_borrowed_places,
-        num_exprs,
-    );
-    intravisit::walk_body(&mut drop_range_visitor, body);
-
-    drop_range_visitor.drop_ranges.process_deferred_edges();
-    if let Some(filename) = &infcx.tcx.sess.opts.unstable_opts.dump_drop_tracking_cfg {
-        super::cfg_visualize::write_graph_to_file(
-            &drop_range_visitor.drop_ranges,
-            filename,
-            infcx.tcx,
-        );
-    }
-
-    (drop_range_visitor.drop_ranges, drop_range_visitor.places.borrowed_temporaries)
-}
-
-/// This struct is used to gather the information for `DropRanges` to determine the regions of the
-/// HIR tree for which a value is dropped.
-///
-/// We are interested in points where a variables is dropped or initialized, and the control flow
-/// of the code. We identify locations in code by their post-order traversal index, so it is
-/// important for this traversal to match that in `RegionResolutionVisitor` and `InteriorVisitor`.
-///
-/// We make several simplifying assumptions, with the goal of being more conservative than
-/// necessary rather than less conservative (since being less conservative is unsound, but more
-/// conservative is still safe). These assumptions are:
-///
-/// 1. Moving a variable `a` counts as a move of the whole variable.
-/// 2. Moving a partial path like `a.b.c` is ignored.
-/// 3. Reinitializing through a field (e.g. `a.b.c = 5`) counts as a reinitialization of all of
-///    `a`.
-///
-/// Some examples:
-///
-/// Rule 1:
-/// ```rust
-/// let mut a = (vec![0], vec![0]);
-/// drop(a);
-/// // `a` is not considered initialized.
-/// ```
-///
-/// Rule 2:
-/// ```rust
-/// let mut a = (vec![0], vec![0]);
-/// drop(a.0);
-/// drop(a.1);
-/// // `a` is still considered initialized.
-/// ```
-///
-/// Rule 3:
-/// ```compile_fail,E0382
-/// let mut a = (vec![0], vec![0]);
-/// drop(a);
-/// a.1 = vec![1];
-/// // all of `a` is considered initialized
-/// ```
-
-struct DropRangeVisitor<'a, 'tcx> {
-    typeck_results: &'a TypeckResults<'tcx>,
-    infcx: &'a InferCtxt<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    places: ConsumedAndBorrowedPlaces,
-    drop_ranges: DropRangesBuilder,
-    expr_index: PostOrderId,
-    label_stack: Vec<(Option<rustc_ast::Label>, PostOrderId)>,
-}
-
-impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
-    fn new(
-        infcx: &'a InferCtxt<'tcx>,
-        typeck_results: &'a TypeckResults<'tcx>,
-        param_env: ParamEnv<'tcx>,
-        places: ConsumedAndBorrowedPlaces,
-        num_exprs: usize,
-    ) -> Self {
-        debug!("consumed_places: {:?}", places.consumed);
-        let drop_ranges = DropRangesBuilder::new(
-            places.consumed.iter().flat_map(|(_, places)| places.iter().cloned()),
-            infcx.tcx.hir(),
-            num_exprs,
-        );
-        Self {
-            infcx,
-            typeck_results,
-            param_env,
-            places,
-            drop_ranges,
-            expr_index: PostOrderId::from_u32(0),
-            label_stack: vec![],
-        }
-    }
-
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.infcx.tcx
-    }
-
-    fn record_drop(&mut self, value: TrackedValue) {
-        if self.places.borrowed.contains(&value) {
-            debug!("not marking {:?} as dropped because it is borrowed at some point", value);
-        } else {
-            debug!("marking {:?} as dropped at {:?}", value, self.expr_index);
-            let count = self.expr_index;
-            self.drop_ranges.drop_at(value, count);
-        }
-    }
-
-    /// ExprUseVisitor's consume callback doesn't go deep enough for our purposes in all
-    /// expressions. This method consumes a little deeper into the expression when needed.
-    fn consume_expr(&mut self, expr: &hir::Expr<'_>) {
-        debug!("consuming expr {:?}, count={:?}", expr.kind, self.expr_index);
-        let places = self
-            .places
-            .consumed
-            .get(&expr.hir_id)
-            .map_or(vec![], |places| places.iter().cloned().collect());
-        for place in places {
-            trace!(?place, "consuming place");
-            for_each_consumable(self.tcx().hir(), place, |value| self.record_drop(value));
-        }
-    }
-
-    /// Marks an expression as being reinitialized.
-    ///
-    /// Note that we always approximated on the side of things being more
-    /// initialized than they actually are, as opposed to less. In cases such
-    /// as `x.y = ...`, we would consider all of `x` as being initialized
-    /// instead of just the `y` field.
-    ///
-    /// This is because it is always safe to consider something initialized
-    /// even when it is not, but the other way around will cause problems.
-    ///
-    /// In the future, we will hopefully tighten up these rules to be more
-    /// precise.
-    fn reinit_expr(&mut self, expr: &hir::Expr<'_>) {
-        // Walk the expression to find the base. For example, in an expression
-        // like `*a[i].x`, we want to find the `a` and mark that as
-        // reinitialized.
-        match expr.kind {
-            ExprKind::Path(hir::QPath::Resolved(
-                _,
-                hir::Path { res: hir::def::Res::Local(hir_id), .. },
-            )) => {
-                // This is the base case, where we have found an actual named variable.
-
-                let location = self.expr_index;
-                debug!("reinitializing {:?} at {:?}", hir_id, location);
-                self.drop_ranges.reinit_at(TrackedValue::Variable(*hir_id), location);
-            }
-
-            ExprKind::Field(base, _) => self.reinit_expr(base),
-
-            // Most expressions do not refer to something where we need to track
-            // reinitializations.
-            //
-            // Some of these may be interesting in the future
-            ExprKind::Path(..)
-            | ExprKind::ConstBlock(..)
-            | ExprKind::Array(..)
-            | ExprKind::Call(..)
-            | ExprKind::MethodCall(..)
-            | ExprKind::Tup(..)
-            | ExprKind::Binary(..)
-            | ExprKind::Unary(..)
-            | ExprKind::Lit(..)
-            | ExprKind::Cast(..)
-            | ExprKind::Type(..)
-            | ExprKind::DropTemps(..)
-            | ExprKind::Let(..)
-            | ExprKind::If(..)
-            | ExprKind::Loop(..)
-            | ExprKind::Match(..)
-            | ExprKind::Closure { .. }
-            | ExprKind::Block(..)
-            | ExprKind::Assign(..)
-            | ExprKind::AssignOp(..)
-            | ExprKind::Index(..)
-            | ExprKind::AddrOf(..)
-            | ExprKind::Break(..)
-            | ExprKind::Continue(..)
-            | ExprKind::Ret(..)
-            | ExprKind::Become(..)
-            | ExprKind::InlineAsm(..)
-            | ExprKind::OffsetOf(..)
-            | ExprKind::Struct(..)
-            | ExprKind::Repeat(..)
-            | ExprKind::Yield(..)
-            | ExprKind::Err(_) => (),
-        }
-    }
-
-    /// For an expression with an uninhabited return type (e.g. a function that returns !),
-    /// this adds a self edge to the CFG to model the fact that the function does not
-    /// return.
-    fn handle_uninhabited_return(&mut self, expr: &Expr<'tcx>) {
-        let ty = self.typeck_results.expr_ty(expr);
-        let ty = self.infcx.resolve_vars_if_possible(ty);
-        if ty.has_non_region_infer() {
-            self.tcx()
-                .sess
-                .delay_span_bug(expr.span, format!("could not resolve infer vars in `{ty}`"));
-            return;
-        }
-        let ty = self.tcx().erase_regions(ty);
-        let m = self.tcx().parent_module(expr.hir_id).to_def_id();
-        if !ty.is_inhabited_from(self.tcx(), m, self.param_env) {
-            // This function will not return. We model this fact as an infinite loop.
-            self.drop_ranges.add_control_edge(self.expr_index + 1, self.expr_index + 1);
-        }
-    }
-
-    /// Map a Destination to an equivalent expression node
-    ///
-    /// The destination field of a Break or Continue expression can target either an
-    /// expression or a block. The drop range analysis, however, only deals in
-    /// expression nodes, so blocks that might be the destination of a Break or Continue
-    /// will not have a PostOrderId.
-    ///
-    /// If the destination is an expression, this function will simply return that expression's
-    /// hir_id. If the destination is a block, this function will return the hir_id of last
-    /// expression in the block.
-    fn find_target_expression_from_destination(
-        &self,
-        destination: hir::Destination,
-    ) -> Result<HirId, LoopIdError> {
-        destination.target_id.map(|target| {
-            let node = self.tcx().hir().get(target);
-            match node {
-                hir::Node::Expr(_) => target,
-                hir::Node::Block(b) => find_last_block_expression(b),
-                hir::Node::Param(..)
-                | hir::Node::Item(..)
-                | hir::Node::ForeignItem(..)
-                | hir::Node::TraitItem(..)
-                | hir::Node::ImplItem(..)
-                | hir::Node::Variant(..)
-                | hir::Node::Field(..)
-                | hir::Node::AnonConst(..)
-                | hir::Node::ConstBlock(..)
-                | hir::Node::Stmt(..)
-                | hir::Node::PathSegment(..)
-                | hir::Node::Ty(..)
-                | hir::Node::TypeBinding(..)
-                | hir::Node::TraitRef(..)
-                | hir::Node::Pat(..)
-                | hir::Node::PatField(..)
-                | hir::Node::ExprField(..)
-                | hir::Node::Arm(..)
-                | hir::Node::Local(..)
-                | hir::Node::Ctor(..)
-                | hir::Node::Lifetime(..)
-                | hir::Node::GenericParam(..)
-                | hir::Node::Crate(..)
-                | hir::Node::Infer(..) => bug!("Unsupported branch target: {:?}", node),
-            }
-        })
-    }
-}
-
-fn find_last_block_expression(block: &hir::Block<'_>) -> HirId {
-    block.expr.map_or_else(
-        // If there is no tail expression, there will be at least one statement in the
-        // block because the block contains a break or continue statement.
-        || block.stmts.last().unwrap().hir_id,
-        |expr| expr.hir_id,
-    )
-}
-
-impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
-    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
-        let mut reinit = None;
-        match expr.kind {
-            ExprKind::Assign(lhs, rhs, _) => {
-                self.visit_expr(rhs);
-                self.visit_expr(lhs);
-
-                reinit = Some(lhs);
-            }
-
-            ExprKind::If(test, if_true, if_false) => {
-                self.visit_expr(test);
-
-                let fork = self.expr_index;
-
-                self.drop_ranges.add_control_edge(fork, self.expr_index + 1);
-                self.visit_expr(if_true);
-                let true_end = self.expr_index;
-
-                self.drop_ranges.add_control_edge(fork, self.expr_index + 1);
-                if let Some(if_false) = if_false {
-                    self.visit_expr(if_false);
-                }
-
-                self.drop_ranges.add_control_edge(true_end, self.expr_index + 1);
-            }
-            ExprKind::Match(scrutinee, arms, ..) => {
-                // We walk through the match expression almost like a chain of if expressions.
-                // Here's a diagram to follow along with:
-                //
-                //           ┌─┐
-                //     match │A│ {
-                //       ┌───┴─┘
-                //       │
-                //      ┌▼┌───►┌─┐   ┌─┐
-                //      │B│ if │C│ =>│D│,
-                //      └─┘    ├─┴──►└─┴──────┐
-                //          ┌──┘              │
-                //       ┌──┘                 │
-                //       │                    │
-                //      ┌▼┌───►┌─┐   ┌─┐      │
-                //      │E│ if │F│ =>│G│,     │
-                //      └─┘    ├─┴──►└─┴┐     │
-                //             │        │     │
-                //     }       ▼        ▼     │
-                //     ┌─┐◄───────────────────┘
-                //     │H│
-                //     └─┘
-                //
-                // The order we want is that the scrutinee (A) flows into the first pattern (B),
-                // which flows into the guard (C). Then the guard either flows into the arm body
-                // (D) or into the start of the next arm (E). Finally, the body flows to the end
-                // of the match block (H).
-                //
-                // The subsequent arms follow the same ordering. First we go to the pattern, then
-                // the guard (if present, otherwise it flows straight into the body), then into
-                // the body and then to the end of the match expression.
-                //
-                // The comments below show which edge is being added.
-                self.visit_expr(scrutinee);
-
-                let (guard_exit, arm_end_ids) = arms.iter().fold(
-                    (self.expr_index, vec![]),
-                    |(incoming_edge, mut arm_end_ids), hir::Arm { pat, body, guard, .. }| {
-                        // A -> B, or C -> E
-                        self.drop_ranges.add_control_edge(incoming_edge, self.expr_index + 1);
-                        self.visit_pat(pat);
-                        // B -> C and E -> F are added implicitly due to the traversal order.
-                        match guard {
-                            Some(Guard::If(expr)) => self.visit_expr(expr),
-                            Some(Guard::IfLet(let_expr)) => {
-                                self.visit_let_expr(let_expr);
-                            }
-                            None => (),
-                        }
-                        // Likewise, C -> D and F -> G are added implicitly.
-
-                        // Save C, F, so we can add the other outgoing edge.
-                        let to_next_arm = self.expr_index;
-
-                        // The default edge does not get added since we also have an explicit edge,
-                        // so we also need to add an edge to the next node as well.
-                        //
-                        // This adds C -> D, F -> G
-                        self.drop_ranges.add_control_edge(self.expr_index, self.expr_index + 1);
-                        self.visit_expr(body);
-
-                        // Save the end of the body so we can add the exit edge once we know where
-                        // the exit is.
-                        arm_end_ids.push(self.expr_index);
-
-                        // Pass C to the next iteration, as well as vec![D]
-                        //
-                        // On the last round through, we pass F and vec![D, G] so that we can
-                        // add all the exit edges.
-                        (to_next_arm, arm_end_ids)
-                    },
-                );
-                // F -> H
-                self.drop_ranges.add_control_edge(guard_exit, self.expr_index + 1);
-
-                arm_end_ids.into_iter().for_each(|arm_end| {
-                    // D -> H, G -> H
-                    self.drop_ranges.add_control_edge(arm_end, self.expr_index + 1)
-                });
-            }
-
-            ExprKind::Loop(body, label, ..) => {
-                let loop_begin = self.expr_index + 1;
-                self.label_stack.push((label, loop_begin));
-                if body.stmts.is_empty() && body.expr.is_none() {
-                    // For empty loops we won't have updated self.expr_index after visiting the
-                    // body, meaning we'd get an edge from expr_index to expr_index + 1, but
-                    // instead we want an edge from expr_index + 1 to expr_index + 1.
-                    self.drop_ranges.add_control_edge(loop_begin, loop_begin);
-                } else {
-                    self.visit_block(body);
-                    self.drop_ranges.add_control_edge(self.expr_index, loop_begin);
-                }
-                self.label_stack.pop();
-            }
-            // Find the loop entry by searching through the label stack for either the last entry
-            // (if label is none), or the first entry where the label matches this one. The Loop
-            // case maintains this stack mapping labels to the PostOrderId for the loop entry.
-            ExprKind::Continue(hir::Destination { label, .. }, ..) => self
-                .label_stack
-                .iter()
-                .rev()
-                .find(|(loop_label, _)| label.is_none() || *loop_label == label)
-                .map_or((), |(_, target)| {
-                    self.drop_ranges.add_control_edge(self.expr_index, *target)
-                }),
-
-            ExprKind::Break(destination, value) => {
-                // destination either points to an expression or to a block. We use
-                // find_target_expression_from_destination to use the last expression of the block
-                // if destination points to a block.
-                //
-                // We add an edge to the hir_id of the expression/block we are breaking out of, and
-                // then in process_deferred_edges we will map this hir_id to its PostOrderId, which
-                // will refer to the end of the block due to the post order traversal.
-                if let Ok(target) = self.find_target_expression_from_destination(destination) {
-                    self.drop_ranges.add_control_edge_hir_id(self.expr_index, target)
-                }
-
-                if let Some(value) = value {
-                    self.visit_expr(value);
-                }
-            }
-
-            ExprKind::Become(_call) => bug!("encountered a tail-call inside a generator"),
-
-            ExprKind::Call(f, args) => {
-                self.visit_expr(f);
-                for arg in args {
-                    self.visit_expr(arg);
-                }
-
-                self.handle_uninhabited_return(expr);
-            }
-            ExprKind::MethodCall(_, receiver, exprs, _) => {
-                self.visit_expr(receiver);
-                for expr in exprs {
-                    self.visit_expr(expr);
-                }
-
-                self.handle_uninhabited_return(expr);
-            }
-
-            ExprKind::AddrOf(..)
-            | ExprKind::Array(..)
-            // FIXME(eholk): We probably need special handling for AssignOps. The ScopeTree builder
-            // in region.rs runs both lhs then rhs and rhs then lhs and then sets all yields to be
-            // the latest they show up in either traversal. With the older scope-based
-            // approximation, this was fine, but it's probably not right now. What we probably want
-            // to do instead is still run both orders, but consider anything that showed up as a
-            // yield in either order.
-            | ExprKind::AssignOp(..)
-            | ExprKind::Binary(..)
-            | ExprKind::Block(..)
-            | ExprKind::Cast(..)
-            | ExprKind::Closure { .. }
-            | ExprKind::ConstBlock(..)
-            | ExprKind::DropTemps(..)
-            | ExprKind::Err(_)
-            | ExprKind::Field(..)
-            | ExprKind::Index(..)
-            | ExprKind::InlineAsm(..)
-            | ExprKind::OffsetOf(..)
-            | ExprKind::Let(..)
-            | ExprKind::Lit(..)
-            | ExprKind::Path(..)
-            | ExprKind::Repeat(..)
-            | ExprKind::Ret(..)
-            | ExprKind::Struct(..)
-            | ExprKind::Tup(..)
-            | ExprKind::Type(..)
-            | ExprKind::Unary(..)
-            | ExprKind::Yield(..) => intravisit::walk_expr(self, expr),
-        }
-
-        self.expr_index = self.expr_index + 1;
-        self.drop_ranges.add_node_mapping(expr.hir_id, self.expr_index);
-        self.consume_expr(expr);
-        if let Some(expr) = reinit {
-            self.reinit_expr(expr);
-        }
-    }
-
-    fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
-        intravisit::walk_pat(self, pat);
-
-        // Increment expr_count here to match what InteriorVisitor expects.
-        self.expr_index = self.expr_index + 1;
-
-        // Save a node mapping to get better CFG visualization
-        self.drop_ranges.add_node_mapping(pat.hir_id, self.expr_index);
-    }
-}
-
-impl DropRangesBuilder {
-    fn new(
-        tracked_values: impl Iterator<Item = TrackedValue>,
-        hir: Map<'_>,
-        num_exprs: usize,
-    ) -> Self {
-        let mut tracked_value_map = UnordMap::<_, TrackedValueIndex>::default();
-        let mut next = <_>::from(0u32);
-        for value in tracked_values {
-            for_each_consumable(hir, value, |value| {
-                if let std::collections::hash_map::Entry::Vacant(e) = tracked_value_map.entry(value)
-                {
-                    e.insert(next);
-                    next = next + 1;
-                }
-            });
-        }
-        debug!("hir_id_map: {:#?}", tracked_value_map);
-        let num_values = tracked_value_map.len();
-        Self {
-            tracked_value_map,
-            nodes: IndexVec::from_fn_n(|_| NodeInfo::new(num_values), num_exprs + 1),
-            deferred_edges: <_>::default(),
-            post_order_map: <_>::default(),
-        }
-    }
-
-    fn tracked_value_index(&self, tracked_value: TrackedValue) -> TrackedValueIndex {
-        *self.tracked_value_map.get(&tracked_value).unwrap()
-    }
-
-    /// Adds an entry in the mapping from HirIds to PostOrderIds
-    ///
-    /// Needed so that `add_control_edge_hir_id` can work.
-    fn add_node_mapping(&mut self, node_hir_id: HirId, post_order_id: PostOrderId) {
-        self.post_order_map.insert(node_hir_id, post_order_id);
-    }
-
-    /// Like add_control_edge, but uses a hir_id as the target.
-    ///
-    /// This can be used for branches where we do not know the PostOrderId of the target yet,
-    /// such as when handling `break` or `continue`.
-    fn add_control_edge_hir_id(&mut self, from: PostOrderId, to: HirId) {
-        self.deferred_edges.push((from, to));
-    }
-
-    fn drop_at(&mut self, value: TrackedValue, location: PostOrderId) {
-        let value = self.tracked_value_index(value);
-        self.node_mut(location).drops.push(value);
-    }
-
-    fn reinit_at(&mut self, value: TrackedValue, location: PostOrderId) {
-        let value = match self.tracked_value_map.get(&value) {
-            Some(value) => *value,
-            // If there's no value, this is never consumed and therefore is never dropped. We can
-            // ignore this.
-            None => return,
-        };
-        self.node_mut(location).reinits.push(value);
-    }
-
-    /// Looks up PostOrderId for any control edges added by HirId and adds a proper edge for them.
-    ///
-    /// Should be called after visiting the HIR but before solving the control flow, otherwise some
-    /// edges will be missed.
-    fn process_deferred_edges(&mut self) {
-        trace!("processing deferred edges. post_order_map={:#?}", self.post_order_map);
-        let mut edges = vec![];
-        swap(&mut edges, &mut self.deferred_edges);
-        edges.into_iter().for_each(|(from, to)| {
-            trace!("Adding deferred edge from {:?} to {:?}", from, to);
-            let to = *self.post_order_map.get(&to).expect("Expression ID not found");
-            trace!("target edge PostOrderId={:?}", to);
-            self.add_control_edge(from, to)
-        });
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs
deleted file mode 100644
index 633b478895b..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-use super::{DropRangesBuilder, PostOrderId};
-use rustc_index::{bit_set::BitSet, IndexVec};
-use std::collections::BTreeMap;
-
-impl DropRangesBuilder {
-    pub fn propagate_to_fixpoint(&mut self) {
-        trace!("before fixpoint: {:#?}", self);
-        let preds = self.compute_predecessors();
-
-        trace!("predecessors: {:#?}", preds.iter_enumerated().collect::<BTreeMap<_, _>>());
-
-        let mut new_state = BitSet::new_empty(self.num_values());
-        let mut changed_nodes = BitSet::new_empty(self.nodes.len());
-        let mut unchanged_mask = BitSet::new_filled(self.nodes.len());
-        changed_nodes.insert(0u32.into());
-
-        let mut propagate = || {
-            let mut changed = false;
-            unchanged_mask.insert_all();
-            for id in self.nodes.indices() {
-                trace!("processing {:?}, changed_nodes: {:?}", id, changed_nodes);
-                // Check if any predecessor has changed, and if not then short-circuit.
-                //
-                // We handle the start node specially, since it doesn't have any predecessors,
-                // but we need to start somewhere.
-                if match id.index() {
-                    0 => !changed_nodes.contains(id),
-                    _ => !preds[id].iter().any(|pred| changed_nodes.contains(*pred)),
-                } {
-                    trace!("short-circuiting because none of {:?} have changed", preds[id]);
-                    unchanged_mask.remove(id);
-                    continue;
-                }
-
-                if id.index() == 0 {
-                    new_state.clear();
-                } else {
-                    // If we are not the start node and we have no predecessors, treat
-                    // everything as dropped because there's no way to get here anyway.
-                    new_state.insert_all();
-                };
-
-                for pred in &preds[id] {
-                    new_state.intersect(&self.nodes[*pred].drop_state);
-                }
-
-                for drop in &self.nodes[id].drops {
-                    new_state.insert(*drop);
-                }
-
-                for reinit in &self.nodes[id].reinits {
-                    new_state.remove(*reinit);
-                }
-
-                if self.nodes[id].drop_state.intersect(&new_state) {
-                    changed_nodes.insert(id);
-                    changed = true;
-                } else {
-                    unchanged_mask.remove(id);
-                }
-            }
-
-            changed_nodes.intersect(&unchanged_mask);
-            changed
-        };
-
-        while propagate() {
-            trace!("drop_state changed, re-running propagation");
-        }
-
-        trace!("after fixpoint: {:#?}", self);
-    }
-
-    fn compute_predecessors(&self) -> IndexVec<PostOrderId, Vec<PostOrderId>> {
-        let mut preds = IndexVec::from_fn_n(|_| vec![], self.nodes.len());
-        for (id, node) in self.nodes.iter_enumerated() {
-            // If the node has no explicit successors, we assume that control
-            // will from this node into the next one.
-            //
-            // If there are successors listed, then we assume that all
-            // possible successors are given and we do not include the default.
-            if node.successors.len() == 0 && id.index() != self.nodes.len() - 1 {
-                preds[id + 1].push(id);
-            } else {
-                for succ in &node.successors {
-                    preds[*succ].push(id);
-                }
-            }
-        }
-        preds
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs
deleted file mode 100644
index e8d31be79d9..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-//! Implementation of GraphWalk for DropRanges so we can visualize the control
-//! flow graph when needed for debugging.
-
-use rustc_graphviz as dot;
-use rustc_hir::{Expr, ExprKind, Node};
-use rustc_middle::ty::TyCtxt;
-
-use super::{DropRangesBuilder, PostOrderId};
-
-/// Writes the CFG for DropRangesBuilder to a .dot file for visualization.
-///
-/// It is not normally called, but is kept around to easily add debugging
-/// code when needed.
-pub(super) fn write_graph_to_file(
-    drop_ranges: &DropRangesBuilder,
-    filename: &str,
-    tcx: TyCtxt<'_>,
-) {
-    dot::render(
-        &DropRangesGraph { drop_ranges, tcx },
-        &mut std::fs::File::create(filename).unwrap(),
-    )
-    .unwrap();
-}
-
-struct DropRangesGraph<'a, 'tcx> {
-    drop_ranges: &'a DropRangesBuilder,
-    tcx: TyCtxt<'tcx>,
-}
-
-impl<'a> dot::GraphWalk<'a> for DropRangesGraph<'_, '_> {
-    type Node = PostOrderId;
-
-    type Edge = (PostOrderId, PostOrderId);
-
-    fn nodes(&'a self) -> dot::Nodes<'a, Self::Node> {
-        self.drop_ranges.nodes.iter_enumerated().map(|(i, _)| i).collect()
-    }
-
-    fn edges(&'a self) -> dot::Edges<'a, Self::Edge> {
-        self.drop_ranges
-            .nodes
-            .iter_enumerated()
-            .flat_map(|(i, node)| {
-                if node.successors.len() == 0 {
-                    vec![(i, i + 1)]
-                } else {
-                    node.successors.iter().map(move |&s| (i, s)).collect()
-                }
-            })
-            .collect()
-    }
-
-    fn source(&'a self, edge: &Self::Edge) -> Self::Node {
-        edge.0
-    }
-
-    fn target(&'a self, edge: &Self::Edge) -> Self::Node {
-        edge.1
-    }
-}
-
-impl<'a> dot::Labeller<'a> for DropRangesGraph<'_, '_> {
-    type Node = PostOrderId;
-
-    type Edge = (PostOrderId, PostOrderId);
-
-    fn graph_id(&'a self) -> dot::Id<'a> {
-        dot::Id::new("drop_ranges").unwrap()
-    }
-
-    fn node_id(&'a self, n: &Self::Node) -> dot::Id<'a> {
-        dot::Id::new(format!("id{}", n.index())).unwrap()
-    }
-
-    fn node_label(&'a self, n: &Self::Node) -> dot::LabelText<'a> {
-        dot::LabelText::LabelStr(
-            format!(
-                "{n:?}: {}",
-                self.drop_ranges
-                    .post_order_map
-                    .iter()
-                    .find(|(_hir_id, &post_order_id)| post_order_id == *n)
-                    .map_or("<unknown>".into(), |(hir_id, _)| format!(
-                        "{}{}",
-                        self.tcx.hir().node_to_string(*hir_id),
-                        match self.tcx.hir().find(*hir_id) {
-                            Some(Node::Expr(Expr { kind: ExprKind::Yield(..), .. })) => " (yield)",
-                            _ => "",
-                        }
-                    ))
-            )
-            .into(),
-        )
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs
deleted file mode 100644
index e563bd40b65..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs
+++ /dev/null
@@ -1,306 +0,0 @@
-//! Drop range analysis finds the portions of the tree where a value is guaranteed to be dropped
-//! (i.e. moved, uninitialized, etc.). This is used to exclude the types of those values from the
-//! generator type. See `InteriorVisitor::record` for where the results of this analysis are used.
-//!
-//! There are three phases to this analysis:
-//! 1. Use `ExprUseVisitor` to identify the interesting values that are consumed and borrowed.
-//! 2. Use `DropRangeVisitor` to find where the interesting values are dropped or reinitialized,
-//!    and also build a control flow graph.
-//! 3. Use `DropRanges::propagate_to_fixpoint` to flow the dropped/reinitialized information through
-//!    the CFG and find the exact points where we know a value is definitely dropped.
-//!
-//! The end result is a data structure that maps the post-order index of each node in the HIR tree
-//! to a set of values that are known to be dropped at that location.
-
-use self::cfg_build::build_control_flow_graph;
-use self::record_consumed_borrow::find_consumed_and_borrowed;
-use crate::FnCtxt;
-use hir::def_id::DefId;
-use hir::{Body, HirId, HirIdMap, Node};
-use rustc_data_structures::unord::{UnordMap, UnordSet};
-use rustc_hir as hir;
-use rustc_index::bit_set::BitSet;
-use rustc_index::IndexVec;
-use rustc_middle::hir::map::Map;
-use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId};
-use rustc_middle::ty;
-use std::collections::BTreeMap;
-use std::fmt::Debug;
-
-mod cfg_build;
-mod cfg_propagate;
-mod cfg_visualize;
-mod record_consumed_borrow;
-
-pub fn compute_drop_ranges<'a, 'tcx>(
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    def_id: DefId,
-    body: &'tcx Body<'tcx>,
-) -> DropRanges {
-    if fcx.sess().opts.unstable_opts.drop_tracking {
-        let consumed_borrowed_places = find_consumed_and_borrowed(fcx, def_id, body);
-
-        let typeck_results = &fcx.typeck_results.borrow();
-        let num_exprs = fcx.tcx.region_scope_tree(def_id).body_expr_count(body.id()).unwrap_or(0);
-        let (mut drop_ranges, borrowed_temporaries) = build_control_flow_graph(
-            &fcx,
-            typeck_results,
-            fcx.param_env,
-            consumed_borrowed_places,
-            body,
-            num_exprs,
-        );
-
-        drop_ranges.propagate_to_fixpoint();
-
-        debug!("borrowed_temporaries = {borrowed_temporaries:?}");
-        DropRanges {
-            tracked_value_map: drop_ranges.tracked_value_map,
-            nodes: drop_ranges.nodes,
-            borrowed_temporaries: Some(borrowed_temporaries),
-        }
-    } else {
-        // If drop range tracking is not enabled, skip all the analysis and produce an
-        // empty set of DropRanges.
-        DropRanges {
-            tracked_value_map: UnordMap::default(),
-            nodes: IndexVec::new(),
-            borrowed_temporaries: None,
-        }
-    }
-}
-
-/// Applies `f` to consumable node in the HIR subtree pointed to by `place`.
-///
-/// This includes the place itself, and if the place is a reference to a local
-/// variable then `f` is also called on the HIR node for that variable as well.
-///
-/// For example, if `place` points to `foo()`, then `f` is called once for the
-/// result of `foo`. On the other hand, if `place` points to `x` then `f` will
-/// be called both on the `ExprKind::Path` node that represents the expression
-/// as well as the HirId of the local `x` itself.
-fn for_each_consumable(hir: Map<'_>, place: TrackedValue, mut f: impl FnMut(TrackedValue)) {
-    f(place);
-    let node = hir.find(place.hir_id());
-    if let Some(Node::Expr(expr)) = node {
-        match expr.kind {
-            hir::ExprKind::Path(hir::QPath::Resolved(
-                _,
-                hir::Path { res: hir::def::Res::Local(hir_id), .. },
-            )) => {
-                f(TrackedValue::Variable(*hir_id));
-            }
-            _ => (),
-        }
-    }
-}
-
-rustc_index::newtype_index! {
-    #[debug_format = "id({})"]
-    pub struct PostOrderId {}
-}
-
-rustc_index::newtype_index! {
-    #[debug_format = "hidx({})"]
-    pub struct TrackedValueIndex {}
-}
-
-/// Identifies a value whose drop state we need to track.
-#[derive(PartialEq, Eq, Hash, Clone, Copy)]
-enum TrackedValue {
-    /// Represents a named variable, such as a let binding, parameter, or upvar.
-    ///
-    /// The HirId points to the variable's definition site.
-    Variable(HirId),
-    /// A value produced as a result of an expression.
-    ///
-    /// The HirId points to the expression that returns this value.
-    Temporary(HirId),
-}
-
-impl Debug for TrackedValue {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        ty::tls::with_opt(|opt_tcx| {
-            if let Some(tcx) = opt_tcx {
-                write!(f, "{}", tcx.hir().node_to_string(self.hir_id()))
-            } else {
-                match self {
-                    Self::Variable(hir_id) => write!(f, "Variable({hir_id:?})"),
-                    Self::Temporary(hir_id) => write!(f, "Temporary({hir_id:?})"),
-                }
-            }
-        })
-    }
-}
-
-impl TrackedValue {
-    fn hir_id(&self) -> HirId {
-        match self {
-            TrackedValue::Variable(hir_id) | TrackedValue::Temporary(hir_id) => *hir_id,
-        }
-    }
-
-    fn from_place_with_projections_allowed(place_with_id: &PlaceWithHirId<'_>) -> Self {
-        match place_with_id.place.base {
-            PlaceBase::Rvalue | PlaceBase::StaticItem => {
-                TrackedValue::Temporary(place_with_id.hir_id)
-            }
-            PlaceBase::Local(hir_id)
-            | PlaceBase::Upvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id }, .. }) => {
-                TrackedValue::Variable(hir_id)
-            }
-        }
-    }
-}
-
-/// Represents a reason why we might not be able to convert a HirId or Place
-/// into a tracked value.
-#[derive(Debug)]
-enum TrackedValueConversionError {
-    /// Place projects are not currently supported.
-    ///
-    /// The reasoning around these is kind of subtle, so we choose to be more
-    /// conservative around these for now. There is no reason in theory we
-    /// cannot support these, we just have not implemented it yet.
-    PlaceProjectionsNotSupported,
-}
-
-impl TryFrom<&PlaceWithHirId<'_>> for TrackedValue {
-    type Error = TrackedValueConversionError;
-
-    fn try_from(place_with_id: &PlaceWithHirId<'_>) -> Result<Self, Self::Error> {
-        if !place_with_id.place.projections.is_empty() {
-            debug!(
-                "TrackedValue from PlaceWithHirId: {:?} has projections, which are not supported.",
-                place_with_id
-            );
-            return Err(TrackedValueConversionError::PlaceProjectionsNotSupported);
-        }
-
-        Ok(TrackedValue::from_place_with_projections_allowed(place_with_id))
-    }
-}
-
-pub struct DropRanges {
-    tracked_value_map: UnordMap<TrackedValue, TrackedValueIndex>,
-    nodes: IndexVec<PostOrderId, NodeInfo>,
-    borrowed_temporaries: Option<UnordSet<HirId>>,
-}
-
-impl DropRanges {
-    pub fn is_dropped_at(&self, hir_id: HirId, location: usize) -> bool {
-        self.tracked_value_map
-            .get(&TrackedValue::Temporary(hir_id))
-            .or(self.tracked_value_map.get(&TrackedValue::Variable(hir_id)))
-            .cloned()
-            .is_some_and(|tracked_value_id| {
-                self.expect_node(location.into()).drop_state.contains(tracked_value_id)
-            })
-    }
-
-    pub fn is_borrowed_temporary(&self, expr: &hir::Expr<'_>) -> bool {
-        if let Some(b) = &self.borrowed_temporaries { b.contains(&expr.hir_id) } else { true }
-    }
-
-    /// Returns a reference to the NodeInfo for a node, panicking if it does not exist
-    fn expect_node(&self, id: PostOrderId) -> &NodeInfo {
-        &self.nodes[id]
-    }
-}
-
-/// Tracks information needed to compute drop ranges.
-struct DropRangesBuilder {
-    /// The core of DropRangesBuilder is a set of nodes, which each represent
-    /// one expression. We primarily refer to them by their index in a
-    /// post-order traversal of the HIR tree,  since this is what
-    /// generator_interior uses to talk about yield positions.
-    ///
-    /// This IndexVec keeps the relevant details for each node. See the
-    /// NodeInfo struct for more details, but this information includes things
-    /// such as the set of control-flow successors, which variables are dropped
-    /// or reinitialized, and whether each variable has been inferred to be
-    /// known-dropped or potentially reinitialized at each point.
-    nodes: IndexVec<PostOrderId, NodeInfo>,
-    /// We refer to values whose drop state we are tracking by the HirId of
-    /// where they are defined. Within a NodeInfo, however, we store the
-    /// drop-state in a bit vector indexed by a HirIdIndex
-    /// (see NodeInfo::drop_state). The hir_id_map field stores the mapping
-    /// from HirIds to the HirIdIndex that is used to represent that value in
-    /// bitvector.
-    tracked_value_map: UnordMap<TrackedValue, TrackedValueIndex>,
-
-    /// When building the control flow graph, we don't always know the
-    /// post-order index of the target node at the point we encounter it.
-    /// For example, this happens with break and continue. In those cases,
-    /// we store a pair of the PostOrderId of the source and the HirId
-    /// of the target. Once we have gathered all of these edges, we make a
-    /// pass over the set of deferred edges (see process_deferred_edges in
-    /// cfg_build.rs), look up the PostOrderId for the target (since now the
-    /// post-order index for all nodes is known), and add missing control flow
-    /// edges.
-    deferred_edges: Vec<(PostOrderId, HirId)>,
-    /// This maps HirIds of expressions to their post-order index. It is
-    /// used in process_deferred_edges to correctly add back-edges.
-    post_order_map: HirIdMap<PostOrderId>,
-}
-
-impl Debug for DropRangesBuilder {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("DropRanges")
-            .field("hir_id_map", &self.tracked_value_map)
-            .field("post_order_maps", &self.post_order_map)
-            .field("nodes", &self.nodes.iter_enumerated().collect::<BTreeMap<_, _>>())
-            .finish()
-    }
-}
-
-/// DropRanges keeps track of what values are definitely dropped at each point in the code.
-///
-/// Values of interest are defined by the hir_id of their place. Locations in code are identified
-/// by their index in the post-order traversal. At its core, DropRanges maps
-/// (hir_id, post_order_id) -> bool, where a true value indicates that the value is definitely
-/// dropped at the point of the node identified by post_order_id.
-impl DropRangesBuilder {
-    /// Returns the number of values (hir_ids) that are tracked
-    fn num_values(&self) -> usize {
-        self.tracked_value_map.len()
-    }
-
-    fn node_mut(&mut self, id: PostOrderId) -> &mut NodeInfo {
-        let size = self.num_values();
-        self.nodes.ensure_contains_elem(id, || NodeInfo::new(size))
-    }
-
-    fn add_control_edge(&mut self, from: PostOrderId, to: PostOrderId) {
-        trace!("adding control edge from {:?} to {:?}", from, to);
-        self.node_mut(from).successors.push(to);
-    }
-}
-
-#[derive(Debug)]
-struct NodeInfo {
-    /// IDs of nodes that can follow this one in the control flow
-    ///
-    /// If the vec is empty, then control proceeds to the next node.
-    successors: Vec<PostOrderId>,
-
-    /// List of hir_ids that are dropped by this node.
-    drops: Vec<TrackedValueIndex>,
-
-    /// List of hir_ids that are reinitialized by this node.
-    reinits: Vec<TrackedValueIndex>,
-
-    /// Set of values that are definitely dropped at this point.
-    drop_state: BitSet<TrackedValueIndex>,
-}
-
-impl NodeInfo {
-    fn new(num_values: usize) -> Self {
-        Self {
-            successors: vec![],
-            drops: vec![],
-            reinits: vec![],
-            drop_state: BitSet::new_filled(num_values),
-        }
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs
deleted file mode 100644
index 29413f08012..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs
+++ /dev/null
@@ -1,242 +0,0 @@
-use super::TrackedValue;
-use crate::{
-    expr_use_visitor::{self, ExprUseVisitor},
-    FnCtxt,
-};
-use hir::{def_id::DefId, Body, HirId, HirIdMap};
-use rustc_data_structures::{fx::FxIndexSet, unord::UnordSet};
-use rustc_hir as hir;
-use rustc_middle::ty::{ParamEnv, TyCtxt};
-use rustc_middle::{
-    hir::place::{PlaceBase, Projection, ProjectionKind},
-    ty::TypeVisitableExt,
-};
-
-pub(super) fn find_consumed_and_borrowed<'a, 'tcx>(
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    def_id: DefId,
-    body: &'tcx Body<'tcx>,
-) -> ConsumedAndBorrowedPlaces {
-    let mut expr_use_visitor = ExprUseDelegate::new(fcx.tcx, fcx.param_env);
-    expr_use_visitor.consume_body(fcx, def_id, body);
-    expr_use_visitor.places
-}
-
-pub(super) struct ConsumedAndBorrowedPlaces {
-    /// Records the variables/expressions that are dropped by a given expression.
-    ///
-    /// The key is the hir-id of the expression, and the value is a set or hir-ids for variables
-    /// or values that are consumed by that expression.
-    ///
-    /// Note that this set excludes "partial drops" -- for example, a statement like `drop(x.y)` is
-    /// not considered a drop of `x`, although it would be a drop of `x.y`.
-    pub(super) consumed: HirIdMap<FxIndexSet<TrackedValue>>,
-
-    /// A set of hir-ids of values or variables that are borrowed at some point within the body.
-    pub(super) borrowed: UnordSet<TrackedValue>,
-
-    /// A set of hir-ids of values or variables that are borrowed at some point within the body.
-    pub(super) borrowed_temporaries: UnordSet<HirId>,
-}
-
-/// Works with ExprUseVisitor to find interesting values for the drop range analysis.
-///
-/// Interesting values are those that are either dropped or borrowed. For dropped values, we also
-/// record the parent expression, which is the point where the drop actually takes place.
-struct ExprUseDelegate<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    places: ConsumedAndBorrowedPlaces,
-}
-
-impl<'tcx> ExprUseDelegate<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
-        Self {
-            tcx,
-            param_env,
-            places: ConsumedAndBorrowedPlaces {
-                consumed: <_>::default(),
-                borrowed: <_>::default(),
-                borrowed_temporaries: <_>::default(),
-            },
-        }
-    }
-
-    fn consume_body(&mut self, fcx: &'_ FnCtxt<'_, 'tcx>, def_id: DefId, body: &'tcx Body<'tcx>) {
-        // Run ExprUseVisitor to find where values are consumed.
-        ExprUseVisitor::new(
-            self,
-            &fcx.infcx,
-            def_id.expect_local(),
-            fcx.param_env,
-            &fcx.typeck_results.borrow(),
-        )
-        .consume_body(body);
-    }
-
-    fn mark_consumed(&mut self, consumer: HirId, target: TrackedValue) {
-        self.places.consumed.entry(consumer).or_insert_with(|| <_>::default());
-
-        debug!(?consumer, ?target, "mark_consumed");
-        self.places.consumed.get_mut(&consumer).map(|places| places.insert(target));
-    }
-
-    fn borrow_place(&mut self, place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>) {
-        self.places
-            .borrowed
-            .insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
-
-        // Ordinarily a value is consumed by it's parent, but in the special case of a
-        // borrowed RValue, we create a reference that lives as long as the temporary scope
-        // for that expression (typically, the innermost statement, but sometimes the enclosing
-        // block). We record this fact here so that later in generator_interior
-        // we can use the correct scope.
-        //
-        // We special case borrows through a dereference (`&*x`, `&mut *x` where `x` is
-        // some rvalue expression), since these are essentially a copy of a pointer.
-        // In other words, this borrow does not refer to the
-        // temporary (`*x`), but to the referent (whatever `x` is a borrow of).
-        //
-        // We were considering that we might encounter problems down the line if somehow,
-        // some part of the compiler were to look at this result and try to use it to
-        // drive a borrowck-like analysis (this does not currently happen, as of this writing).
-        // But even this should be fine, because the lifetime of the dereferenced reference
-        // found in the rvalue is only significant as an intermediate 'link' to the value we
-        // are producing, and we separately track whether that value is live over a yield.
-        // Example:
-        //
-        // ```notrust
-        // fn identity<T>(x: &mut T) -> &mut T { x }
-        // let a: A = ...;
-        // let y: &'y mut A = &mut *identity(&'a mut a);
-        //                    ^^^^^^^^^^^^^^^^^^^^^^^^^ the borrow we are talking about
-        // ```
-        //
-        // The expression `*identity(...)` is a deref of an rvalue,
-        // where the `identity(...)` (the rvalue) produces a return type
-        // of `&'rv mut A`, where `'a: 'rv`. We then assign this result to
-        // `'y`, resulting in (transitively) `'a: 'y` (i.e., while `y` is in use,
-        // `a` will be considered borrowed). Other parts of the code will ensure
-        // that if `y` is live over a yield, `&'y mut A` appears in the generator
-        // state. If `'y` is live, then any sound region analysis must conclude
-        // that `'a` is also live. So if this causes a bug, blame some other
-        // part of the code!
-        let is_deref = place_with_id
-            .place
-            .projections
-            .iter()
-            .any(|Projection { kind, .. }| *kind == ProjectionKind::Deref);
-
-        if let (false, PlaceBase::Rvalue) = (is_deref, place_with_id.place.base) {
-            self.places.borrowed_temporaries.insert(place_with_id.hir_id);
-        }
-    }
-}
-
-impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
-    fn consume(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-    ) {
-        let hir = self.tcx.hir();
-        let parent = match hir.opt_parent_id(place_with_id.hir_id) {
-            Some(parent) => parent,
-            None => place_with_id.hir_id,
-        };
-        debug!(
-            "consume {:?}; diag_expr_id={}, using parent {}",
-            place_with_id,
-            hir.node_to_string(diag_expr_id),
-            hir.node_to_string(parent)
-        );
-
-        if let Ok(tracked_value) = place_with_id.try_into() {
-            self.mark_consumed(parent, tracked_value)
-        }
-    }
-
-    fn borrow(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-        bk: rustc_middle::ty::BorrowKind,
-    ) {
-        debug!(
-            "borrow: place_with_id = {place_with_id:#?}, diag_expr_id={diag_expr_id:#?}, \
-            borrow_kind={bk:#?}"
-        );
-
-        self.borrow_place(place_with_id);
-    }
-
-    fn copy(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        _diag_expr_id: HirId,
-    ) {
-        debug!("copy: place_with_id = {place_with_id:?}");
-
-        self.places
-            .borrowed
-            .insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
-
-        // For copied we treat this mostly like a borrow except that we don't add the place
-        // to borrowed_temporaries because the copy is consumed.
-    }
-
-    fn mutate(
-        &mut self,
-        assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-    ) {
-        debug!("mutate {assignee_place:?}; diag_expr_id={diag_expr_id:?}");
-
-        if assignee_place.place.base == PlaceBase::Rvalue
-            && assignee_place.place.projections.is_empty()
-        {
-            // Assigning to an Rvalue is illegal unless done through a dereference. We would have
-            // already gotten a type error, so we will just return here.
-            return;
-        }
-
-        // If the type being assigned needs dropped, then the mutation counts as a borrow
-        // since it is essentially doing `Drop::drop(&mut x); x = new_value;`.
-        let ty = self.tcx.erase_regions(assignee_place.place.base_ty);
-        if ty.has_infer() {
-            self.tcx.sess.delay_span_bug(
-                self.tcx.hir().span(assignee_place.hir_id),
-                format!("inference variables in {ty}"),
-            );
-        } else if ty.needs_drop(self.tcx, self.param_env) {
-            self.places
-                .borrowed
-                .insert(TrackedValue::from_place_with_projections_allowed(assignee_place));
-        }
-    }
-
-    fn bind(
-        &mut self,
-        binding_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-    ) {
-        debug!("bind {binding_place:?}; diag_expr_id={diag_expr_id:?}");
-    }
-
-    fn fake_read(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        cause: rustc_middle::mir::FakeReadCause,
-        diag_expr_id: HirId,
-    ) {
-        debug!(
-            "fake_read place_with_id={place_with_id:?}; cause={cause:?}; diag_expr_id={diag_expr_id:?}"
-        );
-
-        // fake reads happen in places like the scrutinee of a match expression.
-        // we treat those as a borrow, much like a copy: the idea is that we are
-        // transiently creating a `&T` ref that we can read from to observe the current
-        // value (this `&T` is immediately dropped afterwards).
-        self.borrow_place(place_with_id);
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
deleted file mode 100644
index d2ab5aa6bae..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
+++ /dev/null
@@ -1,723 +0,0 @@
-//! This calculates the types which has storage which lives across a suspension point in a
-//! generator from the perspective of typeck. The actual types used at runtime
-//! is calculated in `rustc_mir_transform::generator` and may be a subset of the
-//! types computed here.
-
-use self::drop_ranges::DropRanges;
-use super::FnCtxt;
-use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
-use rustc_errors::{pluralize, DelayDm};
-use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::hir_id::HirIdSet;
-use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind};
-use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin};
-use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData};
-use rustc_middle::traits::ObligationCauseCode;
-use rustc_middle::ty::fold::FnMutDelegate;
-use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitableExt};
-use rustc_span::symbol::sym;
-use rustc_span::Span;
-use smallvec::{smallvec, SmallVec};
-
-mod drop_ranges;
-
-struct InteriorVisitor<'a, 'tcx> {
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    region_scope_tree: &'a region::ScopeTree,
-    types: FxIndexSet<ty::GeneratorInteriorTypeCause<'tcx>>,
-    rvalue_scopes: &'a RvalueScopes,
-    expr_count: usize,
-    kind: hir::GeneratorKind,
-    prev_unresolved_span: Option<Span>,
-    linted_values: HirIdSet,
-    drop_ranges: DropRanges,
-}
-
-impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
-    fn record(
-        &mut self,
-        ty: Ty<'tcx>,
-        hir_id: HirId,
-        scope: Option<region::Scope>,
-        expr: Option<&'tcx Expr<'tcx>>,
-        source_span: Span,
-    ) {
-        use rustc_span::DUMMY_SP;
-
-        let ty = self.fcx.resolve_vars_if_possible(ty);
-
-        debug!(
-            "attempting to record type ty={:?}; hir_id={:?}; scope={:?}; expr={:?}; source_span={:?}; expr_count={:?}",
-            ty, hir_id, scope, expr, source_span, self.expr_count,
-        );
-
-        let live_across_yield = scope
-            .map(|s| {
-                self.region_scope_tree.yield_in_scope(s).and_then(|yield_data| {
-                    // If we are recording an expression that is the last yield
-                    // in the scope, or that has a postorder CFG index larger
-                    // than the one of all of the yields, then its value can't
-                    // be storage-live (and therefore live) at any of the yields.
-                    //
-                    // See the mega-comment at `yield_in_scope` for a proof.
-
-                    yield_data
-                        .iter()
-                        .find(|yield_data| {
-                            debug!(
-                                "comparing counts yield: {} self: {}, source_span = {:?}",
-                                yield_data.expr_and_pat_count, self.expr_count, source_span
-                            );
-
-                            if self
-                                .is_dropped_at_yield_location(hir_id, yield_data.expr_and_pat_count)
-                            {
-                                debug!("value is dropped at yield point; not recording");
-                                return false;
-                            }
-
-                            // If it is a borrowing happening in the guard,
-                            // it needs to be recorded regardless because they
-                            // do live across this yield point.
-                            yield_data.expr_and_pat_count >= self.expr_count
-                        })
-                        .cloned()
-                })
-            })
-            .unwrap_or_else(|| {
-                Some(YieldData { span: DUMMY_SP, expr_and_pat_count: 0, source: self.kind.into() })
-            });
-
-        if let Some(yield_data) = live_across_yield {
-            debug!(
-                "type in expr = {:?}, scope = {:?}, type = {:?}, count = {}, yield_span = {:?}",
-                expr, scope, ty, self.expr_count, yield_data.span
-            );
-
-            if let Some((unresolved_term, unresolved_type_span)) =
-                self.fcx.first_unresolved_const_or_ty_var(&ty)
-            {
-                // If unresolved type isn't a ty_var then unresolved_type_span is None
-                let span = self
-                    .prev_unresolved_span
-                    .unwrap_or_else(|| unresolved_type_span.unwrap_or(source_span));
-
-                // If we encounter an int/float variable, then inference fallback didn't
-                // finish due to some other error. Don't emit spurious additional errors.
-                if let Some(unresolved_ty) = unresolved_term.ty()
-                    && let ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(_)) = unresolved_ty.kind()
-                {
-                    self.fcx
-                        .tcx
-                        .sess
-                        .delay_span_bug(span, format!("Encountered var {unresolved_term:?}"));
-                } else {
-                    let note = format!(
-                        "the type is part of the {} because of this {}",
-                        self.kind.descr(),
-                        yield_data.source
-                    );
-
-                    self.fcx
-                        .need_type_info_err_in_generator(self.kind, span, unresolved_term)
-                        .span_note(yield_data.span, note)
-                        .emit();
-                }
-            } else {
-                // Insert the type into the ordered set.
-                let scope_span = scope.map(|s| s.span(self.fcx.tcx, self.region_scope_tree));
-
-                if !self.linted_values.contains(&hir_id) {
-                    check_must_not_suspend_ty(
-                        self.fcx,
-                        ty,
-                        hir_id,
-                        SuspendCheckData {
-                            expr,
-                            source_span,
-                            yield_span: yield_data.span,
-                            plural_len: 1,
-                            ..Default::default()
-                        },
-                    );
-                    self.linted_values.insert(hir_id);
-                }
-
-                self.types.insert(ty::GeneratorInteriorTypeCause {
-                    span: source_span,
-                    ty,
-                    scope_span,
-                    yield_span: yield_data.span,
-                    expr: expr.map(|e| e.hir_id),
-                });
-            }
-        } else {
-            debug!(
-                "no type in expr = {:?}, count = {:?}, span = {:?}",
-                expr,
-                self.expr_count,
-                expr.map(|e| e.span)
-            );
-            if let Some((unresolved_type, unresolved_type_span)) =
-                self.fcx.first_unresolved_const_or_ty_var(&ty)
-            {
-                debug!(
-                    "remained unresolved_type = {:?}, unresolved_type_span: {:?}",
-                    unresolved_type, unresolved_type_span
-                );
-                self.prev_unresolved_span = unresolved_type_span;
-            }
-        }
-    }
-
-    /// If drop tracking is enabled, consult drop_ranges to see if a value is
-    /// known to be dropped at a yield point and therefore can be omitted from
-    /// the generator witness.
-    fn is_dropped_at_yield_location(&self, value_hir_id: HirId, yield_location: usize) -> bool {
-        // short-circuit if drop tracking is not enabled.
-        if !self.fcx.sess().opts.unstable_opts.drop_tracking {
-            return false;
-        }
-
-        self.drop_ranges.is_dropped_at(value_hir_id, yield_location)
-    }
-}
-
-pub fn resolve_interior<'a, 'tcx>(
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    def_id: DefId,
-    generator_def_id: LocalDefId,
-    body_id: hir::BodyId,
-    interior: Ty<'tcx>,
-    kind: hir::GeneratorKind,
-) {
-    let body = fcx.tcx.hir().body(body_id);
-    let typeck_results = fcx.inh.typeck_results.borrow();
-    let mut visitor = InteriorVisitor {
-        fcx,
-        types: FxIndexSet::default(),
-        region_scope_tree: fcx.tcx.region_scope_tree(def_id),
-        rvalue_scopes: &typeck_results.rvalue_scopes,
-        expr_count: 0,
-        kind,
-        prev_unresolved_span: None,
-        linted_values: <_>::default(),
-        drop_ranges: drop_ranges::compute_drop_ranges(fcx, def_id, body),
-    };
-    intravisit::walk_body(&mut visitor, body);
-
-    // Check that we visited the same amount of expressions as the RegionResolutionVisitor
-    let region_expr_count = fcx.tcx.region_scope_tree(def_id).body_expr_count(body_id).unwrap();
-    assert_eq!(region_expr_count, visitor.expr_count);
-
-    // The types are already kept in insertion order.
-    let types = visitor.types;
-
-    if fcx.tcx.features().unsized_locals || fcx.tcx.features().unsized_fn_params {
-        for interior_ty in &types {
-            fcx.require_type_is_sized(
-                interior_ty.ty,
-                interior_ty.span,
-                ObligationCauseCode::SizedGeneratorInterior(generator_def_id),
-            );
-        }
-    }
-
-    // The types in the generator interior contain lifetimes local to the generator itself,
-    // which should not be exposed outside of the generator. Therefore, we replace these
-    // lifetimes with existentially-bound lifetimes, which reflect the exact value of the
-    // lifetimes not being known by users.
-    //
-    // These lifetimes are used in auto trait impl checking (for example,
-    // if a Sync generator contains an &'α T, we need to check whether &'α T: Sync),
-    // so knowledge of the exact relationships between them isn't particularly important.
-
-    debug!("types in generator {:?}, span = {:?}", types, body.value.span);
-
-    // We want to deduplicate if the lifetimes are the same modulo some non-informative counter.
-    // So, we need to actually do two passes: first by type to anonymize (preserving information
-    // required for diagnostics), then a second pass over all captured types to reassign disjoint
-    // region indices.
-    let mut captured_tys = FxHashSet::default();
-    let type_causes: Vec<_> = types
-        .into_iter()
-        .filter_map(|mut cause| {
-            // Replace all regions inside the generator interior with late bound regions.
-            // Note that each region slot in the types gets a new fresh late bound region,
-            // which means that none of the regions inside relate to any other, even if
-            // typeck had previously found constraints that would cause them to be related.
-
-            let mut counter = 0;
-            let mut mk_bound_region = |kind| {
-                let var = ty::BoundVar::from_u32(counter);
-                counter += 1;
-                ty::BoundRegion { var, kind }
-            };
-            let ty = fcx.normalize(cause.span, cause.ty);
-            let ty = fcx.tcx.fold_regions(ty, |region, current_depth| {
-                let br = match region.kind() {
-                    ty::ReVar(vid) => {
-                        let origin = fcx.region_var_origin(vid);
-                        match origin {
-                            RegionVariableOrigin::EarlyBoundRegion(span, _) => {
-                                mk_bound_region(ty::BrAnon(Some(span)))
-                            }
-                            _ => mk_bound_region(ty::BrAnon(None)),
-                        }
-                    }
-                    ty::ReEarlyBound(region) => {
-                        mk_bound_region(ty::BrNamed(region.def_id, region.name))
-                    }
-                    ty::ReLateBound(_, ty::BoundRegion { kind, .. })
-                    | ty::ReFree(ty::FreeRegion { bound_region: kind, .. }) => match kind {
-                        ty::BoundRegionKind::BrAnon(span) => mk_bound_region(ty::BrAnon(span)),
-                        ty::BoundRegionKind::BrNamed(def_id, sym) => {
-                            mk_bound_region(ty::BrNamed(def_id, sym))
-                        }
-                        ty::BoundRegionKind::BrEnv => mk_bound_region(ty::BrAnon(None)),
-                    },
-                    _ => mk_bound_region(ty::BrAnon(None)),
-                };
-                let r = ty::Region::new_late_bound(fcx.tcx, current_depth, br);
-                r
-            });
-            captured_tys.insert(ty).then(|| {
-                cause.ty = ty;
-                cause
-            })
-        })
-        .collect();
-
-    let mut bound_vars: SmallVec<[BoundVariableKind; 4]> = smallvec![];
-    let mut counter = 0;
-    // Optimization: If there is only one captured type, then we don't actually
-    // need to fold and reindex (since the first type doesn't change).
-    let type_causes = if captured_tys.len() > 0 {
-        // Optimization: Use `replace_escaping_bound_vars_uncached` instead of
-        // `fold_regions`, since we only have late bound regions, and it skips
-        // types without bound regions.
-        fcx.tcx.replace_escaping_bound_vars_uncached(
-            type_causes,
-            FnMutDelegate {
-                regions: &mut |br| {
-                    let kind = br.kind;
-                    let var = ty::BoundVar::from_usize(bound_vars.len());
-                    bound_vars.push(ty::BoundVariableKind::Region(kind));
-                    counter += 1;
-                    ty::Region::new_late_bound(
-                        fcx.tcx,
-                        ty::INNERMOST,
-                        ty::BoundRegion { var, kind },
-                    )
-                },
-                types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"),
-                consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
-            },
-        )
-    } else {
-        type_causes
-    };
-
-    // Extract type components to build the witness type.
-    let type_list = fcx.tcx.mk_type_list_from_iter(type_causes.iter().map(|cause| cause.ty));
-    let bound_vars = fcx.tcx.mk_bound_variable_kinds(&bound_vars);
-    let witness =
-        Ty::new_generator_witness(fcx.tcx, ty::Binder::bind_with_vars(type_list, bound_vars));
-
-    drop(typeck_results);
-    // Store the generator types and spans into the typeck results for this generator.
-    fcx.inh.typeck_results.borrow_mut().generator_interior_types =
-        ty::Binder::bind_with_vars(type_causes, bound_vars);
-
-    debug!(
-        "types in generator after region replacement {:?}, span = {:?}",
-        witness, body.value.span
-    );
-
-    // Unify the type variable inside the generator with the new witness
-    match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(
-        DefineOpaqueTypes::No,
-        interior,
-        witness,
-    ) {
-        Ok(ok) => fcx.register_infer_ok_obligations(ok),
-        _ => bug!("failed to relate {interior} and {witness}"),
-    }
-}
-
-// This visitor has to have the same visit_expr calls as RegionResolutionVisitor in
-// librustc_middle/middle/region.rs since `expr_count` is compared against the results
-// there.
-impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
-    fn visit_arm(&mut self, arm: &'tcx Arm<'tcx>) {
-        let Arm { guard, pat, body, .. } = arm;
-        self.visit_pat(pat);
-        if let Some(ref g) = guard {
-            {
-                // If there is a guard, we need to count all variables bound in the pattern as
-                // borrowed for the entire guard body, regardless of whether they are accessed.
-                // We do this by walking the pattern bindings and recording `&T` for any `x: T`
-                // that is bound.
-
-                struct ArmPatCollector<'a, 'b, 'tcx> {
-                    interior_visitor: &'a mut InteriorVisitor<'b, 'tcx>,
-                    scope: Scope,
-                }
-
-                impl<'a, 'b, 'tcx> Visitor<'tcx> for ArmPatCollector<'a, 'b, 'tcx> {
-                    fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
-                        intravisit::walk_pat(self, pat);
-                        if let PatKind::Binding(_, id, ident, ..) = pat.kind {
-                            let ty =
-                                self.interior_visitor.fcx.typeck_results.borrow().node_type(id);
-                            let tcx = self.interior_visitor.fcx.tcx;
-                            let ty = Ty::new_ref(
-                                tcx,
-                                // Use `ReErased` as `resolve_interior` is going to replace all the
-                                // regions anyway.
-                                tcx.lifetimes.re_erased,
-                                ty::TypeAndMut { ty, mutbl: hir::Mutability::Not },
-                            );
-                            self.interior_visitor.record(
-                                ty,
-                                id,
-                                Some(self.scope),
-                                None,
-                                ident.span,
-                            );
-                        }
-                    }
-                }
-
-                ArmPatCollector {
-                    interior_visitor: self,
-                    scope: Scope { id: g.body().hir_id.local_id, data: ScopeData::Node },
-                }
-                .visit_pat(pat);
-            }
-
-            match g {
-                Guard::If(ref e) => {
-                    self.visit_expr(e);
-                }
-                Guard::IfLet(ref l) => {
-                    self.visit_let_expr(l);
-                }
-            }
-        }
-        self.visit_expr(body);
-    }
-
-    fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
-        intravisit::walk_pat(self, pat);
-
-        self.expr_count += 1;
-
-        if let PatKind::Binding(..) = pat.kind {
-            let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();
-            let ty = self.fcx.typeck_results.borrow().pat_ty(pat);
-            self.record(ty, pat.hir_id, Some(scope), None, pat.span);
-        }
-    }
-
-    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
-        match &expr.kind {
-            ExprKind::Call(callee, args) => match &callee.kind {
-                ExprKind::Path(qpath) => {
-                    let res = self.fcx.typeck_results.borrow().qpath_res(qpath, callee.hir_id);
-                    match res {
-                        // Direct calls never need to keep the callee `ty::FnDef`
-                        // ZST in a temporary, so skip its type, just in case it
-                        // can significantly complicate the generator type.
-                        Res::Def(
-                            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn),
-                            _,
-                        ) => {
-                            // NOTE(eddyb) this assumes a path expression has
-                            // no nested expressions to keep track of.
-                            self.expr_count += 1;
-
-                            // Record the rest of the call expression normally.
-                            for arg in *args {
-                                self.visit_expr(arg);
-                            }
-                        }
-                        _ => intravisit::walk_expr(self, expr),
-                    }
-                }
-                _ => intravisit::walk_expr(self, expr),
-            },
-            _ => intravisit::walk_expr(self, expr),
-        }
-
-        self.expr_count += 1;
-
-        debug!("is_borrowed_temporary: {:?}", self.drop_ranges.is_borrowed_temporary(expr));
-
-        let ty = self.fcx.typeck_results.borrow().expr_ty_adjusted_opt(expr);
-
-        // Typically, the value produced by an expression is consumed by its parent in some way,
-        // so we only have to check if the parent contains a yield (note that the parent may, for
-        // example, store the value into a local variable, but then we already consider local
-        // variables to be live across their scope).
-        //
-        // However, in the case of temporary values, we are going to store the value into a
-        // temporary on the stack that is live for the current temporary scope and then return a
-        // reference to it. That value may be live across the entire temporary scope.
-        //
-        // There's another subtlety: if the type has an observable drop, it must be dropped after
-        // the yield, even if it's not borrowed or referenced after the yield. Ideally this would
-        // *only* happen for types with observable drop, not all types which wrap them, but that
-        // doesn't match the behavior of MIR borrowck and causes ICEs. See the FIXME comment in
-        // tests/ui/generator/drop-tracking-parent-expression.rs.
-        let scope = if self.drop_ranges.is_borrowed_temporary(expr)
-            || ty.map_or(true, |ty| {
-                // Avoid ICEs in needs_drop.
-                let ty = self.fcx.resolve_vars_if_possible(ty);
-                let ty = self.fcx.tcx.erase_regions(ty);
-                if ty.has_infer() {
-                    self.fcx
-                        .tcx
-                        .sess
-                        .delay_span_bug(expr.span, format!("inference variables in {ty}"));
-                    true
-                } else {
-                    ty.needs_drop(self.fcx.tcx, self.fcx.param_env)
-                }
-            }) {
-            self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
-        } else {
-            let parent_expr = self
-                .fcx
-                .tcx
-                .hir()
-                .parent_iter(expr.hir_id)
-                .find(|(_, node)| matches!(node, hir::Node::Expr(_)))
-                .map(|(id, _)| id);
-            debug!("parent_expr: {:?}", parent_expr);
-            match parent_expr {
-                Some(parent) => Some(Scope { id: parent.local_id, data: ScopeData::Node }),
-                None => {
-                    self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
-                }
-            }
-        };
-
-        // If there are adjustments, then record the final type --
-        // this is the actual value that is being produced.
-        if let Some(adjusted_ty) = ty {
-            self.record(adjusted_ty, expr.hir_id, scope, Some(expr), expr.span);
-        }
-
-        // Also record the unadjusted type (which is the only type if
-        // there are no adjustments). The reason for this is that the
-        // unadjusted value is sometimes a "temporary" that would wind
-        // up in a MIR temporary.
-        //
-        // As an example, consider an expression like `vec![].push(x)`.
-        // Here, the `vec![]` would wind up MIR stored into a
-        // temporary variable `t` which we can borrow to invoke
-        // `<Vec<_>>::push(&mut t, x)`.
-        //
-        // Note that an expression can have many adjustments, and we
-        // are just ignoring those intermediate types. This is because
-        // those intermediate values are always linearly "consumed" by
-        // the other adjustments, and hence would never be directly
-        // captured in the MIR.
-        //
-        // (Note that this partly relies on the fact that the `Deref`
-        // traits always return references, which means their content
-        // can be reborrowed without needing to spill to a temporary.
-        // If this were not the case, then we could conceivably have
-        // to create intermediate temporaries.)
-        //
-        // The type table might not have information for this expression
-        // if it is in a malformed scope. (#66387)
-        if let Some(ty) = self.fcx.typeck_results.borrow().expr_ty_opt(expr) {
-            self.record(ty, expr.hir_id, scope, Some(expr), expr.span);
-        } else {
-            self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
-        }
-    }
-}
-
-#[derive(Default)]
-struct SuspendCheckData<'a, 'tcx> {
-    expr: Option<&'tcx Expr<'tcx>>,
-    source_span: Span,
-    yield_span: Span,
-    descr_pre: &'a str,
-    descr_post: &'a str,
-    plural_len: usize,
-}
-
-// Returns whether it emitted a diagnostic or not
-// Note that this fn and the proceeding one are based on the code
-// for creating must_use diagnostics
-//
-// Note that this technique was chosen over things like a `Suspend` marker trait
-// as it is simpler and has precedent in the compiler
-fn check_must_not_suspend_ty<'tcx>(
-    fcx: &FnCtxt<'_, 'tcx>,
-    ty: Ty<'tcx>,
-    hir_id: HirId,
-    data: SuspendCheckData<'_, 'tcx>,
-) -> bool {
-    if ty.is_unit()
-    // FIXME: should this check `Ty::is_inhabited_from`. This query is not available in this stage
-    // of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in
-    // `must_use`
-    // || !ty.is_inhabited_from(fcx.tcx, fcx.tcx.parent_module(hir_id).to_def_id(), fcx.param_env)
-    {
-        return false;
-    }
-
-    let plural_suffix = pluralize!(data.plural_len);
-
-    debug!("Checking must_not_suspend for {}", ty);
-
-    match *ty.kind() {
-        ty::Adt(..) if ty.is_box() => {
-            let boxed_ty = ty.boxed_ty();
-            let descr_pre = &format!("{}boxed ", data.descr_pre);
-            check_must_not_suspend_ty(fcx, boxed_ty, hir_id, SuspendCheckData { descr_pre, ..data })
-        }
-        ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did(), hir_id, data),
-        // FIXME: support adding the attribute to TAITs
-        ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
-            let mut has_emitted = false;
-            for &(predicate, _) in fcx.tcx.explicit_item_bounds(def).skip_binder() {
-                // We only look at the `DefId`, so it is safe to skip the binder here.
-                if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
-                    predicate.kind().skip_binder()
-                {
-                    let def_id = poly_trait_predicate.trait_ref.def_id;
-                    let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix);
-                    if check_must_not_suspend_def(
-                        fcx.tcx,
-                        def_id,
-                        hir_id,
-                        SuspendCheckData { descr_pre, ..data },
-                    ) {
-                        has_emitted = true;
-                        break;
-                    }
-                }
-            }
-            has_emitted
-        }
-        ty::Dynamic(binder, _, _) => {
-            let mut has_emitted = false;
-            for predicate in binder.iter() {
-                if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
-                    let def_id = trait_ref.def_id;
-                    let descr_post = &format!(" trait object{}{}", plural_suffix, data.descr_post);
-                    if check_must_not_suspend_def(
-                        fcx.tcx,
-                        def_id,
-                        hir_id,
-                        SuspendCheckData { descr_post, ..data },
-                    ) {
-                        has_emitted = true;
-                        break;
-                    }
-                }
-            }
-            has_emitted
-        }
-        ty::Tuple(fields) => {
-            let mut has_emitted = false;
-            let comps = match data.expr.map(|e| &e.kind) {
-                Some(hir::ExprKind::Tup(comps)) if comps.len() == fields.len() => Some(comps),
-                _ => None,
-            };
-            for (i, ty) in fields.iter().enumerate() {
-                let descr_post = &format!(" in tuple element {i}");
-                let span = comps.and_then(|c| c.get(i)).map(|e| e.span).unwrap_or(data.source_span);
-                if check_must_not_suspend_ty(
-                    fcx,
-                    ty,
-                    hir_id,
-                    SuspendCheckData {
-                        descr_post,
-                        expr: comps.and_then(|comps| comps.get(i)),
-                        source_span: span,
-                        ..data
-                    },
-                ) {
-                    has_emitted = true;
-                }
-            }
-            has_emitted
-        }
-        ty::Array(ty, len) => {
-            let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
-            let target_usize =
-                len.try_eval_target_usize(fcx.tcx, fcx.param_env).unwrap_or(0) as usize;
-            let plural_len = target_usize.saturating_add(1);
-            check_must_not_suspend_ty(
-                fcx,
-                ty,
-                hir_id,
-                SuspendCheckData { descr_pre, plural_len, ..data },
-            )
-        }
-        // If drop tracking is enabled, we want to look through references, since the referent
-        // may not be considered live across the await point.
-        ty::Ref(_region, ty, _mutability) if fcx.sess().opts.unstable_opts.drop_tracking => {
-            let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix);
-            check_must_not_suspend_ty(fcx, ty, hir_id, SuspendCheckData { descr_pre, ..data })
-        }
-        _ => false,
-    }
-}
-
-fn check_must_not_suspend_def(
-    tcx: TyCtxt<'_>,
-    def_id: DefId,
-    hir_id: HirId,
-    data: SuspendCheckData<'_, '_>,
-) -> bool {
-    if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
-        tcx.struct_span_lint_hir(
-            rustc_session::lint::builtin::MUST_NOT_SUSPEND,
-            hir_id,
-            data.source_span,
-            DelayDm(|| {
-                format!(
-                    "{}`{}`{} held across a suspend point, but should not be",
-                    data.descr_pre,
-                    tcx.def_path_str(def_id),
-                    data.descr_post,
-                )
-            }),
-            |lint| {
-                // add span pointing to the offending yield/await
-                lint.span_label(data.yield_span, "the value is held across this suspend point");
-
-                // Add optional reason note
-                if let Some(note) = attr.value_str() {
-                    // FIXME(guswynn): consider formatting this better
-                    lint.span_note(data.source_span, note.to_string());
-                }
-
-                // Add some quick suggestions on what to do
-                // FIXME: can `drop` work as a suggestion here as well?
-                lint.span_help(
-                    data.source_span,
-                    "consider using a block (`{ ... }`) \
-                    to shrink the value's scope, ending before the suspend point",
-                );
-
-                lint
-            },
-        );
-
-        true
-    } else {
-        false
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index f17f1d14bf3..6873382c4ac 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -32,7 +32,6 @@ pub mod expr_use_visitor;
 mod fallback;
 mod fn_ctxt;
 mod gather_locals;
-mod generator_interior;
 mod inherited;
 mod intrinsicck;
 mod mem_categorization;
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 2fe41c1197f..9c16b486dbc 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -63,7 +63,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         wbcx.visit_coercion_casts();
         wbcx.visit_user_provided_tys();
         wbcx.visit_user_provided_sigs();
-        wbcx.visit_generator_interior_types();
+        wbcx.visit_generator_interior();
         wbcx.visit_offset_of_container_types();
 
         wbcx.typeck_results.rvalue_scopes =
@@ -538,11 +538,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         );
     }
 
-    fn visit_generator_interior_types(&mut self) {
+    fn visit_generator_interior(&mut self) {
         let fcx_typeck_results = self.fcx.typeck_results.borrow();
         assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
-        self.typeck_results.generator_interior_types =
-            fcx_typeck_results.generator_interior_types.clone();
         self.tcx().with_stable_hashing_context(move |ref hcx| {
             for (&expr_def_id, predicates) in
                 fcx_typeck_results.generator_interior_predicates.to_sorted(hcx, false).into_iter()
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index 38910e45ecc..ad4525c922b 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -14,8 +14,7 @@ use rustc_span::{symbol::Ident, BytePos, Span};
 
 use crate::fluent_generated as fluent;
 use crate::infer::error_reporting::{
-    need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
-    nice_region_error::placeholder_error::Highlighted,
+    need_type_info::UnderspecifiedArgKind, nice_region_error::placeholder_error::Highlighted,
     ObligationCauseAsDiagArg,
 };
 
@@ -86,16 +85,6 @@ pub struct AmbiguousReturn<'a> {
     pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
 }
 
-#[derive(Diagnostic)]
-#[diag(infer_need_type_info_in_generator, code = "E0698")]
-pub struct NeedTypeInfoInGenerator<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub generator_kind: GeneratorKindAsDiagArg,
-    #[subdiagnostic]
-    pub bad_label: InferenceBadError<'a>,
-}
-
 // Used when a better one isn't available
 #[derive(Subdiagnostic)]
 #[label(infer_label_bad)]
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 6d5db3336cf..2797d079761 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -478,7 +478,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
         a: Self,
         b: Self,
     ) -> TypeTrace<'tcx> {
-        TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) }
+        TypeTrace {
+            cause: cause.clone(),
+            values: PolySigs(ExpectedFound::new(
+                a_is_expected,
+                ty::Binder::dummy(a),
+                ty::Binder::dummy(b),
+            )),
+        }
+    }
+}
+
+impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
+    fn to_trace(
+        cause: &ObligationCause<'tcx>,
+        a_is_expected: bool,
+        a: Self,
+        b: Self,
+    ) -> TypeTrace<'tcx> {
+        TypeTrace {
+            cause: cause.clone(),
+            values: PolySigs(ExpectedFound::new(a_is_expected, a, b)),
+        }
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 99bd296d0d5..5978e2c743c 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -459,7 +459,6 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
             ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Bool
             | ty::Char
             | ty::Int(..)
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index 1dbab48fd6c..665297da20f 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -119,26 +119,6 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
                         .obligations,
                 );
             }
-            // Optimization of GeneratorWitness relation since we know that all
-            // free regions are replaced with bound regions during construction.
-            // This greatly speeds up equating of GeneratorWitness.
-            (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
-                let a_types = infcx.tcx.anonymize_bound_vars(a_types);
-                let b_types = infcx.tcx.anonymize_bound_vars(b_types);
-                if a_types.bound_vars() == b_types.bound_vars() {
-                    let (a_types, b_types) = infcx.instantiate_binder_with_placeholders(
-                        a_types.map_bound(|a_types| (a_types, b_types.skip_binder())),
-                    );
-                    for (a, b) in std::iter::zip(a_types, b_types) {
-                        self.relate(a, b)?;
-                    }
-                } else {
-                    return Err(ty::error::TypeError::Sorts(ty::relate::expected_found(
-                        self, a, b,
-                    )));
-                }
-            }
-
             _ => {
                 self.fields.infcx.super_combine_tys(self, a, b)?;
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 1beb13cb94c..e418864026f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1660,7 +1660,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             _ => (false, Mismatch::Fixed("type")),
                         }
                     }
-                    ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => {
+                    ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => {
                         OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
                             .report(diag);
                         (false, Mismatch::Fixed("signature"))
@@ -2232,15 +2232,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     ret => ret,
                 }
             }
-            infer::Sigs(exp_found) => {
+            infer::PolySigs(exp_found) => {
                 let exp_found = self.resolve_vars_if_possible(exp_found);
                 if exp_found.references_error() {
                     return None;
                 }
-                let (exp, fnd) = self.cmp_fn_sig(
-                    &ty::Binder::dummy(exp_found.expected),
-                    &ty::Binder::dummy(exp_found.found),
-                );
+                let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
                 Some((exp, fnd, None, None))
             }
         }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index f2a3c47bdfe..bcaa4091c3a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -1,5 +1,5 @@
 use crate::errors::{
-    AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator,
+    AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError,
     SourceKindMultiSuggestion, SourceKindSubdiag,
 };
 use crate::infer::error_reporting::TypeErrCtxt;
@@ -595,39 +595,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     }
 }
 
-impl<'tcx> InferCtxt<'tcx> {
-    pub fn need_type_info_err_in_generator(
-        &self,
-        kind: hir::GeneratorKind,
-        span: Span,
-        ty: ty::Term<'tcx>,
-    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        let ty = self.resolve_vars_if_possible(ty);
-        let data = self.extract_inference_diagnostics_data(ty.into(), None);
-
-        NeedTypeInfoInGenerator {
-            bad_label: data.make_bad_error(span),
-            span,
-            generator_kind: GeneratorKindAsDiagArg(kind),
-        }
-        .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
-    }
-}
-
-pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind);
-
-impl IntoDiagnosticArg for GeneratorKindAsDiagArg {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
-        let kind = match self.0 {
-            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block",
-            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure",
-            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn",
-            hir::GeneratorKind::Gen => "generator",
-        };
-        rustc_errors::DiagnosticArgValue::Str(kind.into())
-    }
-}
-
 #[derive(Debug)]
 struct InferSource<'tcx> {
     span: Span,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index d2ba9966f03..cb51254a14b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -35,14 +35,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             && let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
             && let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
             && sub_trace.values == sup_trace.values
-            && let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values
+            && let ValuePairs::PolySigs(ExpectedFound { expected, found }) = sub_trace.values
         {
             // FIXME(compiler-errors): Don't like that this needs `Ty`s, but
             // all of the region highlighting machinery only deals with those.
             let guar = self.emit_err(
                 var_origin.span(),
-                Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(expected)),
-                Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(found)),
+                Ty::new_fn_ptr(self.cx.tcx, expected),
+                Ty::new_fn_ptr(self.cx.tcx, found),
                 *trait_item_def_id,
             );
             return Some(guar);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 445f68160d2..b34900da83b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -616,9 +616,13 @@ fn foo(&self) -> Self::T { String::new() }
                 for item in &items[..] {
                     if let hir::AssocItemKind::Type = item.kind {
                         let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();
-
-                        if self.infcx.can_eq(param_env, assoc_ty, found) {
-                            diag.span_label(item.span, "expected this associated type");
+                        if let hir::Defaultness::Default { has_value: true } = tcx.defaultness(item.id.owner_id)
+                            && self.infcx.can_eq(param_env, assoc_ty, found)
+                        {
+                            diag.span_label(
+                                item.span,
+                                format!("associated type is `default` and may be overridden"),
+                            );
                             return true;
                         }
                     }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 4cf9d44ed65..aeb3177af02 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -383,7 +383,7 @@ pub enum ValuePairs<'tcx> {
     Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
     TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
     PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
-    Sigs(ExpectedFound<ty::FnSig<'tcx>>),
+    PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
     ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
     ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>),
 }
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index 2ac9568f60b..6a9d40daab6 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -112,7 +112,7 @@ fn compute_components<'tcx>(
             }
 
             // All regions are bound inside a witness
-            ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => (),
+            ty::GeneratorWitness(..) => (),
 
             // OutlivesTypeParameterEnv -- the actual checking that `X:'a`
             // is implied by the environment is done in regionck.
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index 27e1ed56f31..0c3bb633b53 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -147,25 +147,6 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
                 );
                 Ok(a)
             }
-            // Optimization of GeneratorWitness relation since we know that all
-            // free regions are replaced with bound regions during construction.
-            // This greatly speeds up subtyping of GeneratorWitness.
-            (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
-                let a_types = infcx.tcx.anonymize_bound_vars(a_types);
-                let b_types = infcx.tcx.anonymize_bound_vars(b_types);
-                if a_types.bound_vars() == b_types.bound_vars() {
-                    let (a_types, b_types) = infcx.instantiate_binder_with_placeholders(
-                        a_types.map_bound(|a_types| (a_types, b_types.skip_binder())),
-                    );
-                    for (a, b) in std::iter::zip(a_types, b_types) {
-                        self.relate(a, b)?;
-                    }
-                    Ok(a)
-                } else {
-                    Err(ty::error::TypeError::Sorts(ty::relate::expected_found(self, a, b)))
-                }
-            }
-
             _ => {
                 self.fields.infcx.super_combine_tys(self, a, b)?;
                 Ok(a)
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index a0f0b530bae..1c330c064ab 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -9,7 +9,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_errors::registry::Registry;
 use rustc_errors::{ErrorGuaranteed, Handler};
 use rustc_lint::LintStore;
-use rustc_middle::query::{ExternProviders, Providers};
+use rustc_middle::util::Providers;
 use rustc_middle::{bug, ty};
 use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
@@ -37,7 +37,7 @@ pub struct Compiler {
     pub(crate) sess: Lrc<Session>,
     codegen_backend: Lrc<dyn CodegenBackend>,
     pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
-    pub(crate) override_queries: Option<fn(&Session, &mut Providers, &mut ExternProviders)>,
+    pub(crate) override_queries: Option<fn(&Session, &mut Providers)>,
 }
 
 impl Compiler {
@@ -271,7 +271,7 @@ pub struct Config {
     /// the list of queries.
     ///
     /// The second parameter is local providers and the third parameter is external providers.
-    pub override_queries: Option<fn(&Session, &mut Providers, &mut ExternProviders)>,
+    pub override_queries: Option<fn(&Session, &mut Providers)>,
 
     /// This is a callback from the driver that is called to create a codegen backend.
     pub make_codegen_backend:
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 51bd8381e93..76131c1ad69 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -25,7 +25,7 @@ pub mod util;
 
 pub use callbacks::setup_callbacks;
 pub use interface::{run_compiler, Config};
-pub use passes::{DEFAULT_EXTERN_QUERY_PROVIDERS, DEFAULT_QUERY_PROVIDERS};
+pub use passes::DEFAULT_QUERY_PROVIDERS;
 pub use queries::Queries;
 
 #[cfg(test)]
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index e5ae6d5b5d6..0e8f93cef17 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -18,8 +18,8 @@ use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintSto
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
-use rustc_middle::query::{ExternProviders, Providers};
 use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
+use rustc_middle::util::Providers;
 use rustc_mir_build as mir_build;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
 use rustc_passes::{self, abi_test, hir_stats, layout_test};
@@ -675,13 +675,6 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
     *providers
 });
 
-pub static DEFAULT_EXTERN_QUERY_PROVIDERS: LazyLock<ExternProviders> = LazyLock::new(|| {
-    let mut extern_providers = ExternProviders::default();
-    rustc_metadata::provide_extern(&mut extern_providers);
-    rustc_codegen_ssa::provide_extern(&mut extern_providers);
-    extern_providers
-});
-
 pub fn create_global_ctxt<'tcx>(
     compiler: &'tcx Compiler,
     crate_types: Vec<CrateType>,
@@ -702,14 +695,11 @@ pub fn create_global_ctxt<'tcx>(
     let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
 
     let codegen_backend = compiler.codegen_backend();
-    let mut local_providers = *DEFAULT_QUERY_PROVIDERS;
-    codegen_backend.provide(&mut local_providers);
-
-    let mut extern_providers = *DEFAULT_EXTERN_QUERY_PROVIDERS;
-    codegen_backend.provide_extern(&mut extern_providers);
+    let mut providers = *DEFAULT_QUERY_PROVIDERS;
+    codegen_backend.provide(&mut providers);
 
     if let Some(callback) = compiler.override_queries {
-        callback(sess, &mut local_providers, &mut extern_providers);
+        callback(sess, &mut providers);
     }
 
     let incremental = dep_graph.is_fully_enabled();
@@ -727,11 +717,12 @@ pub fn create_global_ctxt<'tcx>(
                 dep_graph,
                 rustc_query_impl::query_callbacks(arena),
                 rustc_query_impl::query_system(
-                    local_providers,
-                    extern_providers,
+                    providers.queries,
+                    providers.extern_queries,
                     query_result_on_disk_cache,
                     incremental,
                 ),
+                providers.hooks,
             )
         })
     })
@@ -807,14 +798,12 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
         }
     });
 
-    if tcx.sess.opts.unstable_opts.drop_tracking_mir {
-        tcx.hir().par_body_owners(|def_id| {
-            if let rustc_hir::def::DefKind::Generator = tcx.def_kind(def_id) {
-                tcx.ensure().mir_generator_witnesses(def_id);
-                tcx.ensure().check_generator_obligations(def_id);
-            }
-        });
-    }
+    tcx.hir().par_body_owners(|def_id| {
+        if let rustc_hir::def::DefKind::Generator = tcx.def_kind(def_id) {
+            tcx.ensure().mir_generator_witnesses(def_id);
+            tcx.ensure().check_generator_obligations(def_id);
+        }
+    });
 
     sess.time("layout_testing", || layout_test::test_layout(tcx));
     sess.time("abi_testing", || abi_test::test_abi(tcx));
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 1746cc8b719..2510ce71460 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -684,7 +684,6 @@ fn test_unstable_options_tracking_hash() {
     untracked!(dep_tasks, true);
     untracked!(dont_buffer_diagnostics, true);
     untracked!(dump_dep_graph, true);
-    untracked!(dump_drop_tracking_cfg, Some("cfg.dot".to_string()));
     untracked!(dump_mir, Some(String::from("abc")));
     untracked!(dump_mir_dataflow, true);
     untracked!(dump_mir_dir, String::from("abc"));
@@ -773,7 +772,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(debug_info_for_profiling, true);
     tracked!(debug_macros, true);
     tracked!(dep_info_omit_d_target, true);
-    tracked!(drop_tracking, true);
     tracked!(dual_proc_macros, true);
     tracked!(dwarf_version, Some(5));
     tracked!(emit_thin_lto, false);
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 57c2e289f20..44cf1591c7d 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1271,7 +1271,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Placeholder(..)
             | ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
         }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 1951db49e91..21575bf6b04 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -306,6 +306,7 @@ declare_lint! {
     /// pub async fn uhoh() {
     ///     let guard = SyncThing {};
     ///     yield_now().await;
+    ///     let _guard = guard;
     /// }
     /// ```
     ///
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 99fef84931e..fa77b36c4c5 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -26,7 +26,7 @@ extern crate rustc_middle;
 #[macro_use]
 extern crate tracing;
 
-pub use rmeta::{provide, provide_extern};
+pub use rmeta::provide;
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index a57bff3730d..b189e79df56 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -24,7 +24,6 @@ use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::ty::codec::TyDecoder;
 use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::GeneratorDiagnosticData;
 use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility};
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::{Decodable, Decoder};
@@ -44,7 +43,6 @@ use std::sync::atomic::Ordering;
 use std::{io, iter, mem};
 
 pub(super) use cstore_impl::provide;
-pub use cstore_impl::provide_extern;
 use rustc_span::hygiene::HygieneDecodeContext;
 
 mod cstore_impl;
@@ -1751,24 +1749,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .clone()
     }
 
-    fn get_generator_diagnostic_data(
-        self,
-        tcx: TyCtxt<'tcx>,
-        id: DefIndex,
-    ) -> Option<GeneratorDiagnosticData<'tcx>> {
-        self.root
-            .tables
-            .generator_diagnostic_data
-            .get(self, id)
-            .map(|param| param.decode((self, tcx)))
-            .map(|generator_data| GeneratorDiagnosticData {
-                generator_interior_types: generator_data.generator_interior_types,
-                hir_owner: generator_data.hir_owner,
-                nodes_types: generator_data.nodes_types,
-                adjustments: generator_data.adjustments,
-            })
-    }
-
     fn get_attr_flags(self, index: DefIndex) -> AttrFlags {
         self.root.tables.attr_flags.get(self, index)
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index e8c2fe5d178..b56fe375849 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -14,10 +14,11 @@ use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::metadata::ModChild;
 use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::middle::stability::DeprecationEntry;
+use rustc_middle::query::ExternProviders;
 use rustc_middle::query::LocalCrate;
-use rustc_middle::query::{ExternProviders, Providers};
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::util::Providers;
 use rustc_session::cstore::CrateStore;
 use rustc_session::{Session, StableCrateId};
 use rustc_span::hygiene::{ExpnHash, ExpnId};
@@ -147,7 +148,7 @@ macro_rules! provide_one {
 macro_rules! provide {
     ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
       $($name:ident => { $($compute:tt)* })*) => {
-        pub fn provide_extern(providers: &mut ExternProviders) {
+        fn provide_extern(providers: &mut ExternProviders) {
             $(provide_one! {
                 $tcx, $def_id, $other, $cdata, $name => { $($compute)* }
             })*
@@ -373,7 +374,6 @@ provide! { tcx, def_id, other, cdata,
 
     crate_extern_paths => { cdata.source().paths().cloned().collect() }
     expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
-    generator_diagnostic_data => { cdata.get_generator_diagnostic_data(tcx, def_id.index) }
     is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) }
     doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(def_id.index)) }
     doc_link_traits_in_scope => {
@@ -385,7 +385,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
     // FIXME(#44234) - almost all of these queries have no sub-queries and
     // therefore no actual inputs, they're just reading tables calculated in
     // resolve! Does this work? Unsure! That's what the issue is about
-    *providers = Providers {
+    providers.queries = rustc_middle::query::Providers {
         allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(),
         alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(),
         is_private_dep: |_tcx, LocalCrate| false,
@@ -513,8 +513,9 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
             tcx.untracked().cstore.freeze();
             tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum))
         },
-        ..*providers
+        ..providers.queries
     };
+    provide_extern(&mut providers.extern_queries);
 }
 
 impl CStore {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index cc7ae932e11..7506fc1bb05 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1439,7 +1439,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 }
             }
             if let DefKind::Generator = def_kind {
-                self.encode_info_for_generator(local_id);
+                let data = self.tcx.generator_kind(def_id).unwrap();
+                record!(self.tables.generator_kind[def_id] <- data);
             }
             if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
                 self.encode_info_for_adt(local_id);
@@ -1612,8 +1613,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()]
                     <- tcx.closure_saved_names_of_captured_variables(def_id));
 
-                if tcx.sess.opts.unstable_opts.drop_tracking_mir
-                    && let DefKind::Generator = self.tcx.def_kind(def_id)
+                if let DefKind::Generator = self.tcx.def_kind(def_id)
                     && let Some(witnesses) = tcx.mir_generator_witnesses(def_id)
                 {
                     record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses);
@@ -1640,6 +1640,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
 
+            if let DefKind::Generator = self.tcx.def_kind(def_id)
+                && let Some(witnesses) = tcx.mir_generator_witnesses(def_id)
+            {
+                record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses);
+            }
+
             let instance = ty::InstanceDef::Item(def_id.to_def_id());
             let unused = tcx.unused_generic_params(instance);
             self.tables.unused_generic_params.set(def_id.local_def_index, unused);
@@ -1712,15 +1718,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body);
     }
 
-    #[instrument(level = "debug", skip(self))]
-    fn encode_info_for_generator(&mut self, def_id: LocalDefId) {
-        let typeck_result: &'tcx ty::TypeckResults<'tcx> = self.tcx.typeck(def_id);
-        let data = self.tcx.generator_kind(def_id).unwrap();
-        let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
-        record!(self.tables.generator_kind[def_id.to_def_id()] <- data);
-        record!(self.tables.generator_diagnostic_data[def_id.to_def_id()]  <- generator_diagnostic_data);
-    }
-
     fn encode_native_libraries(&mut self) -> LazyArray<NativeLib> {
         empty_proc_macro!(self);
         let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index f2875bb11b1..09b2a1a0cb2 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -21,10 +21,10 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
 use rustc_middle::mir;
-use rustc_middle::query::Providers;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams};
-use rustc_middle::ty::{DeducedParamAttrs, GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
+use rustc_middle::ty::{DeducedParamAttrs, ParameterizedOverTcx, TyCtxt};
+use rustc_middle::util::Providers;
 use rustc_serialize::opaque::FileEncoder;
 use rustc_session::config::SymbolManglingVersion;
 use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
@@ -38,7 +38,6 @@ use rustc_target::spec::{PanicStrategy, TargetTriple};
 use std::marker::PhantomData;
 use std::num::NonZeroUsize;
 
-pub use decoder::provide_extern;
 use decoder::DecodeContext;
 pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
 use encoder::EncodeContext;
@@ -453,7 +452,6 @@ define_tables! {
     // definitions from any given crate.
     def_keys: Table<DefIndex, LazyValue<DefKey>>,
     proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
-    generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
     variant_data: Table<DefIndex, LazyValue<VariantData>>,
     assoc_container: Table<DefIndex, ty::AssocItemContainer>,
     macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs
new file mode 100644
index 00000000000..12aeae17725
--- /dev/null
+++ b/compiler/rustc_middle/src/hooks/mod.rs
@@ -0,0 +1,65 @@
+use crate::mir;
+use crate::query::TyCtxtAt;
+use crate::ty::{Ty, TyCtxt};
+use rustc_span::DUMMY_SP;
+
+macro_rules! declare_hooks {
+    ($($(#[$attr:meta])*hook $name:ident($($arg:ident: $K:ty),*) -> $V:ty;)*) => {
+
+        impl<'tcx> TyCtxt<'tcx> {
+            $(
+            $(#[$attr])*
+            #[inline(always)]
+            #[must_use]
+            pub fn $name(self, $($arg: $K,)*) -> $V
+            {
+                self.at(DUMMY_SP).$name($($arg,)*)
+            }
+            )*
+        }
+
+        impl<'tcx> TyCtxtAt<'tcx> {
+            $(
+            $(#[$attr])*
+            #[inline(always)]
+            #[must_use]
+            #[instrument(level = "debug", skip(self), ret)]
+            pub fn $name(self, $($arg: $K,)*) -> $V
+            {
+                (self.tcx.hooks.$name)(self, $($arg,)*)
+            }
+            )*
+        }
+
+        pub struct Providers {
+            $(pub $name: for<'tcx> fn(
+                TyCtxtAt<'tcx>,
+                $($arg: $K,)*
+            ) -> $V,)*
+        }
+
+        impl Default for Providers {
+            fn default() -> Self {
+                Providers {
+                    $($name: |_, $($arg,)*| bug!(
+                        "`tcx.{}{:?}` cannot be called as `{}` was never assigned to a provider function.\n",
+                        stringify!($name),
+                        ($($arg,)*),
+                        stringify!($name),
+                    ),)*
+                }
+            }
+        }
+
+        impl Copy for Providers {}
+        impl Clone for Providers {
+            fn clone(&self) -> Self { *self }
+        }
+    };
+}
+
+declare_hooks! {
+    /// Tries to destructure an `mir::Const` ADT or array into its variant index
+    /// and its field values. This should only be used for pretty printing.
+    hook try_destructure_mir_constant_for_diagnostics(val: mir::ConstValue<'tcx>, ty: Ty<'tcx>) -> Option<mir::DestructuredConstant<'tcx>>;
+}
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 50b69181d67..fe4fc3761b3 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -89,6 +89,7 @@ mod macros;
 pub mod arena;
 pub mod error;
 pub mod hir;
+pub mod hooks;
 pub mod infer;
 pub mod lint;
 pub mod metadata;
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index b43176a02d8..349b32c10fb 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1691,7 +1691,7 @@ fn pretty_print_const_value_tcx<'tcx>(
         (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => {
             let ct = tcx.lift(ct).unwrap();
             let ty = tcx.lift(ty).unwrap();
-            if let Some(contents) = tcx.try_destructure_mir_constant_for_diagnostics((ct, ty)) {
+            if let Some(contents) = tcx.try_destructure_mir_constant_for_diagnostics(ct, ty) {
                 let fields: Vec<(ConstValue<'_>, Ty<'_>)> = contents.fields.to_vec();
                 match *ty.kind() {
                     ty::Array(..) => {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d888a2c0fb6..5986a8b1cd8 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -44,7 +44,6 @@ use crate::traits::{
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::layout::ValidityRequirement;
 use crate::ty::util::AlwaysRequiresDrop;
-use crate::ty::GeneratorDiagnosticData;
 use crate::ty::TyCtxtFeed;
 use crate::ty::{
     self, print::describe_as_module, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt,
@@ -1100,16 +1099,6 @@ rustc_queries! {
         desc { "destructuring type level constant"}
     }
 
-    /// Tries to destructure an `mir::Const` ADT or array into its variant index
-    /// and its field values. This should only be used for pretty printing.
-    query try_destructure_mir_constant_for_diagnostics(
-        key: (mir::ConstValue<'tcx>, Ty<'tcx>)
-    ) -> Option<mir::DestructuredConstant<'tcx>> {
-        desc { "destructuring MIR constant"}
-        no_hash
-        eval_always
-    }
-
     query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> mir::ConstValue<'tcx> {
         desc { "getting a &core::panic::Location referring to a span" }
     }
@@ -2159,12 +2148,6 @@ rustc_queries! {
         desc { "computing the backend features for CLI flags" }
     }
 
-    query generator_diagnostic_data(key: DefId) -> &'tcx Option<GeneratorDiagnosticData<'tcx>> {
-        arena_cache
-        desc { |tcx| "looking up generator diagnostic data of `{}`", tcx.def_path_str(key) }
-        separate_provide_extern
-    }
-
     query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
         desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
     }
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 7c05deae90a..dff7ff8c66b 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -566,6 +566,5 @@ impl_binder_encode_decode! {
     ty::TraitPredicate<'tcx>,
     ty::ExistentialPredicate<'tcx>,
     ty::TraitRef<'tcx>,
-    Vec<ty::GeneratorInteriorTypeCause<'tcx>>,
     ty::ExistentialTraitRef<'tcx>,
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 9ff4b64f48b..400d4bcad5b 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -554,6 +554,10 @@ pub struct GlobalCtxt<'tcx> {
     /// Common consts, pre-interned for your convenience.
     pub consts: CommonConsts<'tcx>,
 
+    /// Hooks to be able to register functions in other crates that can then still
+    /// be called from rustc_middle.
+    pub(crate) hooks: crate::hooks::Providers,
+
     untracked: Untracked,
 
     pub query_system: QuerySystem<'tcx>,
@@ -703,6 +707,7 @@ impl<'tcx> TyCtxt<'tcx> {
         dep_graph: DepGraph,
         query_kinds: &'tcx [DepKindStruct<'tcx>],
         query_system: QuerySystem<'tcx>,
+        hooks: crate::hooks::Providers,
     ) -> GlobalCtxt<'tcx> {
         let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| {
             s.emit_fatal(err);
@@ -721,6 +726,7 @@ impl<'tcx> TyCtxt<'tcx> {
             hir_arena,
             interners,
             dep_graph,
+            hooks,
             prof: s.prof.clone(),
             types: common_types,
             lifetimes: common_lifetimes,
@@ -1378,7 +1384,6 @@ impl<'tcx> TyCtxt<'tcx> {
                     Placeholder,
                     Generator,
                     GeneratorWitness,
-                    GeneratorWitnessMIR,
                     Dynamic,
                     Closure,
                     Tuple,
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index f939d466078..459c8dfb596 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -242,8 +242,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Dynamic(..) => "trait object".into(),
             ty::Closure(..) => "closure".into(),
             ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
-            ty::GeneratorWitness(..) |
-            ty::GeneratorWitnessMIR(..) => "generator witness".into(),
+            ty::GeneratorWitness(..) => "generator witness".into(),
             ty::Infer(ty::TyVar(_)) => "inferred type".into(),
             ty::Infer(ty::IntVar(_)) => "integer".into(),
             ty::Infer(ty::FloatVar(_)) => "floating-point number".into(),
@@ -295,7 +294,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Dynamic(..) => "trait object".into(),
             ty::Closure(..) => "closure".into(),
             ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
-            ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => "generator witness".into(),
+            ty::GeneratorWitness(..) => "generator witness".into(),
             ty::Tuple(..) => "tuple".into(),
             ty::Placeholder(..) => "higher-ranked type".into(),
             ty::Bound(..) => "bound type variable".into(),
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 668aa4521c1..16935d5b380 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -29,8 +29,7 @@ pub enum SimplifiedType {
     Trait(DefId),
     Closure(DefId),
     Generator(DefId),
-    GeneratorWitness(usize),
-    GeneratorWitnessMIR(DefId),
+    GeneratorWitness(DefId),
     Function(usize),
     Placeholder,
 }
@@ -130,10 +129,7 @@ pub fn simplify_type<'tcx>(
         ty::Ref(_, _, mutbl) => Some(SimplifiedType::Ref(mutbl)),
         ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(SimplifiedType::Closure(def_id)),
         ty::Generator(def_id, _, _) => Some(SimplifiedType::Generator(def_id)),
-        ty::GeneratorWitness(tys) => {
-            Some(SimplifiedType::GeneratorWitness(tys.skip_binder().len()))
-        }
-        ty::GeneratorWitnessMIR(def_id, _) => Some(SimplifiedType::GeneratorWitnessMIR(def_id)),
+        ty::GeneratorWitness(def_id, _) => Some(SimplifiedType::GeneratorWitness(def_id)),
         ty::Never => Some(SimplifiedType::Never),
         ty::Tuple(tys) => Some(SimplifiedType::Tuple(tys.len())),
         ty::FnPtr(f) => Some(SimplifiedType::Function(f.skip_binder().inputs().len())),
@@ -169,7 +165,7 @@ impl SimplifiedType {
             | SimplifiedType::Trait(d)
             | SimplifiedType::Closure(d)
             | SimplifiedType::Generator(d)
-            | SimplifiedType::GeneratorWitnessMIR(d) => Some(d),
+            | SimplifiedType::GeneratorWitness(d) => Some(d),
             _ => None,
         }
     }
@@ -240,7 +236,6 @@ impl DeepRejectCtxt {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Placeholder(..)
             | ty::Bound(..)
             | ty::Infer(_) => bug!("unexpected impl_ty: {impl_ty}"),
@@ -342,7 +337,7 @@ impl DeepRejectCtxt {
 
             ty::Error(_) => true,
 
-            ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => {
+            ty::GeneratorWitness(..) => {
                 bug!("unexpected obligation type: {:?}", obligation_ty)
             }
         }
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 231635c086e..7ed31fbbfd8 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -127,11 +127,7 @@ impl FlagComputation {
                 self.add_ty(args.tupled_upvars_ty());
             }
 
-            &ty::GeneratorWitness(ts) => {
-                self.bound_computation(ts, |flags, ts| flags.add_tys(ts));
-            }
-
-            ty::GeneratorWitnessMIR(_, args) => {
+            ty::GeneratorWitness(_, args) => {
                 let should_remove_further_specializable =
                     !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
                 self.add_args(args);
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 8b425ce0267..bccf5e83987 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -810,7 +810,6 @@ where
                 | ty::Never
                 | ty::FnDef(..)
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Foreign(..)
                 | ty::Dynamic(_, _, ty::Dyn) => {
                     bug!("TyAndLayout::field({:?}): not applicable", this)
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b050208b4a6..aa1e7f216a0 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -106,9 +106,8 @@ pub use self::sty::{
 };
 pub use self::trait_def::TraitDef;
 pub use self::typeck_results::{
-    CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
-    GeneratorDiagnosticData, GeneratorInteriorTypeCause, TypeckResults, UserType,
-    UserTypeAnnotationIndex,
+    CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, TypeckResults,
+    UserType, UserTypeAnnotationIndex,
 };
 
 pub mod _match;
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 0ff5ac90304..6491936c219 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -157,9 +157,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
                 Ty::new_generator(self.tcx, def_id, args, movability)
             }
 
-            ty::GeneratorWitnessMIR(def_id, args) => {
+            ty::GeneratorWitness(def_id, args) => {
                 let args = self.fold_closure_args(def_id, args);
-                Ty::new_generator_witness_mir(self.tcx, def_id, args)
+                Ty::new_generator_witness(self.tcx, def_id, args)
             }
 
             ty::Param(param) => {
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index f1093e88312..9aa673e4418 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -132,5 +132,4 @@ parameterized_over_tcx! {
     ty::Predicate,
     ty::Clause,
     ty::ClauseKind,
-    ty::GeneratorDiagnosticData,
 }
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 05871d0bc39..aa8e2e30715 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -271,7 +271,7 @@ fn characteristic_def_id_of_type_cached<'a>(
         ty::FnDef(def_id, _)
         | ty::Closure(def_id, _)
         | ty::Generator(def_id, _, _)
-        | ty::GeneratorWitnessMIR(def_id, _)
+        | ty::GeneratorWitness(def_id, _)
         | ty::Foreign(def_id) => Some(def_id),
 
         ty::Bool
@@ -286,7 +286,6 @@ fn characteristic_def_id_of_type_cached<'a>(
         | ty::Infer(_)
         | ty::Bound(..)
         | ty::Error(_)
-        | ty::GeneratorWitness(..)
         | ty::Never
         | ty::Float(_) => None,
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5b833dde92c..34e3479c58e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -838,10 +838,7 @@ pub trait PrettyPrinter<'tcx>:
 
                 p!("}}")
             }
-            ty::GeneratorWitness(types) => {
-                p!(in_binder(&types));
-            }
-            ty::GeneratorWitnessMIR(did, args) => {
+            ty::GeneratorWitness(did, args) => {
                 p!(write("{{"));
                 if !self.tcx().sess.verbose() {
                     p!("generator witness");
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 47512d350e5..e9d763afa68 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -453,24 +453,14 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             Ok(Ty::new_generator(tcx, a_id, args, movability))
         }
 
-        (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
-            // Wrap our types with a temporary GeneratorWitness struct
-            // inside the binder so we can related them
-            let a_types = a_types.map_bound(GeneratorWitness);
-            let b_types = b_types.map_bound(GeneratorWitness);
-            // Then remove the GeneratorWitness for the result
-            let types = relation.relate(a_types, b_types)?.map_bound(|witness| witness.0);
-            Ok(Ty::new_generator_witness(tcx, types))
-        }
-
-        (&ty::GeneratorWitnessMIR(a_id, a_args), &ty::GeneratorWitnessMIR(b_id, b_args))
+        (&ty::GeneratorWitness(a_id, a_args), &ty::GeneratorWitness(b_id, b_args))
             if a_id == b_id =>
         {
             // All GeneratorWitness types with the same id represent
             // the (anonymous) type of the same generator expression. So
             // all of their regions should be equated.
             let args = relation.relate(a_args, b_args)?;
-            Ok(Ty::new_generator_witness_mir(tcx, a_id, args))
+            Ok(Ty::new_generator_witness(tcx, a_id, args))
         }
 
         (&ty::Closure(a_id, a_args), &ty::Closure(b_id, b_args)) if a_id == b_id => {
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index b66c0f20990..f6372ef3f2f 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -657,9 +657,8 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
             ty::Generator(did, args, movability) => {
                 ty::Generator(did, args.try_fold_with(folder)?, movability)
             }
-            ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
-            ty::GeneratorWitnessMIR(did, args) => {
-                ty::GeneratorWitnessMIR(did, args.try_fold_with(folder)?)
+            ty::GeneratorWitness(did, args) => {
+                ty::GeneratorWitness(did, args.try_fold_with(folder)?)
             }
             ty::Closure(did, args) => ty::Closure(did, args.try_fold_with(folder)?),
             ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
@@ -708,8 +707,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
                 ty.visit_with(visitor)
             }
             ty::Generator(_did, ref args, _) => args.visit_with(visitor),
-            ty::GeneratorWitness(ref types) => types.visit_with(visitor),
-            ty::GeneratorWitnessMIR(_did, ref args) => args.visit_with(visitor),
+            ty::GeneratorWitness(_did, ref args) => args.visit_with(visitor),
             ty::Closure(_did, ref args) => args.visit_with(visitor),
             ty::Alias(_, ref data) => data.visit_with(visitor),
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index f0526a23714..d2c42235adb 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -2165,18 +2165,10 @@ impl<'tcx> Ty<'tcx> {
     #[inline]
     pub fn new_generator_witness(
         tcx: TyCtxt<'tcx>,
-        types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>,
-    ) -> Ty<'tcx> {
-        Ty::new(tcx, GeneratorWitness(types))
-    }
-
-    #[inline]
-    pub fn new_generator_witness_mir(
-        tcx: TyCtxt<'tcx>,
         id: DefId,
         args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        Ty::new(tcx, GeneratorWitnessMIR(id, args))
+        Ty::new(tcx, GeneratorWitness(id, args))
     }
 
     // misc
@@ -2706,7 +2698,6 @@ impl<'tcx> Ty<'tcx> {
             | ty::Dynamic(..)
             | ty::Closure(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Error(_)
@@ -2742,7 +2733,6 @@ impl<'tcx> Ty<'tcx> {
             | ty::Ref(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::Never
@@ -2831,7 +2821,6 @@ impl<'tcx> Ty<'tcx> {
             | ty::Ref(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::Never
@@ -2894,7 +2883,7 @@ impl<'tcx> Ty<'tcx> {
             // anything with custom metadata it might be more complicated.
             ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false,
 
-            ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => false,
+            ty::Generator(..) | ty::GeneratorWitness(..) => false,
 
             // Might be, but not "trivial" so just giving the safe answer.
             ty::Adt(..) | ty::Closure(..) => false,
@@ -2970,8 +2959,7 @@ impl<'tcx> Ty<'tcx> {
             | Dynamic(_, _, _)
             | Closure(_, _)
             | Generator(_, _, _)
-            | GeneratorWitness(_)
-            | GeneratorWitnessMIR(_, _)
+            | GeneratorWitness(..)
             | Never
             | Tuple(_) => true,
             Error(_) | Infer(_) | Alias(_, _) | Param(_) | Bound(_, _) | Placeholder(_) => false,
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 69c4c588c44..a44224e4dc7 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -189,10 +189,6 @@ pub struct TypeckResults<'tcx> {
     /// Details may be find in `rustc_hir_analysis::check::rvalue_scopes`.
     pub rvalue_scopes: RvalueScopes,
 
-    /// Stores the type, expression, span and optional scope span of all types
-    /// that are live across the yield of this generator (if a generator).
-    pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
-
     /// Stores the predicates that apply on generator witness types.
     /// formatting modified file tests/ui/generator/retain-resume-ref.rs
     pub generator_interior_predicates:
@@ -212,49 +208,6 @@ pub struct TypeckResults<'tcx> {
     offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<FieldIdx>)>,
 }
 
-/// Whenever a value may be live across a generator yield, the type of that value winds up in the
-/// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
-/// captured types that can be useful for diagnostics. In particular, it stores the span that
-/// caused a given type to be recorded, along with the scope that enclosed the value (which can
-/// be used to find the await that the value is live across).
-///
-/// For example:
-///
-/// ```ignore (pseudo-Rust)
-/// async move {
-///     let x: T = expr;
-///     foo.await
-///     ...
-/// }
-/// ```
-///
-/// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
-/// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
-#[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct GeneratorInteriorTypeCause<'tcx> {
-    /// Type of the captured binding.
-    pub ty: Ty<'tcx>,
-    /// Span of the binding that was captured.
-    pub span: Span,
-    /// Span of the scope of the captured binding.
-    pub scope_span: Option<Span>,
-    /// Span of `.await` or `yield` expression.
-    pub yield_span: Span,
-    /// Expr which the type evaluated from.
-    pub expr: Option<hir::HirId>,
-}
-
-// This type holds diagnostic information on generators and async functions across crate boundaries
-// and is used to provide better error messages
-#[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)]
-pub struct GeneratorDiagnosticData<'tcx> {
-    pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
-    pub hir_owner: DefId,
-    pub nodes_types: ItemLocalMap<Ty<'tcx>>,
-    pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
-}
-
 impl<'tcx> TypeckResults<'tcx> {
     pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
         TypeckResults {
@@ -278,7 +231,6 @@ impl<'tcx> TypeckResults<'tcx> {
             closure_min_captures: Default::default(),
             closure_fake_reads: Default::default(),
             rvalue_scopes: Default::default(),
-            generator_interior_types: ty::Binder::dummy(Default::default()),
             generator_interior_predicates: Default::default(),
             treat_byte_string_as_slice: Default::default(),
             closure_size_eval: Default::default(),
@@ -351,28 +303,6 @@ impl<'tcx> TypeckResults<'tcx> {
         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
     }
 
-    pub fn get_generator_diagnostic_data(&self) -> GeneratorDiagnosticData<'tcx> {
-        let generator_interior_type = self.generator_interior_types.map_bound_ref(|vec| {
-            vec.iter()
-                .map(|item| {
-                    GeneratorInteriorTypeCause {
-                        ty: item.ty,
-                        span: item.span,
-                        scope_span: item.scope_span,
-                        yield_span: item.yield_span,
-                        expr: None, //FIXME: Passing expression over crate boundaries is impossible at the moment
-                    }
-                })
-                .collect::<Vec<_>>()
-        });
-        GeneratorDiagnosticData {
-            generator_interior_types: generator_interior_type,
-            hir_owner: self.hir_owner.to_def_id(),
-            nodes_types: self.node_types.clone(),
-            adjustments: self.adjustments.clone(),
-        }
-    }
-
     pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
         self.node_type_opt(id).unwrap_or_else(|| {
             bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id)))
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 564f982f842..0dda7cd83be 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -855,7 +855,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
                         let hidden_ty = bty.instantiate(self.tcx, args);
                         self.fold_ty(hidden_ty);
                     }
-                    let expanded_ty = Ty::new_generator_witness_mir(self.tcx, def_id, args);
+                    let expanded_ty = Ty::new_generator_witness(self.tcx, def_id, args);
                     self.expanded_cache.insert((def_id, args), expanded_ty);
                     expanded_ty
                 }
@@ -888,7 +888,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
             t
         };
         if self.expand_generators {
-            if let ty::GeneratorWitnessMIR(def_id, args) = *t.kind() {
+            if let ty::GeneratorWitness(def_id, args) = *t.kind() {
                 t = self.expand_generator(def_id, args).unwrap_or(t);
             }
         }
@@ -1025,8 +1025,7 @@ impl<'tcx> Ty<'tcx> {
             | ty::Dynamic(..)
             | ty::Foreign(_)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Infer(_)
             | ty::Alias(..)
             | ty::Param(_)
@@ -1065,8 +1064,7 @@ impl<'tcx> Ty<'tcx> {
             | ty::Dynamic(..)
             | ty::Foreign(_)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Infer(_)
             | ty::Alias(..)
             | ty::Param(_)
@@ -1194,10 +1192,7 @@ impl<'tcx> Ty<'tcx> {
                 false
             }
 
-            ty::Foreign(_)
-            | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
-            | ty::Error(_) => false,
+            ty::Foreign(_) | ty::GeneratorWitness(..) | ty::Error(_) => false,
         }
     }
 
@@ -1293,7 +1288,6 @@ pub fn needs_drop_components<'tcx>(
         | ty::FnPtr(_)
         | ty::Char
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::RawPtr(_)
         | ty::Ref(..)
         | ty::Str => Ok(SmallVec::new()),
@@ -1364,11 +1358,7 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
 
         // Not trivial because they have components, and instead of looking inside,
         // we'll just perform trait selection.
-        ty::Closure(..)
-        | ty::Generator(..)
-        | ty::GeneratorWitness(_)
-        | ty::GeneratorWitnessMIR(..)
-        | ty::Adt(..) => false,
+        ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) | ty::Adt(..) => false,
 
         ty::Array(ty, _) | ty::Slice(ty) => is_trivially_const_drop(ty),
 
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 7c3d9ed390a..a86ff64bd0c 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -190,14 +190,11 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
             ty::Adt(_, args)
             | ty::Closure(_, args)
             | ty::Generator(_, args, _)
-            | ty::GeneratorWitnessMIR(_, args)
+            | ty::GeneratorWitness(_, args)
             | ty::FnDef(_, args) => {
                 stack.extend(args.iter().rev());
             }
             ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)),
-            ty::GeneratorWitness(ts) => {
-                stack.extend(ts.skip_binder().iter().rev().map(|ty| ty.into()));
-            }
             ty::FnPtr(sig) => {
                 stack.push(sig.skip_binder().output().into());
                 stack.extend(sig.skip_binder().inputs().iter().copied().rev().map(|ty| ty.into()));
diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs
index 53b4257899b..8c95988477d 100644
--- a/compiler/rustc_middle/src/util/mod.rs
+++ b/compiler/rustc_middle/src/util/mod.rs
@@ -5,3 +5,27 @@ pub mod find_self_call;
 
 pub use call_kind::{call_kind, CallDesugaringKind, CallKind};
 pub use find_self_call::find_self_call;
+
+#[derive(Default, Copy, Clone)]
+pub struct Providers {
+    pub queries: rustc_middle::query::Providers,
+    pub extern_queries: rustc_middle::query::ExternProviders,
+    pub hooks: rustc_middle::hooks::Providers,
+}
+
+/// Backwards compatibility hack to keep the diff small. This
+/// gives direct access to the `queries` field's fields, which
+/// are what almost everything wants access to.
+impl std::ops::DerefMut for Providers {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.queries
+    }
+}
+
+impl std::ops::Deref for Providers {
+    type Target = rustc_middle::query::Providers;
+
+    fn deref(&self) -> &Self::Target {
+        &self.queries
+    }
+}
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 213b81eaac9..9ced3a7f3cd 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -144,8 +144,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     | ty::Dynamic(_, _, _)
                     | ty::Closure(_, _)
                     | ty::Generator(_, _, _)
-                    | ty::GeneratorWitness(_)
-                    | ty::GeneratorWitnessMIR(_, _)
+                    | ty::GeneratorWitness(..)
                     | ty::Never
                     | ty::Tuple(_)
                     | ty::Alias(_, _)
@@ -184,8 +183,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     | ty::FnDef(_, _)
                     | ty::FnPtr(_)
                     | ty::Dynamic(_, _, _)
-                    | ty::GeneratorWitness(_)
-                    | ty::GeneratorWitnessMIR(_, _)
+                    | ty::GeneratorWitness(..)
                     | ty::Never
                     | ty::Alias(_, _)
                     | ty::Param(_)
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 35373bcaa41..5879a803946 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -4,7 +4,9 @@ use rustc_errors::{
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::{self, Lint};
+use rustc_span::def_id::DefId;
 use rustc_span::Span;
 
 #[derive(LintDiagnostic)]
@@ -237,20 +239,38 @@ pub(crate) struct FnItemRef {
     pub ident: String,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(mir_transform_must_not_suspend)]
-pub(crate) struct MustNotSupend<'a> {
-    #[label]
+pub(crate) struct MustNotSupend<'tcx, 'a> {
+    pub tcx: TyCtxt<'tcx>,
     pub yield_sp: Span,
-    #[subdiagnostic]
     pub reason: Option<MustNotSuspendReason>,
-    #[help]
     pub src_sp: Span,
     pub pre: &'a str,
-    pub def_path: String,
+    pub def_id: DefId,
     pub post: &'a str,
 }
 
+// Needed for def_path_str
+impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> {
+    fn decorate_lint<'b>(
+        self,
+        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
+    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+        diag.span_label(self.yield_sp, crate::fluent_generated::_subdiag::label);
+        if let Some(reason) = self.reason {
+            diag.subdiagnostic(reason);
+        }
+        diag.span_help(self.src_sp, crate::fluent_generated::_subdiag::help);
+        diag.set_arg("pre", self.pre);
+        diag.set_arg("def_path", self.tcx.def_path_str(self.def_id));
+        diag.set_arg("post", self.post);
+        diag
+    }
+
+    fn msg(&self) -> rustc_errors::DiagnosticMessage {
+        crate::fluent_generated::mir_transform_must_not_suspend
+    }
+}
+
 #[derive(Subdiagnostic)]
 #[note(mir_transform_note)]
 pub(crate) struct MustNotSuspendReason {
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 96c60fdf41b..8a807d786a5 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -853,60 +853,7 @@ impl StorageConflictVisitor<'_, '_, '_> {
     }
 }
 
-/// Validates the typeck view of the generator against the actual set of types saved between
-/// yield points.
-fn sanitize_witness<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    body: &Body<'tcx>,
-    witness: Ty<'tcx>,
-    upvars: &'tcx ty::List<Ty<'tcx>>,
-    layout: &GeneratorLayout<'tcx>,
-) {
-    let did = body.source.def_id();
-    let param_env = tcx.param_env(did);
-
-    let allowed_upvars = tcx.normalize_erasing_regions(param_env, upvars);
-    let allowed = match witness.kind() {
-        &ty::GeneratorWitness(interior_tys) => {
-            tcx.normalize_erasing_late_bound_regions(param_env, interior_tys)
-        }
-        _ => {
-            tcx.sess.delay_span_bug(
-                body.span,
-                format!("unexpected generator witness type {:?}", witness.kind()),
-            );
-            return;
-        }
-    };
-
-    let mut mismatches = Vec::new();
-    for fty in &layout.field_tys {
-        if fty.ignore_for_traits {
-            continue;
-        }
-        let decl_ty = tcx.normalize_erasing_regions(param_env, fty.ty);
-
-        // Sanity check that typeck knows about the type of locals which are
-        // live across a suspension point
-        if !allowed.contains(&decl_ty) && !allowed_upvars.contains(&decl_ty) {
-            mismatches.push(decl_ty);
-        }
-    }
-
-    if !mismatches.is_empty() {
-        span_bug!(
-            body.span,
-            "Broken MIR: generator contains type {:?} in MIR, \
-                       but typeck only knows about {} and {:?}",
-            mismatches,
-            allowed,
-            allowed_upvars
-        );
-    }
-}
-
 fn compute_layout<'tcx>(
-    tcx: TyCtxt<'tcx>,
     liveness: LivenessInfo,
     body: &Body<'tcx>,
 ) -> (
@@ -932,27 +879,20 @@ fn compute_layout<'tcx>(
         let decl = &body.local_decls[local];
         debug!(?decl);
 
-        let ignore_for_traits = if tcx.sess.opts.unstable_opts.drop_tracking_mir {
-            // Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared
-            // the information. This is alright, since `ignore_for_traits` is only relevant when
-            // this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
-            // default.
-            match decl.local_info {
-                // Do not include raw pointers created from accessing `static` items, as those could
-                // well be re-created by another access to the same static.
-                ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
-                    !is_thread_local
-                }
-                // Fake borrows are only read by fake reads, so do not have any reality in
-                // post-analysis MIR.
-                ClearCrossCrate::Set(box LocalInfo::FakeBorrow) => true,
-                _ => false,
+        // Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared
+        // the information. This is alright, since `ignore_for_traits` is only relevant when
+        // this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
+        // default.
+        let ignore_for_traits = match decl.local_info {
+            // Do not include raw pointers created from accessing `static` items, as those could
+            // well be re-created by another access to the same static.
+            ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
+                !is_thread_local
             }
-        } else {
-            // FIXME(#105084) HIR-based drop tracking does not account for all the temporaries that
-            // MIR building may introduce. This leads to wrongly ignored types, but this is
-            // necessary for internal consistency and to avoid ICEs.
-            decl.internal
+            // Fake borrows are only read by fake reads, so do not have any reality in
+            // post-analysis MIR.
+            ClearCrossCrate::Set(box LocalInfo::FakeBorrow) => true,
+            _ => false,
         };
         let decl =
             GeneratorSavedTy { ty: decl.ty, source_info: decl.source_info, ignore_for_traits };
@@ -1445,8 +1385,6 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
 ) -> Option<GeneratorLayout<'tcx>> {
-    assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
-
     let (body, _) = tcx.mir_promoted(def_id);
     let body = body.borrow();
     let body = &*body;
@@ -1469,7 +1407,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
     // Extract locals which are live across suspension point into `layout`
     // `remap` gives a mapping from local indices onto generator struct indices
     // `storage_liveness` tells us which locals have live storage at suspension points
-    let (_, generator_layout, _) = compute_layout(tcx, liveness_info, body);
+    let (_, generator_layout, _) = compute_layout(liveness_info, body);
 
     check_suspend_tys(tcx, &generator_layout, &body);
 
@@ -1489,15 +1427,10 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         let gen_ty = body.local_decls.raw[1].ty;
 
         // Get the discriminant type and args which typeck computed
-        let (discr_ty, upvars, interior, movable) = match *gen_ty.kind() {
+        let (discr_ty, movable) = match *gen_ty.kind() {
             ty::Generator(_, args, movability) => {
                 let args = args.as_generator();
-                (
-                    args.discr_ty(tcx),
-                    args.upvar_tys(),
-                    args.witness(),
-                    movability == hir::Movability::Movable,
-                )
+                (args.discr_ty(tcx), movability == hir::Movability::Movable)
             }
             _ => {
                 tcx.sess.delay_span_bug(body.span, format!("unexpected generator type {gen_ty}"));
@@ -1574,13 +1507,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         // Extract locals which are live across suspension point into `layout`
         // `remap` gives a mapping from local indices onto generator struct indices
         // `storage_liveness` tells us which locals have live storage at suspension points
-        let (remap, layout, storage_liveness) = compute_layout(tcx, liveness_info, body);
-
-        if tcx.sess.opts.unstable_opts.validate_mir
-            && !tcx.sess.opts.unstable_opts.drop_tracking_mir
-        {
-            sanitize_witness(tcx, body, interior, upvars, &layout);
-        }
+        let (remap, layout, storage_liveness) = compute_layout(liveness_info, body);
 
         let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id()));
 
@@ -1954,11 +1881,12 @@ fn check_must_not_suspend_def(
             hir_id,
             data.source_span,
             errors::MustNotSupend {
+                tcx,
                 yield_sp: data.yield_span,
                 reason,
                 src_sp: data.source_span,
                 pre: data.descr_pre,
-                def_path: tcx.def_path_str(def_id),
+                def_id,
                 post: data.descr_post,
             },
         );
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index d55b0cbe635..d7fef093278 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -358,9 +358,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
 /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
 /// end up missing the source MIR due to stealing happening.
 fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
-    if tcx.sess.opts.unstable_opts.drop_tracking_mir
-        && let DefKind::Generator = tcx.def_kind(def)
-    {
+    if let DefKind::Generator = tcx.def_kind(def) {
         tcx.ensure_with_value().mir_generator_witnesses(def);
     }
     let mir_borrowck = tcx.mir_borrowck(def);
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 12118a0268b..afba366a365 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2333,7 +2333,10 @@ impl CheckAttrVisitor<'_> {
                 &mut diag,
                 &cause,
                 None,
-                Some(ValuePairs::Sigs(ExpectedFound { expected: expected_sig, found: sig })),
+                Some(ValuePairs::PolySigs(ExpectedFound {
+                    expected: ty::Binder::dummy(expected_sig),
+                    found: ty::Binder::dummy(sig),
+                })),
                 terr,
                 false,
                 false,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 1c2303ae9e0..2e71ac8d7dc 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -291,8 +291,7 @@ where
             | ty::Param(..)
             | ty::Bound(..)
             | ty::Error(_)
-            | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..) => {}
+            | ty::GeneratorWitness(..) => {}
             ty::Placeholder(..) | ty::Infer(..) => {
                 bug!("unexpected type: {:?}", ty)
             }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index c34b7df9b46..06a08f29a1e 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -214,6 +214,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 module: None,
             }
         } else {
+            let mut span_label = None;
             let item_span = path.last().unwrap().ident.span;
             let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 {
                 debug!(?self.diagnostic_metadata.current_impl_items);
@@ -224,32 +225,41 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                     && let FnKind::Fn(_, _, sig, ..) = fn_kind
                     && let Some(items) = self.diagnostic_metadata.current_impl_items
                     && let Some(item) = items.iter().find(|i| {
-                        if let AssocItemKind::Fn(..) | AssocItemKind::Const(..) = &i.kind
-                            && i.ident.name == item_str.name
-                            // don't suggest if the item is in Fn signature arguments
-                            // issue #112590
+                        i.ident.name == item_str.name
+                            // Don't suggest if the item is in Fn signature arguments (#112590).
                             && !sig.span.contains(item_span)
-                        {
-                            debug!(?item_str.name);
-                            return true
-                        }
-                        false
                     })
                 {
-                    let self_sugg = match &item.kind {
-                        AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => "self.",
-                        _ => "Self::",
-                    };
-
-                    Some((
-                        item_span.shrink_to_lo(),
-                        match &item.kind {
-                            AssocItemKind::Fn(..) => "consider using the associated function",
-                            AssocItemKind::Const(..) => "consider using the associated constant",
-                            _ => unreachable!("item kind was filtered above"),
-                        },
-                        self_sugg.to_string()
-                    ))
+                    let sp = item_span.shrink_to_lo();
+                    match &item.kind {
+                        AssocItemKind::Fn(fn_)
+                        if !sig.decl.has_self() && fn_.sig.decl.has_self() => {
+                            // Ensure that we only suggest `self.` if `self` is available,
+                            // you can't call `fn foo(&self)` from `fn bar()` (#115992).
+                            // We also want to mention that the method exists.
+                            span_label = Some((
+                                item.ident.span,
+                                "a method by that name is available on `Self` here",
+                            ));
+                            None
+                        }
+                        AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => Some((
+                            sp,
+                            "consider using the method on `Self`",
+                            "self.".to_string(),
+                        )),
+                        AssocItemKind::Fn(_) => Some((
+                            sp,
+                            "consider using the associated function on `Self`",
+                            "Self::".to_string(),
+                        )),
+                        AssocItemKind::Const(..) => Some((
+                            sp,
+                            "consider using the associated constant on `Self`",
+                            "Self::".to_string(),
+                        )),
+                        _ => None
+                    }
                 } else {
                     None
                 };
@@ -314,7 +324,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"),
                 fallback_label,
                 span: item_span,
-                span_label: None,
+                span_label,
                 could_be_expr: false,
                 suggestion,
                 module,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 23f2be632b2..c1424db600e 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1458,17 +1458,11 @@ options! {
     dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED],
         "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \
         (default: no)"),
-    drop_tracking: bool = (false, parse_bool, [TRACKED],
-        "enables drop tracking in generators (default: no)"),
-    drop_tracking_mir: bool = (false, parse_bool, [TRACKED],
-        "enables drop tracking on MIR in generators (default: no)"),
     dual_proc_macros: bool = (false, parse_bool, [TRACKED],
         "load proc macros for both target and host, but only link to the target (default: no)"),
     dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
         "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) \
         (default: no)"),
-    dump_drop_tracking_cfg: Option<String> = (None, parse_opt_string, [UNTRACKED],
-        "dump drop-tracking control-flow graph as a `.dot` file (default: no)"),
     dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "dump MIR state to file.
         `val` is used to select which passes and functions to dump. For example:
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index ad5f17cab6c..07aeac6b539 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -1128,11 +1128,7 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
             ty::Bound(debruijn_idx, bound_ty) => {
                 TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables))
             }
-            ty::Placeholder(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(_, _)
-            | ty::Infer(_)
-            | ty::Error(_) => {
+            ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) | ty::Error(_) => {
                 unreachable!();
             }
         }
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index d1f2c1b27fd..6ad3e7155e8 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -720,7 +720,6 @@ fn encode_ty<'tcx>(
         | ty::Bound(..)
         | ty::Error(..)
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::Infer(..)
         | ty::Placeholder(..) => {
             bug!("encode_ty: unexpected `{:?}`", ty.kind());
@@ -973,12 +972,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
             );
         }
 
-        ty::Bound(..)
-        | ty::Error(..)
-        | ty::GeneratorWitnessMIR(..)
-        | ty::Infer(..)
-        | ty::Param(..)
-        | ty::Placeholder(..) => {
+        ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) => {
             bug!("transform_ty: unexpected `{:?}`", ty.kind());
         }
     }
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index e9a7d0be4b4..ec94deb4658 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -484,8 +484,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
 
             ty::Alias(ty::Inherent, _) => bug!("symbol_names: unexpected inherent projection"),
             ty::Alias(ty::Weak, _) => bug!("symbol_names: unexpected weak projection"),
-            ty::GeneratorWitness(_) => bug!("symbol_names: unexpected `GeneratorWitness`"),
-            ty::GeneratorWitnessMIR(..) => bug!("symbol_names: unexpected `GeneratorWitnessMIR`"),
+            ty::GeneratorWitness(..) => bug!("symbol_names: unexpected `GeneratorWitness`"),
         }
 
         // Only cache types that do not refer to an enclosing
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index f7dcec307dd..7a666eea437 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -11,7 +11,6 @@ use Arch::*;
 #[allow(non_camel_case_types)]
 #[derive(Copy, Clone)]
 pub enum Arch {
-    Armv7,
     Armv7k,
     Armv7s,
     Arm64,
@@ -29,7 +28,6 @@ pub enum Arch {
 impl Arch {
     pub fn target_name(self) -> &'static str {
         match self {
-            Armv7 => "armv7",
             Armv7k => "armv7k",
             Armv7s => "armv7s",
             Arm64 | Arm64_macabi | Arm64_sim => "arm64",
@@ -43,7 +41,7 @@ impl Arch {
 
     pub fn target_arch(self) -> Cow<'static, str> {
         Cow::Borrowed(match self {
-            Armv7 | Armv7k | Armv7s => "arm",
+            Armv7k | Armv7s => "arm",
             Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64",
             I386 | I686 => "x86",
             X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64",
@@ -52,7 +50,7 @@ impl Arch {
 
     fn target_abi(self) -> &'static str {
         match self {
-            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "",
+            Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "",
             X86_64_macabi | Arm64_macabi => "macabi",
             // x86_64-apple-ios is a simulator target, even though it isn't
             // declared that way in the target like the other ones...
@@ -62,18 +60,20 @@ impl Arch {
 
     fn target_cpu(self) -> &'static str {
         match self {
-            Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
             Armv7k => "cortex-a8",
-            Armv7s => "cortex-a9",
+            Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher.
             Arm64 => "apple-a7",
             Arm64_32 => "apple-s4",
-            I386 | I686 => "yonah",
-            X86_64 | X86_64_sim => "core2",
+            // Only macOS 10.12+ is supported, which means
+            // all x86_64/x86 CPUs must be running at least penryn
+            // https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82
+            I386 | I686 => "penryn",
+            X86_64 | X86_64_sim => "penryn",
+            X86_64_macabi => "penryn",
             // Note: `core-avx2` is slightly more advanced than `x86_64h`, see
             // comments (and disabled features) in `x86_64h_apple_darwin` for
-            // details.
+            // details. It is a higher baseline then `penryn` however.
             X86_64h => "core-avx2",
-            X86_64_macabi => "core2",
             Arm64_macabi => "apple-a12",
             Arm64_sim => "apple-a12",
         }
@@ -115,21 +115,6 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
 }
 
 pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
-    // Static TLS is only available in macOS 10.7+. If you try to compile for 10.6
-    // either the linker will complain if it is used or the binary will end up
-    // segfaulting at runtime when run on 10.6. Rust by default supports macOS
-    // 10.7+, but there is a standard environment variable,
-    // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
-    // versions of macOS. For example compiling on 10.10 with
-    // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
-    // warnings about the usage of static TLS.
-    //
-    // Here we detect what version is being requested, defaulting to 10.7. Static
-    // TLS is flagged as enabled if it looks to be supported. The architecture
-    // only matters for default deployment target which is 11.0 for ARM64 and
-    // 10.7 for everything else.
-    let has_thread_local = os == "macos" && macos_deployment_target(Arch::X86_64) >= (10, 7);
-
     let abi = arch.target_abi();
 
     TargetOptions {
@@ -145,12 +130,17 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
         pre_link_args: pre_link_args(os, arch, abi),
         families: cvs!["unix"],
         is_like_osx: true,
-        default_dwarf_version: 2,
+        // LLVM notes that macOS 10.11+ and iOS 9+ default
+        // to v4, so we do the same.
+        // https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203
+        default_dwarf_version: 4,
         frame_pointer: FramePointer::Always,
         has_rpath: true,
         dll_suffix: ".dylib".into(),
         archive_format: "darwin".into(),
-        has_thread_local,
+        // Thread locals became available with iOS 8 and macOS 10.7,
+        // and both are far below our minimum.
+        has_thread_local: true,
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
         eh_frame_header: false,
@@ -239,9 +229,7 @@ fn macos_default_deployment_target(arch: Arch) -> (u32, u32) {
     match arch {
         // Note: Arm64_sim is not included since macOS has no simulator.
         Arm64 | Arm64_macabi => (11, 0),
-        // x86_64h-apple-darwin only supports macOS 10.8 and later
-        X86_64h => (10, 8),
-        _ => (10, 7),
+        _ => (10, 12),
     }
 }
 
@@ -292,8 +280,8 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]>
         // Otherwise if cross-compiling for a different OS/SDK, remove any part
         // of the linking environment that's wrong and reversed.
         match arch {
-            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim
-            | X86_64h | Arm64_sim => {
+            Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim | X86_64h
+            | Arm64_sim => {
                 cvs!["MACOSX_DEPLOYMENT_TARGET"]
             }
             X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"],
@@ -303,7 +291,7 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]>
 
 fn ios_deployment_target() -> (u32, u32) {
     // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
+    from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
 }
 
 fn mac_catalyst_deployment_target() -> (u32, u32) {
@@ -334,7 +322,7 @@ pub fn ios_sim_llvm_target(arch: Arch) -> String {
 
 fn tvos_deployment_target() -> (u32, u32) {
     // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
+    from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
 }
 
 fn tvos_lld_platform_version() -> String {
diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
deleted file mode 100644
index 3259c854791..00000000000
--- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use super::apple_base::{ios_llvm_target, opts, Arch};
-use crate::spec::{Target, TargetOptions};
-
-pub fn target() -> Target {
-    let arch = Arch::Armv7;
-    Target {
-        // Clang automatically chooses a more specific target based on
-        // IPHONEOS_DEPLOYMENT_TARGET.
-        // This is required for the target to pick the right
-        // MACH-O commands, so we do too.
-        llvm_target: ios_llvm_target(arch).into(),
-        pointer_width: 32,
-        data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions {
-            features: "+v7,+vfp3,+neon".into(),
-            max_atomic_width: Some(64),
-            ..opts("ios", arch)
-        },
-    }
-}
diff --git a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
index be4bc675844..be7f8542c9e 100644
--- a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
@@ -1,10 +1,10 @@
-use super::apple_base::{opts, Arch};
+use super::apple_base::{ios_llvm_target, opts, Arch};
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::Armv7s;
     Target {
-        llvm_target: "armv7s-apple-ios".into(),
+        llvm_target: ios_llvm_target(arch).into(),
         pointer_width: 32,
         data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(),
         arch: arch.target_arch(),
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 60fe98e5045..1bcb1f35315 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1394,7 +1394,6 @@ supported_targets! {
     ("i386-apple-ios", i386_apple_ios),
     ("x86_64-apple-ios", x86_64_apple_ios),
     ("aarch64-apple-ios", aarch64_apple_ios),
-    ("armv7-apple-ios", armv7_apple_ios),
     ("armv7s-apple-ios", armv7s_apple_ios),
     ("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
     ("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index e90bda9c9a8..e3f5d7321d1 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
@@ -5,7 +5,7 @@ use crate::spec::{StackProbeType, Target, TargetOptions};
 pub fn target() -> Target {
     let arch = Arch::X86_64;
     let mut base = opts("macos", arch);
-    base.max_atomic_width = Some(128); // core2 supports cmpxchg16b
+    base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b
     base.frame_pointer = FramePointer::Always;
     base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
     base.stack_probes = StackProbeType::X86;
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 128b9ad7e47..23d2c0c4ea0 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -469,7 +469,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             // FIXME: These should ideally not exist as a self type. It would be nice for
             // the builtin auto trait impls of generators to instead directly recurse
             // into the witness.
-            ty::GeneratorWitness(_) | ty::GeneratorWitnessMIR(_, _) => (),
+            ty::GeneratorWitness(..) => (),
 
             // These variants should not exist as a self type.
             ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
@@ -621,8 +621,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::Dynamic(..)
             | ty::Closure(..)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Param(_)
@@ -778,8 +777,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::Alias(..)
             | ty::Closure(..)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Param(_)
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index b61e02ba761..5935c614ffd 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -61,9 +61,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
             Ok(vec![generator_args.tupled_upvars_ty(), generator_args.witness()])
         }
 
-        ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
-
-        ty::GeneratorWitnessMIR(def_id, args) => Ok(ecx
+        ty::GeneratorWitness(def_id, args) => Ok(ecx
             .tcx()
             .generator_hidden_types(def_id)
             .map(|bty| {
@@ -127,7 +125,6 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
         | ty::Ref(..)
         | ty::Generator(..)
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::Array(..)
         | ty::Closure(..)
         | ty::Never
@@ -204,9 +201,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
             }
         }
 
-        ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
-
-        ty::GeneratorWitnessMIR(def_id, args) => Ok(ecx
+        ty::GeneratorWitness(def_id, args) => Ok(ecx
             .tcx()
             .generator_hidden_types(def_id)
             .map(|bty| {
@@ -282,8 +277,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
         | ty::Ref(_, _, _)
         | ty::Dynamic(_, _, _)
         | ty::Generator(_, _, _)
-        | ty::GeneratorWitness(_)
-        | ty::GeneratorWitnessMIR(..)
+        | ty::GeneratorWitness(..)
         | ty::Never
         | ty::Tuple(_)
         | ty::Alias(_, _)
diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
index f5901057a9d..64b1321e51d 100644
--- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
@@ -330,8 +330,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
             | ty::Dynamic(_, _, _)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Alias(_, _)
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index f6e781b87ba..c579da61e38 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -388,7 +388,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                 | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
                 | ty::Generator(..)
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Never
                 | ty::Foreign(..) => tcx.types.unit,
 
@@ -556,7 +555,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
             | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Never
             | ty::Foreign(..)
             | ty::Adt(_, _)
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index f18eed94a68..8055c63b9f3 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -879,8 +879,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::FnPtr(_)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(_, _)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Adt(_, _)
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 59f712721fb..acab4498a09 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -827,9 +827,7 @@ where
             // This should only be created when checking whether we have to check whether some
             // auto trait impl applies. There will never be multiple impls, so we can just
             // act as if it were a local type here.
-            ty::GeneratorWitness(_) | ty::GeneratorWitnessMIR(..) => {
-                ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
-            }
+            ty::GeneratorWitness(..) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
             ty::Alias(ty::Opaque, ..) => {
                 // This merits some explanation.
                 // Normally, opaque types are not involved when performing
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index d3e0d3b8b18..2a333a4f0e3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1847,7 +1847,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 ty::Generator(..) => Some(18),
                 ty::Foreign(..) => Some(19),
                 ty::GeneratorWitness(..) => Some(20),
-                ty::GeneratorWitnessMIR(..) => Some(21),
                 ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
             }
         }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index bb96e135741..748ecdc01b4 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -30,10 +30,9 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk, LateBoundRegionConversionTi
 use rustc_middle::hir::map;
 use rustc_middle::ty::error::TypeError::{self, Sorts};
 use rustc_middle::ty::{
-    self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind,
-    GeneratorDiagnosticData, GeneratorInteriorTypeCause, GenericArgs, InferTy, IsSuggestable,
-    ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder, TypeSuperFoldable,
-    TypeVisitableExt, TypeckResults,
+    self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, GenericArgs,
+    InferTy, IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder,
+    TypeSuperFoldable, TypeVisitableExt, TypeckResults,
 };
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -58,15 +57,12 @@ pub enum GeneratorInteriorOrUpvar {
 // This type provides a uniform interface to retrieve data on generators, whether it originated from
 // the local crate being compiled or from a foreign crate.
 #[derive(Debug)]
-pub enum GeneratorData<'tcx, 'a> {
-    Local(&'a TypeckResults<'tcx>),
-    Foreign(&'tcx GeneratorDiagnosticData<'tcx>),
-}
+struct GeneratorData<'tcx, 'a>(&'a TypeckResults<'tcx>);
 
 impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
-    // Try to get information about variables captured by the generator that matches a type we are
-    // looking for with `ty_matches` function. We uses it to find upvar which causes a failure to
-    // meet an obligation
+    /// Try to get information about variables captured by the generator that matches a type we are
+    /// looking for with `ty_matches` function. We uses it to find upvar which causes a failure to
+    /// meet an obligation
     fn try_get_upvar_span<F>(
         &self,
         infer_context: &InferCtxt<'tcx>,
@@ -76,27 +72,21 @@ impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
     where
         F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
     {
-        match self {
-            GeneratorData::Local(typeck_results) => {
-                infer_context.tcx.upvars_mentioned(generator_did).and_then(|upvars| {
-                    upvars.iter().find_map(|(upvar_id, upvar)| {
-                        let upvar_ty = typeck_results.node_type(*upvar_id);
-                        let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty);
-                        ty_matches(ty::Binder::dummy(upvar_ty))
-                            .then(|| GeneratorInteriorOrUpvar::Upvar(upvar.span))
-                    })
-                })
-            }
-            GeneratorData::Foreign(_) => None,
-        }
+        infer_context.tcx.upvars_mentioned(generator_did).and_then(|upvars| {
+            upvars.iter().find_map(|(upvar_id, upvar)| {
+                let upvar_ty = self.0.node_type(*upvar_id);
+                let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty);
+                ty_matches(ty::Binder::dummy(upvar_ty))
+                    .then(|| GeneratorInteriorOrUpvar::Upvar(upvar.span))
+            })
+        })
     }
 
-    // Try to get the span of a type being awaited on that matches the type we are looking with the
-    // `ty_matches` function. We uses it to find awaited type which causes a failure to meet an
-    // obligation
+    /// Try to get the span of a type being awaited on that matches the type we are looking with the
+    /// `ty_matches` function. We uses it to find awaited type which causes a failure to meet an
+    /// obligation
     fn get_from_await_ty<F>(
         &self,
-        tcx: TyCtxt<'tcx>,
         visitor: AwaitsVisitor,
         hir: map::Map<'tcx>,
         ty_matches: F,
@@ -104,69 +94,12 @@ impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
     where
         F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
     {
-        match self {
-            GeneratorData::Local(typeck_results) => visitor
-                .awaits
-                .into_iter()
-                .map(|id| hir.expect_expr(id))
-                .find(|await_expr| {
-                    ty_matches(ty::Binder::dummy(typeck_results.expr_ty_adjusted(&await_expr)))
-                })
-                .map(|expr| expr.span),
-            GeneratorData::Foreign(generator_diagnostic_data) => visitor
-                .awaits
-                .into_iter()
-                .map(|id| hir.expect_expr(id))
-                .find(|await_expr| {
-                    ty_matches(ty::Binder::dummy(
-                        generator_diagnostic_data
-                            .adjustments
-                            .get(&await_expr.hir_id.local_id)
-                            .map_or::<&[ty::adjustment::Adjustment<'tcx>], _>(&[], |a| &a[..])
-                            .last()
-                            .map_or_else::<Ty<'tcx>, _, _>(
-                                || {
-                                    generator_diagnostic_data
-                                        .nodes_types
-                                        .get(&await_expr.hir_id.local_id)
-                                        .cloned()
-                                        .unwrap_or_else(|| {
-                                            bug!(
-                                                "node_type: no type for node {}",
-                                                tcx.hir().node_to_string(await_expr.hir_id)
-                                            )
-                                        })
-                                },
-                                |adj| adj.target,
-                            ),
-                    ))
-                })
-                .map(|expr| expr.span),
-        }
-    }
-
-    /// Get the type, expression, span and optional scope span of all types
-    /// that are live across the yield of this generator
-    fn get_generator_interior_types(
-        &self,
-    ) -> ty::Binder<'tcx, &[GeneratorInteriorTypeCause<'tcx>]> {
-        match self {
-            GeneratorData::Local(typeck_result) => {
-                typeck_result.generator_interior_types.as_deref()
-            }
-            GeneratorData::Foreign(generator_diagnostic_data) => {
-                generator_diagnostic_data.generator_interior_types.as_deref()
-            }
-        }
-    }
-
-    // Used to get the source of the data, note we don't have as much information for generators
-    // originated from foreign crates
-    fn is_foreign(&self) -> bool {
-        match self {
-            GeneratorData::Local(_) => false,
-            GeneratorData::Foreign(_) => true,
-        }
+        visitor
+            .awaits
+            .into_iter()
+            .map(|id| hir.expect_expr(id))
+            .find(|await_expr| ty_matches(ty::Binder::dummy(self.0.expr_ty_adjusted(&await_expr))))
+            .map(|expr| expr.span)
     }
 }
 
@@ -316,7 +249,7 @@ pub trait TypeErrCtxtExt<'tcx> {
         outer_generator: Option<DefId>,
         trait_pred: ty::TraitPredicate<'tcx>,
         target_ty: Ty<'tcx>,
-        typeck_results: Option<&ty::TypeckResults<'tcx>>,
+        typeck_results: &ty::TypeckResults<'tcx>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
     );
@@ -2240,11 +2173,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     );
 
                     match *ty.kind() {
-                        ty::Generator(did, ..) | ty::GeneratorWitnessMIR(did, _) => {
+                        ty::Generator(did, ..) | ty::GeneratorWitness(did, _) => {
                             generator = generator.or(Some(did));
                             outer_generator = Some(did);
                         }
-                        ty::GeneratorWitness(..) => {}
                         ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
                             // By introducing a tuple of upvar types into the chain of obligations
                             // of a generator, the first non-generator item is now the tuple itself,
@@ -2270,11 +2202,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     );
 
                     match *ty.kind() {
-                        ty::Generator(did, ..) | ty::GeneratorWitnessMIR(did, ..) => {
+                        ty::Generator(did, ..) | ty::GeneratorWitness(did, ..) => {
                             generator = generator.or(Some(did));
                             outer_generator = Some(did);
                         }
-                        ty::GeneratorWitness(..) => {}
                         ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
                             // By introducing a tuple of upvar types into the chain of obligations
                             // of a generator, the first non-generator item is now the tuple itself,
@@ -2351,12 +2282,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         // cycles. If we can't use resolved types because the generator comes from another crate,
         // we still provide a targeted error but without all the relevant spans.
         let generator_data = match &self.typeck_results {
-            Some(t) if t.hir_owner.to_def_id() == generator_did_root => GeneratorData::Local(&t),
+            Some(t) if t.hir_owner.to_def_id() == generator_did_root => GeneratorData(&t),
             _ if generator_did.is_local() => {
-                GeneratorData::Local(self.tcx.typeck(generator_did.expect_local()))
-            }
-            _ if let Some(generator_diag_data) = self.tcx.generator_diagnostic_data(generator_did) => {
-                GeneratorData::Foreign(generator_diag_data)
+                GeneratorData(self.tcx.typeck(generator_did.expect_local()))
             }
             _ => return false,
         };
@@ -2368,30 +2296,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
         let mut interior_or_upvar_span = None;
 
-        let from_awaited_ty = generator_data.get_from_await_ty(self.tcx, visitor, hir, ty_matches);
+        let from_awaited_ty = generator_data.get_from_await_ty(visitor, hir, ty_matches);
         debug!(?from_awaited_ty);
 
-        // The generator interior types share the same binders
-        if let Some(cause) =
-            generator_data.get_generator_interior_types().skip_binder().iter().find(
-                |ty::GeneratorInteriorTypeCause { ty, .. }| {
-                    ty_matches(generator_data.get_generator_interior_types().rebind(*ty))
-                },
-            )
-        {
-            let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
-
-            interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(
-                *span,
-                Some((*scope_span, *yield_span, *expr, from_awaited_ty)),
-            ));
-
-            if interior_or_upvar_span.is_none() && generator_data.is_foreign() {
-                interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(*span, None));
-            }
-        } else if self.tcx.sess.opts.unstable_opts.drop_tracking_mir
-            // Avoid disclosing internal information to downstream crates.
-            && generator_did.is_local()
+        // Avoid disclosing internal information to downstream crates.
+        if generator_did.is_local()
             // Try to avoid cycles.
             && !generator_within_in_progress_typeck
             && let Some(generator_info) = self.tcx.mir_generator_witnesses(generator_did)
@@ -2420,17 +2329,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 generator_data.try_get_upvar_span(&self, generator_did, ty_matches);
         }
 
-        if interior_or_upvar_span.is_none() && generator_data.is_foreign() {
+        if interior_or_upvar_span.is_none() && !generator_did.is_local() {
             interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span, None));
         }
 
         debug!(?interior_or_upvar_span);
         if let Some(interior_or_upvar_span) = interior_or_upvar_span {
             let is_async = self.tcx.generator_is_async(generator_did);
-            let typeck_results = match generator_data {
-                GeneratorData::Local(typeck_results) => Some(typeck_results),
-                GeneratorData::Foreign(_) => None,
-            };
+            let typeck_results = generator_data.0;
             self.note_obligation_cause_for_async_await(
                 err,
                 interior_or_upvar_span,
@@ -2459,7 +2365,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         outer_generator: Option<DefId>,
         trait_pred: ty::TraitPredicate<'tcx>,
         target_ty: Ty<'tcx>,
-        typeck_results: Option<&ty::TypeckResults<'tcx>>,
+        typeck_results: &ty::TypeckResults<'tcx>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
     ) {
@@ -2584,11 +2490,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         );
                     } else {
                         // Look at the last interior type to get a span for the `.await`.
-                        debug!(
-                            generator_interior_types = ?format_args!(
-                                "{:#?}", typeck_results.as_ref().map(|t| &t.generator_interior_types)
-                            ),
-                        );
                         explain_yield(interior_span, yield_span, scope_span);
                     }
 
@@ -2608,14 +2509,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             // ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
                             // ```
                             //
-                            let is_region_borrow = if let Some(typeck_results) = typeck_results {
-                                typeck_results
-                                    .expr_adjustments(expr)
-                                    .iter()
-                                    .any(|adj| adj.is_region_borrow())
-                            } else {
-                                false
-                            };
+                            let is_region_borrow = typeck_results
+                                .expr_adjustments(expr)
+                                .iter()
+                                .any(|adj| adj.is_region_borrow());
 
                             // ```rust
                             // struct Foo(*const u8);
@@ -2628,16 +2525,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                     DefKind::Fn | DefKind::Ctor(..) => target_ty.is_unsafe_ptr(),
                                     _ => false,
                                 };
-                            if let Some(typeck_results) = typeck_results {
-                                if (typeck_results.is_method_call(e) && is_region_borrow)
-                                    || is_raw_borrow_inside_fn_like_call
-                                {
-                                    err.span_help(
-                                        parent_span,
-                                        "consider moving this into a `let` \
+                            if (typeck_results.is_method_call(e) && is_region_borrow)
+                                || is_raw_borrow_inside_fn_like_call
+                            {
+                                err.span_help(
+                                    parent_span,
+                                    "consider moving this into a `let` \
                         binding to create a shorter lived borrow",
-                                    );
-                                }
+                                );
                             }
                         }
                     }
@@ -3090,20 +2985,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 }
                                 err.span_note(self.tcx.def_span(def_id), msg)
                             }
-                            ty::GeneratorWitness(bound_tys) => {
-                                use std::fmt::Write;
-
-                                // FIXME: this is kind of an unusual format for rustc, can we make it more clear?
-                                // Maybe we should just remove this note altogether?
-                                // FIXME: only print types which don't meet the trait requirement
-                                let mut msg =
-                                    "required because it captures the following types: ".to_owned();
-                                for ty in bound_tys.skip_binder() {
-                                    with_forced_trimmed_paths!(write!(msg, "`{ty}`, ").unwrap());
-                                }
-                                err.note(msg.trim_end_matches(", ").to_string())
-                            }
-                            ty::GeneratorWitnessMIR(def_id, args) => {
+                            ty::GeneratorWitness(def_id, args) => {
                                 use std::fmt::Write;
 
                                 // FIXME: this is kind of an unusual format for rustc, can we make it more clear?
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 93e8e1f4bb1..154cc7a7141 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1813,7 +1813,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                         | ty::Closure(..)
                         | ty::Generator(..)
                         | ty::GeneratorWitness(..)
-                        | ty::GeneratorWitnessMIR(..)
                         | ty::Never
                         | ty::Tuple(..)
                         // Integers and floats always have `u8` as their discriminant.
@@ -1863,7 +1862,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                         | ty::Closure(..)
                         | ty::Generator(..)
                         | ty::GeneratorWitness(..)
-                        | ty::GeneratorWitnessMIR(..)
                         | ty::Never
                         // Extern types have unit metadata, according to RFC 2850
                         | ty::Foreign(_)
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 9484a50e3a9..86ea7a2bf83 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -36,7 +36,6 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
         | ty::FnPtr(_)
         | ty::Char
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::RawPtr(_)
         | ty::Ref(..)
         | ty::Str
@@ -218,8 +217,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
         | ty::Ref(..)
         | ty::FnDef(..)
         | ty::FnPtr(_)
-        | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..) => {
+        | ty::GeneratorWitness(..) => {
             // these types never have a destructor
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index e3da87a2210..bead8758ad6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -436,8 +436,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | ty::Ref(_, _, _)
                 | ty::Closure(_, _)
                 | ty::Generator(_, _, _)
-                | ty::GeneratorWitness(_)
-                | ty::GeneratorWitnessMIR(_, _)
+                | ty::GeneratorWitness(..)
                 | ty::Never
                 | ty::Tuple(_)
                 | ty::Error(_) => return true,
@@ -569,8 +568,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | ty::Generator(..)
                 | ty::Never
                 | ty::Tuple(_)
-                | ty::GeneratorWitness(_)
-                | ty::GeneratorWitnessMIR(..) => {
+                | ty::GeneratorWitness(..) => {
                     // Only consider auto impls if there are no manual impls for the root of `self_ty`.
                     //
                     // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
@@ -946,8 +944,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::Tuple(_)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..) => {
+            | ty::GeneratorWitness(..) => {
                 // These are built-in, and cannot have a custom `impl const Destruct`.
                 candidates.vec.push(ConstDestructCandidate(None));
             }
@@ -1020,8 +1017,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Dynamic(_, _, _)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Alias(..)
             | ty::Param(_)
@@ -1083,7 +1079,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Never
             | ty::Tuple(..)
             | ty::Alias(..)
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index eadac70057c..08ee9c73bf8 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -1238,10 +1238,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     let generator = args.as_generator();
                     stack.extend([generator.tupled_upvars_ty(), generator.witness()]);
                 }
-                ty::GeneratorWitness(tys) => {
-                    stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
-                }
-                ty::GeneratorWitnessMIR(def_id, args) => {
+                ty::GeneratorWitness(def_id, args) => {
                     let tcx = self.tcx();
                     stack.extend(tcx.generator_hidden_types(def_id).map(|bty| {
                         let ty = bty.instantiate(tcx, args);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index dcf41c3774f..7d672e658c7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2131,7 +2131,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             | ty::Ref(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::Never
@@ -2230,22 +2229,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 }
             }
 
-            ty::GeneratorWitness(binder) => {
-                let witness_tys = binder.skip_binder();
-                for witness_ty in witness_tys.iter() {
-                    let resolved = self.infcx.shallow_resolve(witness_ty);
-                    if resolved.is_ty_var() {
-                        return Ambiguous;
-                    }
-                }
-                // (*) binder moved here
-                let all_vars = self.tcx().mk_bound_variable_kinds_from_iter(
-                    obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()),
-                );
-                Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
-            }
-
-            ty::GeneratorWitnessMIR(def_id, ref args) => {
+            ty::GeneratorWitness(def_id, ref args) => {
                 let hidden_types = bind_generator_hidden_types_above(
                     self.infcx,
                     def_id,
@@ -2350,12 +2334,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 t.rebind([ty].into_iter().chain(iter::once(witness)).collect())
             }
 
-            ty::GeneratorWitness(types) => {
-                debug_assert!(!types.has_escaping_bound_vars());
-                types.map_bound(|types| types.to_vec())
-            }
-
-            ty::GeneratorWitnessMIR(def_id, ref args) => {
+            ty::GeneratorWitness(def_id, ref args) => {
                 bind_generator_hidden_types_above(self.infcx, def_id, args, t.bound_vars())
             }
 
@@ -3115,25 +3094,25 @@ fn bind_generator_hidden_types_above<'tcx>(
         .generator_hidden_types(def_id)
         // Deduplicate tys to avoid repeated work.
         .filter(|bty| seen_tys.insert(*bty))
-        .map(|bty| {
-            let mut ty = bty.instantiate(tcx, args);
-
+        .map(|mut bty| {
             // Only remap erased regions if we use them.
             if considering_regions {
-                ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
-                    ty::ReErased => {
-                        let br = ty::BoundRegion {
-                            var: ty::BoundVar::from_u32(counter),
-                            kind: ty::BrAnon(None),
-                        };
-                        counter += 1;
-                        ty::Region::new_late_bound(tcx, current_depth, br)
-                    }
-                    r => bug!("unexpected region: {r:?}"),
+                bty = bty.map_bound(|ty| {
+                    tcx.fold_regions(ty, |r, current_depth| match r.kind() {
+                        ty::ReErased => {
+                            let br = ty::BoundRegion {
+                                var: ty::BoundVar::from_u32(counter),
+                                kind: ty::BrAnon(None),
+                            };
+                            counter += 1;
+                            ty::Region::new_late_bound(tcx, current_depth, br)
+                        }
+                        r => bug!("unexpected region: {r:?}"),
+                    })
                 })
             }
 
-            ty
+            bty.instantiate(tcx, args)
         })
         .collect();
     if considering_regions {
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index 0864e4dc841..fc9b424369a 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -79,7 +79,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
             ty::Closure(..) => {
                 return ControlFlow::Break(ty);
             }
-            ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => {
+            ty::Generator(..) | ty::GeneratorWitness(..) => {
                 return ControlFlow::Break(ty);
             }
             ty::FnDef(..) => {
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index f26310665f9..b04008d9ee5 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -609,7 +609,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                 | ty::Error(_)
                 | ty::Str
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Never
                 | ty::Param(_)
                 | ty::Bound(..)
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index a03b82305f0..5bd68d7ccaa 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -577,11 +577,7 @@ fn layout_of_uncached<'tcx>(
             return Err(error(cx, LayoutError::Unknown(ty)));
         }
 
-        ty::Bound(..)
-        | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
-        | ty::Infer(_)
-        | ty::Error(_) => {
+        ty::Bound(..) | ty::GeneratorWitness(..) | ty::Infer(_) | ty::Error(_) => {
             bug!("Layout::compute: unexpected type `{}`", ty)
         }
 
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 1fc5d9359a4..6dcbc4470e6 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -7,7 +7,7 @@ use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
 use rustc_session::Limit;
-use rustc_span::{sym, DUMMY_SP};
+use rustc_span::sym;
 
 use crate::errors::NeedsDropOverflow;
 
@@ -133,7 +133,7 @@ where
                     // The information required to determine whether a generator has drop is
                     // computed on MIR, while this very method is used to build MIR.
                     // To avoid cycles, we consider that generators always require drop.
-                    ty::Generator(..) if tcx.sess.opts.unstable_opts.drop_tracking_mir => {
+                    ty::Generator(..) => {
                         return Some(Err(AlwaysRequiresDrop));
                     }
 
@@ -145,29 +145,6 @@ where
                         }
                     }
 
-                    ty::Generator(def_id, args, _) => {
-                        let args = args.as_generator();
-                        for upvar in args.upvar_tys() {
-                            queue_type(self, upvar);
-                        }
-
-                        let witness = args.witness();
-                        let interior_tys = match witness.kind() {
-                            &ty::GeneratorWitness(tys) => tcx.erase_late_bound_regions(tys),
-                            _ => {
-                                tcx.sess.delay_span_bug(
-                                    tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP),
-                                    format!("unexpected generator witness type {witness:?}"),
-                                );
-                                return Some(Err(AlwaysRequiresDrop));
-                            }
-                        };
-
-                        for interior_ty in interior_tys {
-                            queue_type(self, interior_ty);
-                        }
-                    }
-
                     // Check for a `Drop` impl and whether this is a union or
                     // `ManuallyDrop`. If it's a struct or enum without a `Drop`
                     // impl then check whether the field types need `Drop`.
@@ -215,7 +192,6 @@ where
                     | ty::Tuple(_)
                     | ty::Bound(..)
                     | ty::GeneratorWitness(..)
-                    | ty::GeneratorWitnessMIR(..)
                     | ty::Never
                     | ty::Infer(_)
                     | ty::Error(_) => {
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 6c23589b39a..4234e69e854 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -21,13 +21,7 @@ fn sized_constraint_for_ty<'tcx>(
         Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..)
         | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![],
 
-        Str
-        | Dynamic(..)
-        | Slice(_)
-        | Foreign(..)
-        | Error(_)
-        | GeneratorWitness(..)
-        | GeneratorWitnessMIR(..) => {
+        Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | GeneratorWitness(..) => {
             // these are never sized - return the target type
             vec![ty]
         }
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index b574cdcc879..c7fa0dcffa9 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -146,31 +146,6 @@ pub enum TyKind<I: Interner> {
     /// A type representing the types stored inside a generator.
     /// This should only appear as part of the `GeneratorArgs`.
     ///
-    /// Note that the captured variables for generators are stored separately
-    /// using a tuple in the same way as for closures.
-    ///
-    /// Unlike upvars, the witness can reference lifetimes from
-    /// inside of the generator itself. To deal with them in
-    /// the type of the generator, we convert them to higher ranked
-    /// lifetimes bound by the witness itself.
-    ///
-    /// Looking at the following example, the witness for this generator
-    /// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
-    ///
-    /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
-    /// #![feature(generators)]
-    /// |a| {
-    ///     let x = &vec![3];
-    ///     yield a;
-    ///     yield x[0];
-    /// }
-    /// # ;
-    /// ```
-    GeneratorWitness(I::BinderListTy),
-
-    /// A type representing the types stored inside a generator.
-    /// This should only appear as part of the `GeneratorArgs`.
-    ///
     /// Unlike upvars, the witness can reference lifetimes from
     /// inside of the generator itself. To deal with them in
     /// the type of the generator, we convert them to higher ranked
@@ -192,7 +167,7 @@ pub enum TyKind<I: Interner> {
     /// }
     /// # ;
     /// ```
-    GeneratorWitnessMIR(I::DefId, I::GenericArgsRef),
+    GeneratorWitness(I::DefId, I::GenericArgsRef),
 
     /// The never type `!`.
     Never,
@@ -278,7 +253,7 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
         Dynamic(..) => 14,
         Closure(_, _) => 15,
         Generator(_, _, _) => 16,
-        GeneratorWitness(_) => 17,
+        GeneratorWitness(_, _) => 17,
         Never => 18,
         Tuple(_) => 19,
         Alias(_, _) => 20,
@@ -287,7 +262,6 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
         Placeholder(_) => 23,
         Infer(_) => 24,
         Error(_) => 25,
-        GeneratorWitnessMIR(_, _) => 26,
     }
 }
 
@@ -312,8 +286,7 @@ impl<I: Interner> Clone for TyKind<I> {
             Dynamic(p, r, repr) => Dynamic(p.clone(), r.clone(), *repr),
             Closure(d, s) => Closure(d.clone(), s.clone()),
             Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()),
-            GeneratorWitness(g) => GeneratorWitness(g.clone()),
-            GeneratorWitnessMIR(d, s) => GeneratorWitnessMIR(d.clone(), s.clone()),
+            GeneratorWitness(d, s) => GeneratorWitness(d.clone(), s.clone()),
             Never => Never,
             Tuple(t) => Tuple(t.clone()),
             Alias(k, p) => Alias(*k, p.clone()),
@@ -355,10 +328,7 @@ impl<I: Interner> PartialEq for TyKind<I> {
             (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => {
                 a_d == b_d && a_s == b_s && a_m == b_m
             }
-            (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g,
-            (GeneratorWitnessMIR(a_d, a_s), GeneratorWitnessMIR(b_d, b_s)) => {
-                a_d == b_d && a_s == b_s
-            }
+            (GeneratorWitness(a_d, a_s), GeneratorWitness(b_d, b_s)) => a_d == b_d && a_s == b_s,
             (Tuple(a_t), Tuple(b_t)) => a_t == b_t,
             (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p,
             (Param(a_p), Param(b_p)) => a_p == b_p,
@@ -415,10 +385,9 @@ impl<I: Interner> Ord for TyKind<I> {
                 (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => {
                     a_d.cmp(b_d).then_with(|| a_s.cmp(b_s).then_with(|| a_m.cmp(b_m)))
                 }
-                (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g.cmp(b_g),
                 (
-                    GeneratorWitnessMIR(a_d, a_s),
-                    GeneratorWitnessMIR(b_d, b_s),
+                    GeneratorWitness(a_d, a_s),
+                    GeneratorWitness(b_d, b_s),
                 ) => match Ord::cmp(a_d, b_d) {
                     Ordering::Equal => Ord::cmp(a_s, b_s),
                     cmp => cmp,
@@ -483,8 +452,7 @@ impl<I: Interner> hash::Hash for TyKind<I> {
                 s.hash(state);
                 m.hash(state)
             }
-            GeneratorWitness(g) => g.hash(state),
-            GeneratorWitnessMIR(d, s) => {
+            GeneratorWitness(d, s) => {
                 d.hash(state);
                 s.hash(state);
             }
@@ -558,9 +526,8 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
             },
             Closure(d, s) => f.debug_tuple_field2_finish("Closure", d, &this.wrap(s)),
             Generator(d, s, m) => f.debug_tuple_field3_finish("Generator", d, &this.wrap(s), m),
-            GeneratorWitness(g) => f.debug_tuple_field1_finish("GeneratorWitness", &this.wrap(g)),
-            GeneratorWitnessMIR(d, s) => {
-                f.debug_tuple_field2_finish("GeneratorWitnessMIR", d, &this.wrap(s))
+            GeneratorWitness(d, s) => {
+                f.debug_tuple_field2_finish("GeneratorWitness", d, &this.wrap(s))
             }
             Never => write!(f, "!"),
             Tuple(t) => {
@@ -682,10 +649,7 @@ where
                 args.encode(e);
                 m.encode(e);
             }),
-            GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
-                b.encode(e);
-            }),
-            GeneratorWitnessMIR(def_id, args) => e.emit_enum_variant(disc, |e| {
+            GeneratorWitness(def_id, args) => e.emit_enum_variant(disc, |e| {
                 def_id.encode(e);
                 args.encode(e);
             }),
@@ -762,7 +726,7 @@ where
             14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
             15 => Closure(Decodable::decode(d), Decodable::decode(d)),
             16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
-            17 => GeneratorWitness(Decodable::decode(d)),
+            17 => GeneratorWitness(Decodable::decode(d), Decodable::decode(d)),
             18 => Never,
             19 => Tuple(Decodable::decode(d)),
             20 => Alias(Decodable::decode(d), Decodable::decode(d)),
@@ -771,12 +735,11 @@ where
             23 => Placeholder(Decodable::decode(d)),
             24 => Infer(Decodable::decode(d)),
             25 => Error(Decodable::decode(d)),
-            26 => GeneratorWitnessMIR(Decodable::decode(d), Decodable::decode(d)),
             _ => panic!(
                 "{}",
                 format!(
                     "invalid enum variant tag while decoding `{}`, expected 0..{}",
-                    "TyKind", 27,
+                    "TyKind", 26,
                 )
             ),
         }
@@ -870,10 +833,7 @@ where
                 args.hash_stable(__hcx, __hasher);
                 m.hash_stable(__hcx, __hasher);
             }
-            GeneratorWitness(b) => {
-                b.hash_stable(__hcx, __hasher);
-            }
-            GeneratorWitnessMIR(def_id, args) => {
+            GeneratorWitness(def_id, args) => {
                 def_id.hash_stable(__hcx, __hasher);
                 args.hash_stable(__hcx, __hasher);
             }