about summary refs log tree commit diff
path: root/compiler/stable_mir
diff options
context:
space:
mode:
authorMakai <m4kai410@gmail.com>2025-04-05 18:23:07 +0800
committerMakai <m4kai410@gmail.com>2025-04-05 18:23:07 +0800
commit707d356d004029a7e5300ce51e5aed330aa4a1a7 (patch)
tree8cc166ca3855dfdc724dbbafcd6955a113683ecb /compiler/stable_mir
parent1e008dd5d83e782ad37fc9cf6824733f824cc8cd (diff)
downloadrust-707d356d004029a7e5300ce51e5aed330aa4a1a7.tar.gz
rust-707d356d004029a7e5300ce51e5aed330aa4a1a7.zip
let `rustc_smir` host `stable_mir` for refactoring
Diffstat (limited to 'compiler/stable_mir')
-rw-r--r--compiler/stable_mir/Cargo.toml3
-rw-r--r--compiler/stable_mir/src/abi.rs456
-rw-r--r--compiler/stable_mir/src/compiler_interface.rs286
-rw-r--r--compiler/stable_mir/src/crate_def.rs174
-rw-r--r--compiler/stable_mir/src/error.rs85
-rw-r--r--compiler/stable_mir/src/lib.rs234
-rw-r--r--compiler/stable_mir/src/mir.rs8
-rw-r--r--compiler/stable_mir/src/mir/alloc.rs87
-rw-r--r--compiler/stable_mir/src/mir/body.rs1108
-rw-r--r--compiler/stable_mir/src/mir/mono.rs307
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs462
-rw-r--r--compiler/stable_mir/src/mir/visit.rs586
-rw-r--r--compiler/stable_mir/src/target.rs60
-rw-r--r--compiler/stable_mir/src/ty.rs1622
-rw-r--r--compiler/stable_mir/src/visitor.rs224
15 files changed, 6 insertions, 5696 deletions
diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml
index d691a0e4f22..3a01ee5783e 100644
--- a/compiler/stable_mir/Cargo.toml
+++ b/compiler/stable_mir/Cargo.toml
@@ -4,5 +4,4 @@ version = "0.1.0-preview"
 edition = "2024"
 
 [dependencies]
-scoped-tls = "1.0"
-serde = { version = "1.0.125", features = [ "derive" ] }
+rustc_smir = { path = "../rustc_smir" }
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs
deleted file mode 100644
index 091f3e1a95e..00000000000
--- a/compiler/stable_mir/src/abi.rs
+++ /dev/null
@@ -1,456 +0,0 @@
-use std::fmt::{self, Debug};
-use std::num::NonZero;
-use std::ops::RangeInclusive;
-
-use serde::Serialize;
-
-use crate::compiler_interface::with;
-use crate::mir::FieldIdx;
-use crate::target::{MachineInfo, MachineSize as Size};
-use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
-use crate::{Error, Opaque, error};
-
-/// A function ABI definition.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct FnAbi {
-    /// The types of each argument.
-    pub args: Vec<ArgAbi>,
-
-    /// The expected return type.
-    pub ret: ArgAbi,
-
-    /// The count of non-variadic arguments.
-    ///
-    /// Should only be different from `args.len()` when a function is a C variadic function.
-    pub fixed_count: u32,
-
-    /// The ABI convention.
-    pub conv: CallConvention,
-
-    /// Whether this is a variadic C function,
-    pub c_variadic: bool,
-}
-
-/// Information about the ABI of a function's argument, or return value.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct ArgAbi {
-    pub ty: Ty,
-    pub layout: Layout,
-    pub mode: PassMode,
-}
-
-/// How a function argument should be passed in to the target function.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum PassMode {
-    /// Ignore the argument.
-    ///
-    /// The argument is either uninhabited or a ZST.
-    Ignore,
-    /// Pass the argument directly.
-    ///
-    /// The argument has a layout abi of `Scalar` or `Vector`.
-    Direct(Opaque),
-    /// Pass a pair's elements directly in two arguments.
-    ///
-    /// The argument has a layout abi of `ScalarPair`.
-    Pair(Opaque, Opaque),
-    /// Pass the argument after casting it.
-    Cast { pad_i32: bool, cast: Opaque },
-    /// Pass the argument indirectly via a hidden pointer.
-    Indirect { attrs: Opaque, meta_attrs: Opaque, on_stack: bool },
-}
-
-/// The layout of a type, alongside the type itself.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct TyAndLayout {
-    pub ty: Ty,
-    pub layout: Layout,
-}
-
-/// The layout of a type in memory.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct LayoutShape {
-    /// The fields location within the layout
-    pub fields: FieldsShape,
-
-    /// Encodes information about multi-variant layouts.
-    /// Even with `Multiple` variants, a layout still has its own fields! Those are then
-    /// shared between all variants.
-    ///
-    /// To access all fields of this layout, both `fields` and the fields of the active variant
-    /// must be taken into account.
-    pub variants: VariantsShape,
-
-    /// The `abi` defines how this data is passed between functions.
-    pub abi: ValueAbi,
-
-    /// The ABI mandated alignment in bytes.
-    pub abi_align: Align,
-
-    /// The size of this layout in bytes.
-    pub size: Size,
-}
-
-impl LayoutShape {
-    /// Returns `true` if the layout corresponds to an unsized type.
-    #[inline]
-    pub fn is_unsized(&self) -> bool {
-        self.abi.is_unsized()
-    }
-
-    #[inline]
-    pub fn is_sized(&self) -> bool {
-        !self.abi.is_unsized()
-    }
-
-    /// Returns `true` if the type is sized and a 1-ZST (meaning it has size 0 and alignment 1).
-    pub fn is_1zst(&self) -> bool {
-        self.is_sized() && self.size.bits() == 0 && self.abi_align == 1
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct Layout(usize);
-
-impl Layout {
-    pub fn shape(self) -> LayoutShape {
-        with(|cx| cx.layout_shape(self))
-    }
-}
-
-impl IndexedVal for Layout {
-    fn to_val(index: usize) -> Self {
-        Layout(index)
-    }
-    fn to_index(&self) -> usize {
-        self.0
-    }
-}
-
-/// Describes how the fields of a type are shaped in memory.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum FieldsShape {
-    /// Scalar primitives and `!`, which never have fields.
-    Primitive,
-
-    /// All fields start at no offset. The `usize` is the field count.
-    Union(NonZero<usize>),
-
-    /// Array/vector-like placement, with all fields of identical types.
-    Array { stride: Size, count: u64 },
-
-    /// Struct-like placement, with precomputed offsets.
-    ///
-    /// Fields are guaranteed to not overlap, but note that gaps
-    /// before, between and after all the fields are NOT always
-    /// padding, and as such their contents may not be discarded.
-    /// For example, enum variants leave a gap at the start,
-    /// where the discriminant field in the enum layout goes.
-    Arbitrary {
-        /// Offsets for the first byte of each field,
-        /// ordered to match the source definition order.
-        /// I.e.: It follows the same order as [crate::ty::VariantDef::fields()].
-        /// This vector does not go in increasing order.
-        offsets: Vec<Size>,
-    },
-}
-
-impl FieldsShape {
-    pub fn fields_by_offset_order(&self) -> Vec<FieldIdx> {
-        match self {
-            FieldsShape::Primitive => vec![],
-            FieldsShape::Union(_) | FieldsShape::Array { .. } => (0..self.count()).collect(),
-            FieldsShape::Arbitrary { offsets, .. } => {
-                let mut indices = (0..offsets.len()).collect::<Vec<_>>();
-                indices.sort_by_key(|idx| offsets[*idx]);
-                indices
-            }
-        }
-    }
-
-    pub fn count(&self) -> usize {
-        match self {
-            FieldsShape::Primitive => 0,
-            FieldsShape::Union(count) => count.get(),
-            FieldsShape::Array { count, .. } => *count as usize,
-            FieldsShape::Arbitrary { offsets, .. } => offsets.len(),
-        }
-    }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum VariantsShape {
-    /// A type with no valid variants. Must be uninhabited.
-    Empty,
-
-    /// Single enum variants, structs/tuples, unions, and all non-ADTs.
-    Single { index: VariantIdx },
-
-    /// Enum-likes with more than one inhabited variant: each variant comes with
-    /// a *discriminant* (usually the same as the variant index but the user can
-    /// assign explicit discriminant values). That discriminant is encoded
-    /// as a *tag* on the machine. The layout of each variant is
-    /// a struct, and they all have space reserved for the tag.
-    /// For enums, the tag is the sole field of the layout.
-    Multiple {
-        tag: Scalar,
-        tag_encoding: TagEncoding,
-        tag_field: usize,
-        variants: Vec<LayoutShape>,
-    },
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum TagEncoding {
-    /// The tag directly stores the discriminant, but possibly with a smaller layout
-    /// (so converting the tag to the discriminant can require sign extension).
-    Direct,
-
-    /// Niche (values invalid for a type) encoding the discriminant:
-    /// Discriminant and variant index coincide.
-    /// The variant `untagged_variant` contains a niche at an arbitrary
-    /// offset (field `tag_field` of the enum), which for a variant with
-    /// discriminant `d` is set to
-    /// `(d - niche_variants.start).wrapping_add(niche_start)`.
-    ///
-    /// For example, `Option<(usize, &T)>`  is represented such that
-    /// `None` has a null pointer for the second tuple field, and
-    /// `Some` is the identity function (with a non-null reference).
-    Niche {
-        untagged_variant: VariantIdx,
-        niche_variants: RangeInclusive<VariantIdx>,
-        niche_start: u128,
-    },
-}
-
-/// Describes how values of the type are passed by target ABIs,
-/// in terms of categories of C types there are ABI rules for.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum ValueAbi {
-    Scalar(Scalar),
-    ScalarPair(Scalar, Scalar),
-    Vector {
-        element: Scalar,
-        count: u64,
-    },
-    Aggregate {
-        /// If true, the size is exact, otherwise it's only a lower bound.
-        sized: bool,
-    },
-}
-
-impl ValueAbi {
-    /// Returns `true` if the layout corresponds to an unsized type.
-    pub fn is_unsized(&self) -> bool {
-        match *self {
-            ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false,
-            ValueAbi::Aggregate { sized } => !sized,
-        }
-    }
-}
-
-/// Information about one scalar component of a Rust type.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)]
-pub enum Scalar {
-    Initialized {
-        /// The primitive type used to represent this value.
-        value: Primitive,
-        /// The range that represents valid values.
-        /// The range must be valid for the `primitive` size.
-        valid_range: WrappingRange,
-    },
-    Union {
-        /// Unions never have niches, so there is no `valid_range`.
-        /// Even for unions, we need to use the correct registers for the kind of
-        /// values inside the union, so we keep the `Primitive` type around.
-        /// It is also used to compute the size of the scalar.
-        value: Primitive,
-    },
-}
-
-impl Scalar {
-    pub fn has_niche(&self, target: &MachineInfo) -> bool {
-        match self {
-            Scalar::Initialized { value, valid_range } => {
-                !valid_range.is_full(value.size(target)).unwrap()
-            }
-            Scalar::Union { .. } => false,
-        }
-    }
-}
-
-/// Fundamental unit of memory access and layout.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize)]
-pub enum Primitive {
-    /// The `bool` is the signedness of the `Integer` type.
-    ///
-    /// One would think we would not care about such details this low down,
-    /// but some ABIs are described in terms of C types and ISAs where the
-    /// integer arithmetic is done on {sign,zero}-extended registers, e.g.
-    /// a negative integer passed by zero-extension will appear positive in
-    /// the callee, and most operations on it will produce the wrong values.
-    Int {
-        length: IntegerLength,
-        signed: bool,
-    },
-    Float {
-        length: FloatLength,
-    },
-    Pointer(AddressSpace),
-}
-
-impl Primitive {
-    pub fn size(self, target: &MachineInfo) -> Size {
-        match self {
-            Primitive::Int { length, .. } => Size::from_bits(length.bits()),
-            Primitive::Float { length } => Size::from_bits(length.bits()),
-            Primitive::Pointer(_) => target.pointer_width,
-        }
-    }
-}
-
-/// Enum representing the existing integer lengths.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
-pub enum IntegerLength {
-    I8,
-    I16,
-    I32,
-    I64,
-    I128,
-}
-
-/// Enum representing the existing float lengths.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
-pub enum FloatLength {
-    F16,
-    F32,
-    F64,
-    F128,
-}
-
-impl IntegerLength {
-    pub fn bits(self) -> usize {
-        match self {
-            IntegerLength::I8 => 8,
-            IntegerLength::I16 => 16,
-            IntegerLength::I32 => 32,
-            IntegerLength::I64 => 64,
-            IntegerLength::I128 => 128,
-        }
-    }
-}
-
-impl FloatLength {
-    pub fn bits(self) -> usize {
-        match self {
-            FloatLength::F16 => 16,
-            FloatLength::F32 => 32,
-            FloatLength::F64 => 64,
-            FloatLength::F128 => 128,
-        }
-    }
-}
-
-/// An identifier that specifies the address space that some operation
-/// should operate on. Special address spaces have an effect on code generation,
-/// depending on the target and the address spaces it implements.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
-pub struct AddressSpace(pub u32);
-
-impl AddressSpace {
-    /// The default address space, corresponding to data space.
-    pub const DATA: Self = AddressSpace(0);
-}
-
-/// Inclusive wrap-around range of valid values (bitwise representation), that is, if
-/// start > end, it represents `start..=MAX`, followed by `0..=end`.
-///
-/// That is, for an i8 primitive, a range of `254..=2` means following
-/// sequence:
-///
-///    254 (-2), 255 (-1), 0, 1, 2
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
-pub struct WrappingRange {
-    pub start: u128,
-    pub end: u128,
-}
-
-impl WrappingRange {
-    /// Returns `true` if `size` completely fills the range.
-    #[inline]
-    pub fn is_full(&self, size: Size) -> Result<bool, Error> {
-        let Some(max_value) = size.unsigned_int_max() else {
-            return Err(error!("Expected size <= 128 bits, but found {} instead", size.bits()));
-        };
-        if self.start <= max_value && self.end <= max_value {
-            Ok(self.start == (self.end.wrapping_add(1) & max_value))
-        } else {
-            Err(error!("Range `{self:?}` out of bounds for size `{}` bits.", size.bits()))
-        }
-    }
-
-    /// Returns `true` if `v` is contained in the range.
-    #[inline(always)]
-    pub fn contains(&self, v: u128) -> bool {
-        if self.wraps_around() {
-            self.start <= v || v <= self.end
-        } else {
-            self.start <= v && v <= self.end
-        }
-    }
-
-    /// Returns `true` if the range wraps around.
-    /// I.e., the range represents the union of `self.start..=MAX` and `0..=self.end`.
-    /// Returns `false` if this is a non-wrapping range, i.e.: `self.start..=self.end`.
-    #[inline]
-    pub fn wraps_around(&self) -> bool {
-        self.start > self.end
-    }
-}
-
-impl Debug for WrappingRange {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if self.start > self.end {
-            write!(fmt, "(..={}) | ({}..)", self.end, self.start)?;
-        } else {
-            write!(fmt, "{}..={}", self.start, self.end)?;
-        }
-        Ok(())
-    }
-}
-
-/// General language calling conventions.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum CallConvention {
-    C,
-    Rust,
-
-    Cold,
-    PreserveMost,
-    PreserveAll,
-
-    // Target-specific calling conventions.
-    ArmAapcs,
-    CCmseNonSecureCall,
-    CCmseNonSecureEntry,
-
-    Msp430Intr,
-
-    PtxKernel,
-
-    GpuKernel,
-
-    X86Fastcall,
-    X86Intr,
-    X86Stdcall,
-    X86ThisCall,
-    X86VectorCall,
-
-    X86_64SysV,
-    X86_64Win64,
-
-    AvrInterrupt,
-    AvrNonBlockingInterrupt,
-
-    RiscvInterrupt,
-}
diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs
deleted file mode 100644
index 46154da36ca..00000000000
--- a/compiler/stable_mir/src/compiler_interface.rs
+++ /dev/null
@@ -1,286 +0,0 @@
-//! Define the interface with the Rust compiler.
-//!
-//! StableMIR users should not use any of the items in this module directly.
-//! These APIs have no stability guarantee.
-
-use std::cell::Cell;
-
-use crate::abi::{FnAbi, Layout, LayoutShape};
-use crate::crate_def::Attribute;
-use crate::mir::alloc::{AllocId, GlobalAlloc};
-use crate::mir::mono::{Instance, InstanceDef, StaticDef};
-use crate::mir::{BinOp, Body, Place, UnOp};
-use crate::target::MachineInfo;
-use crate::ty::{
-    AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
-    ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
-    ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl,
-    TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
-};
-use crate::{
-    AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls,
-    ItemKind, Symbol, TraitDecls, mir,
-};
-
-/// This trait defines the interface between stable_mir and the Rust compiler.
-/// Do not use this directly.
-pub trait Context {
-    fn entry_fn(&self) -> Option<CrateItem>;
-    /// Retrieve all items of the local crate that have a MIR associated with them.
-    fn all_local_items(&self) -> CrateItems;
-    /// Retrieve the body of a function.
-    /// This function will panic if the body is not available.
-    fn mir_body(&self, item: DefId) -> mir::Body;
-    /// Check whether the body of a function is available.
-    fn has_body(&self, item: DefId) -> bool;
-    fn foreign_modules(&self, crate_num: CrateNum) -> Vec<ForeignModuleDef>;
-
-    /// Retrieve all functions defined in this crate.
-    fn crate_functions(&self, crate_num: CrateNum) -> Vec<FnDef>;
-
-    /// Retrieve all static items defined in this crate.
-    fn crate_statics(&self, crate_num: CrateNum) -> Vec<StaticDef>;
-    fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule;
-    fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec<ForeignDef>;
-    fn all_trait_decls(&self) -> TraitDecls;
-    fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls;
-    fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl;
-    fn all_trait_impls(&self) -> ImplTraitDecls;
-    fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls;
-    fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait;
-    fn generics_of(&self, def_id: DefId) -> Generics;
-    fn predicates_of(&self, def_id: DefId) -> GenericPredicates;
-    fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates;
-    /// Get information about the local crate.
-    fn local_crate(&self) -> Crate;
-    /// Retrieve a list of all external crates.
-    fn external_crates(&self) -> Vec<Crate>;
-
-    /// Find a crate with the given name.
-    fn find_crates(&self, name: &str) -> Vec<Crate>;
-
-    /// Returns the name of given `DefId`
-    fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol;
-
-    /// Return registered tool attributes with the given attribute name.
-    ///
-    /// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool
-    /// attributes will simply return an empty list.
-    ///
-    /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`.
-    /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
-    fn tool_attrs(&self, def_id: DefId, attr: &[Symbol]) -> Vec<Attribute>;
-
-    /// Get all tool attributes of a definition.
-    fn all_tool_attrs(&self, def_id: DefId) -> Vec<Attribute>;
-
-    /// Returns printable, human readable form of `Span`
-    fn span_to_string(&self, span: Span) -> String;
-
-    /// Return filename from given `Span`, for diagnostic purposes
-    fn get_filename(&self, span: &Span) -> Filename;
-
-    /// Return lines corresponding to this `Span`
-    fn get_lines(&self, span: &Span) -> LineInfo;
-
-    /// Returns the `kind` of given `DefId`
-    fn item_kind(&self, item: CrateItem) -> ItemKind;
-
-    /// Returns whether this is a foreign item.
-    fn is_foreign_item(&self, item: DefId) -> bool;
-
-    /// Returns the kind of a given foreign item.
-    fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind;
-
-    /// Returns the kind of a given algebraic data type
-    fn adt_kind(&self, def: AdtDef) -> AdtKind;
-
-    /// Returns if the ADT is a box.
-    fn adt_is_box(&self, def: AdtDef) -> bool;
-
-    /// Returns whether this ADT is simd.
-    fn adt_is_simd(&self, def: AdtDef) -> bool;
-
-    /// Returns whether this definition is a C string.
-    fn adt_is_cstr(&self, def: AdtDef) -> bool;
-
-    /// Retrieve the function signature for the given generic arguments.
-    fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig;
-
-    /// Retrieve the intrinsic definition if the item corresponds one.
-    fn intrinsic(&self, item: DefId) -> Option<IntrinsicDef>;
-
-    /// Retrieve the plain function name of an intrinsic.
-    fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol;
-
-    /// Retrieve the closure signature for the given generic arguments.
-    fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig;
-
-    /// The number of variants in this ADT.
-    fn adt_variants_len(&self, def: AdtDef) -> usize;
-
-    /// The name of a variant.
-    fn variant_name(&self, def: VariantDef) -> Symbol;
-    fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef>;
-
-    /// Evaluate constant as a target usize.
-    fn eval_target_usize(&self, cnst: &MirConst) -> Result<u64, Error>;
-    fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result<u64, Error>;
-
-    /// Create a new zero-sized constant.
-    fn try_new_const_zst(&self, ty: Ty) -> Result<MirConst, Error>;
-
-    /// Create a new constant that represents the given string value.
-    fn new_const_str(&self, value: &str) -> MirConst;
-
-    /// Create a new constant that represents the given boolean value.
-    fn new_const_bool(&self, value: bool) -> MirConst;
-
-    /// Create a new constant that represents the given value.
-    fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error>;
-    fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<TyConst, Error>;
-
-    /// Create a new type from the given kind.
-    fn new_rigid_ty(&self, kind: RigidTy) -> Ty;
-
-    /// Create a new box type, `Box<T>`, for the given inner type `T`.
-    fn new_box_ty(&self, ty: Ty) -> Ty;
-
-    /// Returns the type of given crate item.
-    fn def_ty(&self, item: DefId) -> Ty;
-
-    /// Returns the type of given definition instantiated with the given arguments.
-    fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty;
-
-    /// Returns literal value of a const as a string.
-    fn mir_const_pretty(&self, cnst: &MirConst) -> String;
-
-    /// `Span` of an item
-    fn span_of_an_item(&self, def_id: DefId) -> Span;
-
-    fn ty_const_pretty(&self, ct: TyConstId) -> String;
-
-    /// Obtain the representation of a type.
-    fn ty_pretty(&self, ty: Ty) -> String;
-
-    /// Obtain the representation of a type.
-    fn ty_kind(&self, ty: Ty) -> TyKind;
-
-    // Get the discriminant Ty for this Ty if there's one.
-    fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty;
-
-    /// Get the body of an Instance which is already monomorphized.
-    fn instance_body(&self, instance: InstanceDef) -> Option<Body>;
-
-    /// Get the instance type with generic instantiations applied and lifetimes erased.
-    fn instance_ty(&self, instance: InstanceDef) -> Ty;
-
-    /// Get the instantiation types.
-    fn instance_args(&self, def: InstanceDef) -> GenericArgs;
-
-    /// Get the instance.
-    fn instance_def_id(&self, instance: InstanceDef) -> DefId;
-
-    /// Get the instance mangled name.
-    fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol;
-
-    /// Check if this is an empty DropGlue shim.
-    fn is_empty_drop_shim(&self, def: InstanceDef) -> bool;
-
-    /// Check if this is an empty AsyncDropGlueCtor shim.
-    fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool;
-
-    /// Convert a non-generic crate item into an instance.
-    /// This function will panic if the item is generic.
-    fn mono_instance(&self, def_id: DefId) -> Instance;
-
-    /// Item requires monomorphization.
-    fn requires_monomorphization(&self, def_id: DefId) -> bool;
-
-    /// Resolve an instance from the given function definition and generic arguments.
-    fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
-
-    /// Resolve an instance for drop_in_place for the given type.
-    fn resolve_drop_in_place(&self, ty: Ty) -> Instance;
-
-    /// Resolve instance for a function pointer.
-    fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
-
-    /// Resolve instance for a closure with the requested type.
-    fn resolve_closure(
-        &self,
-        def: ClosureDef,
-        args: &GenericArgs,
-        kind: ClosureKind,
-    ) -> Option<Instance>;
-
-    /// Evaluate a static's initializer.
-    fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error>;
-
-    /// Try to evaluate an instance into a constant.
-    fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result<Allocation, Error>;
-
-    /// Retrieve global allocation for the given allocation ID.
-    fn global_alloc(&self, id: AllocId) -> GlobalAlloc;
-
-    /// Retrieve the id for the virtual table.
-    fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option<AllocId>;
-    fn krate(&self, def_id: DefId) -> Crate;
-    fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol;
-
-    /// Return information about the target machine.
-    fn target_info(&self) -> MachineInfo;
-
-    /// Get an instance ABI.
-    fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error>;
-
-    /// Get the ABI of a function pointer.
-    fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error>;
-
-    /// Get the layout of a type.
-    fn ty_layout(&self, ty: Ty) -> Result<Layout, Error>;
-
-    /// Get the layout shape.
-    fn layout_shape(&self, id: Layout) -> LayoutShape;
-
-    /// Get a debug string representation of a place.
-    fn place_pretty(&self, place: &Place) -> String;
-
-    /// Get the resulting type of binary operation.
-    fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty;
-
-    /// Get the resulting type of unary operation.
-    fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty;
-
-    /// Get all associated items of a definition.
-    fn associated_items(&self, def_id: DefId) -> AssocItems;
-}
-
-// A thread local variable that stores a pointer to the tables mapping between TyCtxt
-// datastructures and stable MIR datastructures
-scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>);
-
-pub fn run<F, T>(context: &dyn Context, f: F) -> Result<T, Error>
-where
-    F: FnOnce() -> T,
-{
-    if TLV.is_set() {
-        Err(Error::from("StableMIR already running"))
-    } else {
-        let ptr: *const () = (&raw const context) as _;
-        TLV.set(&Cell::new(ptr), || Ok(f()))
-    }
-}
-
-/// Execute the given function with access the compiler [Context].
-///
-/// I.e., This function will load the current context and calls a function with it.
-/// Do not nest these, as that will ICE.
-pub(crate) fn with<R>(f: impl FnOnce(&dyn Context) -> R) -> R {
-    assert!(TLV.is_set());
-    TLV.with(|tlv| {
-        let ptr = tlv.get();
-        assert!(!ptr.is_null());
-        f(unsafe { *(ptr as *const &dyn Context) })
-    })
-}
diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/stable_mir/src/crate_def.rs
deleted file mode 100644
index 75228135e4c..00000000000
--- a/compiler/stable_mir/src/crate_def.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-//! Module that define a common trait for things that represent a crate definition,
-//! such as, a function, a trait, an enum, and any other definitions.
-
-use serde::Serialize;
-
-use crate::ty::{GenericArgs, Span, Ty};
-use crate::{AssocItems, Crate, Symbol, with};
-
-/// A unique identification number for each item accessible for the current compilation unit.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
-pub struct DefId(pub(crate) usize);
-
-impl DefId {
-    /// Return fully qualified name of this definition
-    pub fn name(&self) -> Symbol {
-        with(|cx| cx.def_name(*self, false))
-    }
-
-    /// Return a trimmed name of this definition.
-    ///
-    /// This can be used to print more user friendly diagnostic messages.
-    ///
-    /// If a symbol name can only be imported from one place for a type, and as
-    /// long as it was not glob-imported anywhere in the current crate, we trim its
-    /// path and print only the name.
-    ///
-    /// For example, this function may shorten `std::vec::Vec` to just `Vec`,
-    /// as long as there is no other `Vec` importable anywhere.
-    pub fn trimmed_name(&self) -> Symbol {
-        with(|cx| cx.def_name(*self, true))
-    }
-}
-
-/// A trait for retrieving information about a particular definition.
-///
-/// Implementors must provide the implementation of `def_id` which will be used to retrieve
-/// information about a crate's definition.
-pub trait CrateDef {
-    /// Retrieve the unique identifier for the current definition.
-    fn def_id(&self) -> DefId;
-
-    /// Return the fully qualified name of the current definition.
-    ///
-    /// See [`DefId::name`] for more details
-    fn name(&self) -> Symbol {
-        self.def_id().name()
-    }
-
-    /// Return a trimmed name of this definition.
-    ///
-    /// See [`DefId::trimmed_name`] for more details
-    fn trimmed_name(&self) -> Symbol {
-        self.def_id().trimmed_name()
-    }
-
-    /// Return information about the crate where this definition is declared.
-    ///
-    /// This will return the crate number and its name.
-    fn krate(&self) -> Crate {
-        let def_id = self.def_id();
-        with(|cx| cx.krate(def_id))
-    }
-
-    /// Return the span of this definition.
-    fn span(&self) -> Span {
-        let def_id = self.def_id();
-        with(|cx| cx.span_of_an_item(def_id))
-    }
-
-    /// Return registered tool attributes with the given attribute name.
-    ///
-    /// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool
-    /// attributes will simply return an empty list.
-    ///
-    /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`.
-    /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
-    fn tool_attrs(&self, attr: &[Symbol]) -> Vec<Attribute> {
-        let def_id = self.def_id();
-        with(|cx| cx.tool_attrs(def_id, attr))
-    }
-
-    /// Return all tool attributes of this definition.
-    fn all_tool_attrs(&self) -> Vec<Attribute> {
-        let def_id = self.def_id();
-        with(|cx| cx.all_tool_attrs(def_id))
-    }
-}
-
-/// A trait that can be used to retrieve a definition's type.
-///
-/// Note that not every CrateDef has a type `Ty`. They should not implement this trait.
-pub trait CrateDefType: CrateDef {
-    /// Returns the type of this crate item.
-    fn ty(&self) -> Ty {
-        with(|cx| cx.def_ty(self.def_id()))
-    }
-
-    /// Retrieve the type of this definition by instantiating and normalizing it with `args`.
-    ///
-    /// This will panic if instantiation fails.
-    fn ty_with_args(&self, args: &GenericArgs) -> Ty {
-        with(|cx| cx.def_ty_with_args(self.def_id(), args))
-    }
-}
-
-/// A trait for retrieving all items from a definition within a crate.
-pub trait CrateDefItems: CrateDef {
-    /// Retrieve all associated items from a definition.
-    fn associated_items(&self) -> AssocItems {
-        with(|cx| cx.associated_items(self.def_id()))
-    }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct Attribute {
-    value: String,
-    span: Span,
-}
-
-impl Attribute {
-    pub fn new(value: String, span: Span) -> Attribute {
-        Attribute { value, span }
-    }
-
-    /// Get the span of this attribute.
-    pub fn span(&self) -> Span {
-        self.span
-    }
-
-    /// Get the string representation of this attribute.
-    pub fn as_str(&self) -> &str {
-        &self.value
-    }
-}
-
-macro_rules! crate_def {
-    ( $(#[$attr:meta])*
-      $vis:vis $name:ident $(;)?
-    ) => {
-        $(#[$attr])*
-        #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
-        $vis struct $name(pub DefId);
-
-        impl CrateDef for $name {
-            fn def_id(&self) -> DefId {
-                self.0
-            }
-        }
-    };
-}
-
-macro_rules! crate_def_with_ty {
-    ( $(#[$attr:meta])*
-      $vis:vis $name:ident $(;)?
-    ) => {
-        $(#[$attr])*
-        #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
-        $vis struct $name(pub DefId);
-
-        impl CrateDef for $name {
-            fn def_id(&self) -> DefId {
-                self.0
-            }
-        }
-
-        impl CrateDefType for $name {}
-    };
-}
-
-macro_rules! impl_crate_def_items {
-    ( $name:ident $(;)? ) => {
-        impl CrateDefItems for $name {}
-    };
-}
diff --git a/compiler/stable_mir/src/error.rs b/compiler/stable_mir/src/error.rs
deleted file mode 100644
index 050752e41eb..00000000000
--- a/compiler/stable_mir/src/error.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-//! When things go wrong, we need some error handling.
-//! There are a few different types of errors in StableMIR:
-//!
-//! - [CompilerError]: This represents errors that can be raised when invoking the compiler.
-//! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.
-
-use std::fmt::{Debug, Display, Formatter};
-use std::{fmt, io};
-
-macro_rules! error {
-     ($fmt: literal $(,)?) => { Error(format!($fmt)) };
-     ($fmt: literal, $($arg:tt)*) => { Error(format!($fmt, $($arg)*)) };
-}
-
-pub(crate) use error;
-
-/// An error type used to represent an error that has already been reported by the compiler.
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub enum CompilerError<T> {
-    /// Compilation failed, either due to normal errors or ICE.
-    Failed,
-    /// Compilation was interrupted.
-    Interrupted(T),
-    /// Compilation skipped. This happens when users invoke rustc to retrieve information such as
-    /// --version.
-    Skipped,
-}
-
-/// A generic error to represent an API request that cannot be fulfilled.
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Error(pub(crate) String);
-
-impl Error {
-    pub fn new(msg: String) -> Self {
-        Self(msg)
-    }
-}
-
-impl From<&str> for Error {
-    fn from(value: &str) -> Self {
-        Self(value.into())
-    }
-}
-
-impl Display for Error {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        Display::fmt(&self.0, f)
-    }
-}
-
-impl<T> Display for CompilerError<T>
-where
-    T: Display,
-{
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self {
-            CompilerError::Failed => write!(f, "Compilation Failed"),
-            CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason}"),
-            CompilerError::Skipped => write!(f, "Compilation Skipped"),
-        }
-    }
-}
-
-impl<T> Debug for CompilerError<T>
-where
-    T: Debug,
-{
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self {
-            CompilerError::Failed => write!(f, "Compilation Failed"),
-            CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason:?}"),
-            CompilerError::Skipped => write!(f, "Compilation Skipped"),
-        }
-    }
-}
-
-impl std::error::Error for Error {}
-
-impl<T> std::error::Error for CompilerError<T> where T: Display + Debug {}
-
-impl From<io::Error> for Error {
-    fn from(value: io::Error) -> Self {
-        Error(value.to_string())
-    }
-}
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index df90d3e5a08..cc0fb52433d 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -1,231 +1,7 @@
-//! The WIP stable interface to rustc internals.
+//! We've temporarily moved the `stable_mir` implementation to [`rustc_smir::stable_mir`],
+//! during refactoring to break the circular dependency between `rustc_smir` and `stable_mir`,
 //!
-//! For more information see <https://github.com/rust-lang/project-stable-mir>
-//!
-//! # Note
-//!
-//! This API is still completely unstable and subject to change.
-
-#![doc(
-    html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
-    test(attr(allow(unused_variables), deny(warnings)))
-)]
-//!
-//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to
-//! interact with the compiler.
-//!
-//! The goal is to eventually be published on
-//! [crates.io](https://crates.io).
-
-use std::fmt::Debug;
-use std::{fmt, io};
-
-use serde::Serialize;
-
-use crate::compiler_interface::with;
-pub use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId};
-pub use crate::error::*;
-use crate::mir::mono::StaticDef;
-use crate::mir::{Body, Mutability};
-use crate::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
-
-pub mod abi;
-#[macro_use]
-pub mod crate_def;
-pub mod compiler_interface;
-#[macro_use]
-pub mod error;
-pub mod mir;
-pub mod target;
-pub mod ty;
-pub mod visitor;
-
-/// Use String for now but we should replace it.
-pub type Symbol = String;
-
-/// The number that identifies a crate.
-pub type CrateNum = usize;
-
-impl Debug for DefId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("DefId").field("id", &self.0).field("name", &self.name()).finish()
-    }
-}
-
-impl IndexedVal for DefId {
-    fn to_val(index: usize) -> Self {
-        DefId(index)
-    }
-
-    fn to_index(&self) -> usize {
-        self.0
-    }
-}
-
-/// A list of crate items.
-pub type CrateItems = Vec<CrateItem>;
-
-/// A list of trait decls.
-pub type TraitDecls = Vec<TraitDef>;
-
-/// A list of impl trait decls.
-pub type ImplTraitDecls = Vec<ImplDef>;
-
-/// A list of associated items.
-pub type AssocItems = Vec<AssocItem>;
-
-/// Holds information about a crate.
-#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
-pub struct Crate {
-    pub id: CrateNum,
-    pub name: Symbol,
-    pub is_local: bool,
-}
-
-impl Crate {
-    /// The list of foreign modules in this crate.
-    pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> {
-        with(|cx| cx.foreign_modules(self.id))
-    }
-
-    /// The list of traits declared in this crate.
-    pub fn trait_decls(&self) -> TraitDecls {
-        with(|cx| cx.trait_decls(self.id))
-    }
-
-    /// The list of trait implementations in this crate.
-    pub fn trait_impls(&self) -> ImplTraitDecls {
-        with(|cx| cx.trait_impls(self.id))
-    }
-
-    /// Return a list of function definitions from this crate independent on their visibility.
-    pub fn fn_defs(&self) -> Vec<FnDef> {
-        with(|cx| cx.crate_functions(self.id))
-    }
-
-    /// Return a list of static items defined in this crate independent on their visibility.
-    pub fn statics(&self) -> Vec<StaticDef> {
-        with(|cx| cx.crate_statics(self.id))
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
-pub enum ItemKind {
-    Fn,
-    Static,
-    Const,
-    Ctor(CtorKind),
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
-pub enum CtorKind {
-    Const,
-    Fn,
-}
-
-pub type Filename = String;
-
-crate_def_with_ty! {
-    /// Holds information about an item in a crate.
-    #[derive(Serialize)]
-    pub CrateItem;
-}
-
-impl CrateItem {
-    /// This will return the body of an item or panic if it's not available.
-    pub fn expect_body(&self) -> mir::Body {
-        with(|cx| cx.mir_body(self.0))
-    }
-
-    /// Return the body of an item if available.
-    pub fn body(&self) -> Option<mir::Body> {
-        with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
-    }
-
-    /// Check if a body is available for this item.
-    pub fn has_body(&self) -> bool {
-        with(|cx| cx.has_body(self.0))
-    }
-
-    pub fn span(&self) -> Span {
-        with(|cx| cx.span_of_an_item(self.0))
-    }
-
-    pub fn kind(&self) -> ItemKind {
-        with(|cx| cx.item_kind(*self))
-    }
-
-    pub fn requires_monomorphization(&self) -> bool {
-        with(|cx| cx.requires_monomorphization(self.0))
-    }
-
-    pub fn ty(&self) -> Ty {
-        with(|cx| cx.def_ty(self.0))
-    }
-
-    pub fn is_foreign_item(&self) -> bool {
-        with(|cx| cx.is_foreign_item(self.0))
-    }
-
-    /// Emit MIR for this item body.
-    pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
-        self.body()
-            .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
-            .dump(w, &self.name())
-    }
-}
-
-/// Return the function where execution starts if the current
-/// crate defines that. This is usually `main`, but could be
-/// `start` if the crate is a no-std crate.
-pub fn entry_fn() -> Option<CrateItem> {
-    with(|cx| cx.entry_fn())
-}
-
-/// Access to the local crate.
-pub fn local_crate() -> Crate {
-    with(|cx| cx.local_crate())
-}
-
-/// Try to find a crate or crates if multiple crates exist from given name.
-pub fn find_crates(name: &str) -> Vec<Crate> {
-    with(|cx| cx.find_crates(name))
-}
-
-/// Try to find a crate with the given name.
-pub fn external_crates() -> Vec<Crate> {
-    with(|cx| cx.external_crates())
-}
-
-/// Retrieve all items in the local crate that have a MIR associated with them.
-pub fn all_local_items() -> CrateItems {
-    with(|cx| cx.all_local_items())
-}
-
-pub fn all_trait_decls() -> TraitDecls {
-    with(|cx| cx.all_trait_decls())
-}
-
-pub fn all_trait_impls() -> ImplTraitDecls {
-    with(|cx| cx.all_trait_impls())
-}
-
-/// A type that provides internal information but that can still be used for debug purpose.
-#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
-pub struct Opaque(String);
-
-impl std::fmt::Display for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
-
-impl std::fmt::Debug for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
+//! This is a transitional measure as described in [PR #139319](https://github.com/rust-lang/rust/pull/139319).
+//! Once the refactoring is complete, the `stable_mir` implementation will be moved back here.
 
-pub fn opaque<T: Debug>(value: &T) -> Opaque {
-    Opaque(format!("{value:?}"))
-}
+pub use rustc_smir::stable_mir::*;
diff --git a/compiler/stable_mir/src/mir.rs b/compiler/stable_mir/src/mir.rs
deleted file mode 100644
index 413b5152bb3..00000000000
--- a/compiler/stable_mir/src/mir.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-pub mod alloc;
-mod body;
-pub mod mono;
-pub mod pretty;
-pub mod visit;
-
-pub use body::*;
-pub use visit::{MirVisitor, MutMirVisitor};
diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/stable_mir/src/mir/alloc.rs
deleted file mode 100644
index 023807b76ae..00000000000
--- a/compiler/stable_mir/src/mir/alloc.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-//! This module provides methods to retrieve allocation information, such as static variables.
-
-use std::io::Read;
-
-use serde::Serialize;
-
-use crate::mir::mono::{Instance, StaticDef};
-use crate::target::{Endian, MachineInfo};
-use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
-use crate::{Error, with};
-
-/// An allocation in the SMIR global memory can be either a function pointer,
-/// a static, or a "real" allocation with some data in it.
-#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
-pub enum GlobalAlloc {
-    /// The alloc ID is used as a function pointer.
-    Function(Instance),
-    /// This alloc ID points to a symbolic (not-reified) vtable.
-    /// The `None` trait ref is used to represent auto traits.
-    VTable(Ty, Option<Binder<ExistentialTraitRef>>),
-    /// The alloc ID points to a "lazy" static variable that did not get computed (yet).
-    /// This is also used to break the cycle in recursive statics.
-    Static(StaticDef),
-    /// The alloc ID points to memory.
-    Memory(Allocation),
-}
-
-impl From<AllocId> for GlobalAlloc {
-    fn from(value: AllocId) -> Self {
-        with(|cx| cx.global_alloc(value))
-    }
-}
-
-impl GlobalAlloc {
-    /// Retrieve the allocation id for a global allocation if it exists.
-    ///
-    /// For `[GlobalAlloc::VTable]`, this will return the allocation for the VTable of the given
-    /// type for the optional trait if the type implements the trait.
-    ///
-    /// This method will always return `None` for allocations other than `[GlobalAlloc::VTable]`.
-    pub fn vtable_allocation(&self) -> Option<AllocId> {
-        with(|cx| cx.vtable_allocation(self))
-    }
-}
-
-/// A unique identification number for each provenance
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
-pub struct AllocId(usize);
-
-impl IndexedVal for AllocId {
-    fn to_val(index: usize) -> Self {
-        AllocId(index)
-    }
-    fn to_index(&self) -> usize {
-        self.0
-    }
-}
-
-/// Utility function used to read an allocation data into a unassigned integer.
-pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
-    let mut buf = [0u8; size_of::<u128>()];
-    match MachineInfo::target_endianness() {
-        Endian::Little => {
-            bytes.read_exact(&mut buf[..bytes.len()])?;
-            Ok(u128::from_le_bytes(buf))
-        }
-        Endian::Big => {
-            bytes.read_exact(&mut buf[16 - bytes.len()..])?;
-            Ok(u128::from_be_bytes(buf))
-        }
-    }
-}
-
-/// Utility function used to read an allocation data into an assigned integer.
-pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result<i128, Error> {
-    let mut buf = [0u8; size_of::<i128>()];
-    match MachineInfo::target_endianness() {
-        Endian::Little => {
-            bytes.read_exact(&mut buf[..bytes.len()])?;
-            Ok(i128::from_le_bytes(buf))
-        }
-        Endian::Big => {
-            bytes.read_exact(&mut buf[16 - bytes.len()..])?;
-            Ok(i128::from_be_bytes(buf))
-        }
-    }
-}
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
deleted file mode 100644
index 2a1c163de3c..00000000000
--- a/compiler/stable_mir/src/mir/body.rs
+++ /dev/null
@@ -1,1108 +0,0 @@
-use std::io;
-
-use serde::Serialize;
-
-use crate::compiler_interface::with;
-use crate::mir::pretty::function_body;
-use crate::ty::{
-    AdtDef, ClosureDef, CoroutineClosureDef, CoroutineDef, GenericArgs, MirConst, Movability,
-    Region, RigidTy, Ty, TyConst, TyKind, VariantIdx,
-};
-use crate::{Error, Opaque, Span, Symbol};
-
-/// The SMIR representation of a single function.
-#[derive(Clone, Debug, Serialize)]
-pub struct Body {
-    pub blocks: Vec<BasicBlock>,
-
-    /// Declarations of locals within the function.
-    ///
-    /// The first local is the return value pointer, followed by `arg_count`
-    /// locals for the function arguments, followed by any user-declared
-    /// variables and temporaries.
-    pub(super) locals: LocalDecls,
-
-    /// The number of arguments this function takes.
-    pub(super) arg_count: usize,
-
-    /// Debug information pertaining to user variables, including captures.
-    pub var_debug_info: Vec<VarDebugInfo>,
-
-    /// Mark an argument (which must be a tuple) as getting passed as its individual components.
-    ///
-    /// This is used for the "rust-call" ABI such as closures.
-    pub(super) spread_arg: Option<Local>,
-
-    /// The span that covers the entire function body.
-    pub span: Span,
-}
-
-pub type BasicBlockIdx = usize;
-
-impl Body {
-    /// Constructs a `Body`.
-    ///
-    /// A constructor is required to build a `Body` from outside the crate
-    /// because the `arg_count` and `locals` fields are private.
-    pub fn new(
-        blocks: Vec<BasicBlock>,
-        locals: LocalDecls,
-        arg_count: usize,
-        var_debug_info: Vec<VarDebugInfo>,
-        spread_arg: Option<Local>,
-        span: Span,
-    ) -> Self {
-        // If locals doesn't contain enough entries, it can lead to panics in
-        // `ret_local`, `arg_locals`, and `inner_locals`.
-        assert!(
-            locals.len() > arg_count,
-            "A Body must contain at least a local for the return value and each of the function's arguments"
-        );
-        Self { blocks, locals, arg_count, var_debug_info, spread_arg, span }
-    }
-
-    /// Return local that holds this function's return value.
-    pub fn ret_local(&self) -> &LocalDecl {
-        &self.locals[RETURN_LOCAL]
-    }
-
-    /// Locals in `self` that correspond to this function's arguments.
-    pub fn arg_locals(&self) -> &[LocalDecl] {
-        &self.locals[1..][..self.arg_count]
-    }
-
-    /// Inner locals for this function. These are the locals that are
-    /// neither the return local nor the argument locals.
-    pub fn inner_locals(&self) -> &[LocalDecl] {
-        &self.locals[self.arg_count + 1..]
-    }
-
-    /// Returns a mutable reference to the local that holds this function's return value.
-    pub(crate) fn ret_local_mut(&mut self) -> &mut LocalDecl {
-        &mut self.locals[RETURN_LOCAL]
-    }
-
-    /// Returns a mutable slice of locals corresponding to this function's arguments.
-    pub(crate) fn arg_locals_mut(&mut self) -> &mut [LocalDecl] {
-        &mut self.locals[1..][..self.arg_count]
-    }
-
-    /// Returns a mutable slice of inner locals for this function.
-    /// Inner locals are those that are neither the return local nor the argument locals.
-    pub(crate) fn inner_locals_mut(&mut self) -> &mut [LocalDecl] {
-        &mut self.locals[self.arg_count + 1..]
-    }
-
-    /// Convenience function to get all the locals in this function.
-    ///
-    /// Locals are typically accessed via the more specific methods `ret_local`,
-    /// `arg_locals`, and `inner_locals`.
-    pub fn locals(&self) -> &[LocalDecl] {
-        &self.locals
-    }
-
-    /// Get the local declaration for this local.
-    pub fn local_decl(&self, local: Local) -> Option<&LocalDecl> {
-        self.locals.get(local)
-    }
-
-    /// Get an iterator for all local declarations.
-    pub fn local_decls(&self) -> impl Iterator<Item = (Local, &LocalDecl)> {
-        self.locals.iter().enumerate()
-    }
-
-    /// Emit the body using the provided name for the signature.
-    pub fn dump<W: io::Write>(&self, w: &mut W, fn_name: &str) -> io::Result<()> {
-        function_body(w, self, fn_name)
-    }
-
-    pub fn spread_arg(&self) -> Option<Local> {
-        self.spread_arg
-    }
-}
-
-type LocalDecls = Vec<LocalDecl>;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct LocalDecl {
-    pub ty: Ty,
-    pub span: Span,
-    pub mutability: Mutability,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
-pub struct BasicBlock {
-    pub statements: Vec<Statement>,
-    pub terminator: Terminator,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct Terminator {
-    pub kind: TerminatorKind,
-    pub span: Span,
-}
-
-impl Terminator {
-    pub fn successors(&self) -> Successors {
-        self.kind.successors()
-    }
-}
-
-pub type Successors = Vec<BasicBlockIdx>;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum TerminatorKind {
-    Goto {
-        target: BasicBlockIdx,
-    },
-    SwitchInt {
-        discr: Operand,
-        targets: SwitchTargets,
-    },
-    Resume,
-    Abort,
-    Return,
-    Unreachable,
-    Drop {
-        place: Place,
-        target: BasicBlockIdx,
-        unwind: UnwindAction,
-    },
-    Call {
-        func: Operand,
-        args: Vec<Operand>,
-        destination: Place,
-        target: Option<BasicBlockIdx>,
-        unwind: UnwindAction,
-    },
-    Assert {
-        cond: Operand,
-        expected: bool,
-        msg: AssertMessage,
-        target: BasicBlockIdx,
-        unwind: UnwindAction,
-    },
-    InlineAsm {
-        template: String,
-        operands: Vec<InlineAsmOperand>,
-        options: String,
-        line_spans: String,
-        destination: Option<BasicBlockIdx>,
-        unwind: UnwindAction,
-    },
-}
-
-impl TerminatorKind {
-    pub fn successors(&self) -> Successors {
-        use self::TerminatorKind::*;
-        match *self {
-            Call { target: Some(t), unwind: UnwindAction::Cleanup(u), .. }
-            | Drop { target: t, unwind: UnwindAction::Cleanup(u), .. }
-            | Assert { target: t, unwind: UnwindAction::Cleanup(u), .. }
-            | InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(u), .. } => {
-                vec![t, u]
-            }
-            Goto { target: t }
-            | Call { target: None, unwind: UnwindAction::Cleanup(t), .. }
-            | Call { target: Some(t), unwind: _, .. }
-            | Drop { target: t, unwind: _, .. }
-            | Assert { target: t, unwind: _, .. }
-            | InlineAsm { destination: None, unwind: UnwindAction::Cleanup(t), .. }
-            | InlineAsm { destination: Some(t), unwind: _, .. } => {
-                vec![t]
-            }
-
-            Return
-            | Resume
-            | Abort
-            | Unreachable
-            | Call { target: None, unwind: _, .. }
-            | InlineAsm { destination: None, unwind: _, .. } => {
-                vec![]
-            }
-            SwitchInt { ref targets, .. } => targets.all_targets(),
-        }
-    }
-
-    pub fn unwind(&self) -> Option<&UnwindAction> {
-        match *self {
-            TerminatorKind::Goto { .. }
-            | TerminatorKind::Return
-            | TerminatorKind::Unreachable
-            | TerminatorKind::Resume
-            | TerminatorKind::Abort
-            | TerminatorKind::SwitchInt { .. } => None,
-            TerminatorKind::Call { ref unwind, .. }
-            | TerminatorKind::Assert { ref unwind, .. }
-            | TerminatorKind::Drop { ref unwind, .. }
-            | TerminatorKind::InlineAsm { ref unwind, .. } => Some(unwind),
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct InlineAsmOperand {
-    pub in_value: Option<Operand>,
-    pub out_place: Option<Place>,
-    // This field has a raw debug representation of MIR's InlineAsmOperand.
-    // For now we care about place/operand + the rest in a debug format.
-    pub raw_rpr: String,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum UnwindAction {
-    Continue,
-    Unreachable,
-    Terminate,
-    Cleanup(BasicBlockIdx),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum AssertMessage {
-    BoundsCheck { len: Operand, index: Operand },
-    Overflow(BinOp, Operand, Operand),
-    OverflowNeg(Operand),
-    DivisionByZero(Operand),
-    RemainderByZero(Operand),
-    ResumedAfterReturn(CoroutineKind),
-    ResumedAfterPanic(CoroutineKind),
-    MisalignedPointerDereference { required: Operand, found: Operand },
-    NullPointerDereference,
-}
-
-impl AssertMessage {
-    pub fn description(&self) -> Result<&'static str, Error> {
-        match self {
-            AssertMessage::Overflow(BinOp::Add, _, _) => Ok("attempt to add with overflow"),
-            AssertMessage::Overflow(BinOp::Sub, _, _) => Ok("attempt to subtract with overflow"),
-            AssertMessage::Overflow(BinOp::Mul, _, _) => Ok("attempt to multiply with overflow"),
-            AssertMessage::Overflow(BinOp::Div, _, _) => Ok("attempt to divide with overflow"),
-            AssertMessage::Overflow(BinOp::Rem, _, _) => {
-                Ok("attempt to calculate the remainder with overflow")
-            }
-            AssertMessage::OverflowNeg(_) => Ok("attempt to negate with overflow"),
-            AssertMessage::Overflow(BinOp::Shr, _, _) => Ok("attempt to shift right with overflow"),
-            AssertMessage::Overflow(BinOp::Shl, _, _) => Ok("attempt to shift left with overflow"),
-            AssertMessage::Overflow(op, _, _) => Err(error!("`{:?}` cannot overflow", op)),
-            AssertMessage::DivisionByZero(_) => Ok("attempt to divide by zero"),
-            AssertMessage::RemainderByZero(_) => {
-                Ok("attempt to calculate the remainder with a divisor of zero")
-            }
-            AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
-                Ok("coroutine resumed after completion")
-            }
-            AssertMessage::ResumedAfterReturn(CoroutineKind::Desugared(
-                CoroutineDesugaring::Async,
-                _,
-            )) => Ok("`async fn` resumed after completion"),
-            AssertMessage::ResumedAfterReturn(CoroutineKind::Desugared(
-                CoroutineDesugaring::Gen,
-                _,
-            )) => Ok("`async gen fn` resumed after completion"),
-            AssertMessage::ResumedAfterReturn(CoroutineKind::Desugared(
-                CoroutineDesugaring::AsyncGen,
-                _,
-            )) => Ok("`gen fn` should just keep returning `AssertMessage::None` after completion"),
-            AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
-                Ok("coroutine resumed after panicking")
-            }
-            AssertMessage::ResumedAfterPanic(CoroutineKind::Desugared(
-                CoroutineDesugaring::Async,
-                _,
-            )) => Ok("`async fn` resumed after panicking"),
-            AssertMessage::ResumedAfterPanic(CoroutineKind::Desugared(
-                CoroutineDesugaring::Gen,
-                _,
-            )) => Ok("`async gen fn` resumed after panicking"),
-            AssertMessage::ResumedAfterPanic(CoroutineKind::Desugared(
-                CoroutineDesugaring::AsyncGen,
-                _,
-            )) => Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking"),
-
-            AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"),
-            AssertMessage::MisalignedPointerDereference { .. } => {
-                Ok("misaligned pointer dereference")
-            }
-            AssertMessage::NullPointerDereference => Ok("null pointer dereference occurred"),
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum BinOp {
-    Add,
-    AddUnchecked,
-    Sub,
-    SubUnchecked,
-    Mul,
-    MulUnchecked,
-    Div,
-    Rem,
-    BitXor,
-    BitAnd,
-    BitOr,
-    Shl,
-    ShlUnchecked,
-    Shr,
-    ShrUnchecked,
-    Eq,
-    Lt,
-    Le,
-    Ne,
-    Ge,
-    Gt,
-    Cmp,
-    Offset,
-}
-
-impl BinOp {
-    /// Return the type of this operation for the given input Ty.
-    /// This function does not perform type checking, and it currently doesn't handle SIMD.
-    pub fn ty(&self, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
-        with(|ctx| ctx.binop_ty(*self, lhs_ty, rhs_ty))
-    }
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum UnOp {
-    Not,
-    Neg,
-    PtrMetadata,
-}
-
-impl UnOp {
-    /// Return the type of this operation for the given input Ty.
-    /// This function does not perform type checking, and it currently doesn't handle SIMD.
-    pub fn ty(&self, arg_ty: Ty) -> Ty {
-        with(|ctx| ctx.unop_ty(*self, arg_ty))
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum CoroutineKind {
-    Desugared(CoroutineDesugaring, CoroutineSource),
-    Coroutine(Movability),
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum CoroutineSource {
-    Block,
-    Closure,
-    Fn,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum CoroutineDesugaring {
-    Async,
-
-    Gen,
-
-    AsyncGen,
-}
-
-pub(crate) type LocalDefId = Opaque;
-/// The rustc coverage data structures are heavily tied to internal details of the
-/// coverage implementation that are likely to change, and are unlikely to be
-/// useful to third-party tools for the foreseeable future.
-pub(crate) type Coverage = Opaque;
-
-/// The FakeReadCause describes the type of pattern why a FakeRead statement exists.
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum FakeReadCause {
-    ForMatchGuard,
-    ForMatchedPlace(LocalDefId),
-    ForGuardBinding,
-    ForLet(LocalDefId),
-    ForIndex,
-}
-
-/// Describes what kind of retag is to be performed
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
-pub enum RetagKind {
-    FnEntry,
-    TwoPhase,
-    Raw,
-    Default,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
-pub enum Variance {
-    Covariant,
-    Invariant,
-    Contravariant,
-    Bivariant,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct CopyNonOverlapping {
-    pub src: Operand,
-    pub dst: Operand,
-    pub count: Operand,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum NonDivergingIntrinsic {
-    Assume(Operand),
-    CopyNonOverlapping(CopyNonOverlapping),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct Statement {
-    pub kind: StatementKind,
-    pub span: Span,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum StatementKind {
-    Assign(Place, Rvalue),
-    FakeRead(FakeReadCause, Place),
-    SetDiscriminant { place: Place, variant_index: VariantIdx },
-    Deinit(Place),
-    StorageLive(Local),
-    StorageDead(Local),
-    Retag(RetagKind, Place),
-    PlaceMention(Place),
-    AscribeUserType { place: Place, projections: UserTypeProjection, variance: Variance },
-    Coverage(Coverage),
-    Intrinsic(NonDivergingIntrinsic),
-    ConstEvalCounter,
-    Nop,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum Rvalue {
-    /// Creates a pointer with the indicated mutability to the place.
-    ///
-    /// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
-    /// `&raw v` or `addr_of!(v)`.
-    AddressOf(RawPtrKind, Place),
-
-    /// Creates an aggregate value, like a tuple or struct.
-    ///
-    /// This is needed because dataflow analysis needs to distinguish
-    /// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
-    /// has a destructor.
-    ///
-    /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Coroutine`. After
-    /// coroutine lowering, `Coroutine` aggregate kinds are disallowed too.
-    Aggregate(AggregateKind, Vec<Operand>),
-
-    /// * `Offset` has the same semantics as `<*const T>::offset`, except that the second
-    ///   parameter may be a `usize` as well.
-    /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
-    ///   raw pointers, or function pointers and return a `bool`. The types of the operands must be
-    ///   matching, up to the usual caveat of the lifetimes in function pointers.
-    /// * Left and right shift operations accept signed or unsigned integers not necessarily of the
-    ///   same type and return a value of the same type as their LHS. Like in Rust, the RHS is
-    ///   truncated as needed.
-    /// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
-    ///   types and return a value of that type.
-    /// * The remaining operations accept signed integers, unsigned integers, or floats with
-    ///   matching types and return a value of that type.
-    BinaryOp(BinOp, Operand, Operand),
-
-    /// Performs essentially all of the casts that can be performed via `as`.
-    ///
-    /// This allows for casts from/to a variety of types.
-    Cast(CastKind, Operand, Ty),
-
-    /// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
-    ///
-    /// For addition, subtraction, and multiplication on integers the error condition is set when
-    /// the infinite precision result would not be equal to the actual result.
-    CheckedBinaryOp(BinOp, Operand, Operand),
-
-    /// A CopyForDeref is equivalent to a read from a place.
-    /// When such a read happens, it is guaranteed that the only use of the returned value is a
-    /// deref operation, immediately followed by one or more projections.
-    CopyForDeref(Place),
-
-    /// Computes the discriminant of the place, returning it as an integer.
-    /// Returns zero for types without discriminant.
-    ///
-    /// The validity requirements for the underlying value are undecided for this rvalue, see
-    /// [#91095]. Note too that the value of the discriminant is not the same thing as the
-    /// variant index;
-    ///
-    /// [#91095]: https://github.com/rust-lang/rust/issues/91095
-    Discriminant(Place),
-
-    /// Yields the length of the place, as a `usize`.
-    ///
-    /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
-    /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
-    /// ill-formed for places of other types.
-    Len(Place),
-
-    /// Creates a reference to the place.
-    Ref(Region, BorrowKind, Place),
-
-    /// Creates an array where each element is the value of the operand.
-    ///
-    /// This is the cause of a bug in the case where the repetition count is zero because the value
-    /// is not dropped, see [#74836].
-    ///
-    /// Corresponds to source code like `[x; 32]`.
-    ///
-    /// [#74836]: https://github.com/rust-lang/rust/issues/74836
-    Repeat(Operand, TyConst),
-
-    /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
-    ///
-    /// This is different from a normal transmute because dataflow analysis will treat the box as
-    /// initialized but its content as uninitialized. Like other pointer casts, this in general
-    /// affects alias analysis.
-    ShallowInitBox(Operand, Ty),
-
-    /// Creates a pointer/reference to the given thread local.
-    ///
-    /// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a
-    /// `*const T`, and if neither of those apply a `&T`.
-    ///
-    /// **Note:** This is a runtime operation that actually executes code and is in this sense more
-    /// like a function call. Also, eliminating dead stores of this rvalue causes `fn main() {}` to
-    /// SIGILL for some reason that I (JakobDegen) never got a chance to look into.
-    ///
-    /// **Needs clarification**: Are there weird additional semantics here related to the runtime
-    /// nature of this operation?
-    ThreadLocalRef(crate::CrateItem),
-
-    /// Computes a value as described by the operation.
-    NullaryOp(NullOp, Ty),
-
-    /// Exactly like `BinaryOp`, but less operands.
-    ///
-    /// Also does two's-complement arithmetic. Negation requires a signed integer or a float;
-    /// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds
-    /// return a value with the same type as their operand.
-    UnaryOp(UnOp, Operand),
-
-    /// Yields the operand unchanged
-    Use(Operand),
-}
-
-impl Rvalue {
-    pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
-        match self {
-            Rvalue::Use(operand) => operand.ty(locals),
-            Rvalue::Repeat(operand, count) => {
-                Ok(Ty::new_array_with_const_len(operand.ty(locals)?, count.clone()))
-            }
-            Rvalue::ThreadLocalRef(did) => Ok(did.ty()),
-            Rvalue::Ref(reg, bk, place) => {
-                let place_ty = place.ty(locals)?;
-                Ok(Ty::new_ref(reg.clone(), place_ty, bk.to_mutable_lossy()))
-            }
-            Rvalue::AddressOf(mutability, place) => {
-                let place_ty = place.ty(locals)?;
-                Ok(Ty::new_ptr(place_ty, mutability.to_mutable_lossy()))
-            }
-            Rvalue::Len(..) => Ok(Ty::usize_ty()),
-            Rvalue::Cast(.., ty) => Ok(*ty),
-            Rvalue::BinaryOp(op, lhs, rhs) => {
-                let lhs_ty = lhs.ty(locals)?;
-                let rhs_ty = rhs.ty(locals)?;
-                Ok(op.ty(lhs_ty, rhs_ty))
-            }
-            Rvalue::CheckedBinaryOp(op, lhs, rhs) => {
-                let lhs_ty = lhs.ty(locals)?;
-                let rhs_ty = rhs.ty(locals)?;
-                let ty = op.ty(lhs_ty, rhs_ty);
-                Ok(Ty::new_tuple(&[ty, Ty::bool_ty()]))
-            }
-            Rvalue::UnaryOp(op, operand) => {
-                let arg_ty = operand.ty(locals)?;
-                Ok(op.ty(arg_ty))
-            }
-            Rvalue::Discriminant(place) => {
-                let place_ty = place.ty(locals)?;
-                place_ty
-                    .kind()
-                    .discriminant_ty()
-                    .ok_or_else(|| error!("Expected a `RigidTy` but found: {place_ty:?}"))
-            }
-            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
-                Ok(Ty::usize_ty())
-            }
-            Rvalue::NullaryOp(NullOp::ContractChecks, _)
-            | Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()),
-            Rvalue::Aggregate(ak, ops) => match *ak {
-                AggregateKind::Array(ty) => Ty::try_new_array(ty, ops.len() as u64),
-                AggregateKind::Tuple => Ok(Ty::new_tuple(
-                    &ops.iter().map(|op| op.ty(locals)).collect::<Result<Vec<_>, _>>()?,
-                )),
-                AggregateKind::Adt(def, _, ref args, _, _) => Ok(def.ty_with_args(args)),
-                AggregateKind::Closure(def, ref args) => Ok(Ty::new_closure(def, args.clone())),
-                AggregateKind::Coroutine(def, ref args, mov) => {
-                    Ok(Ty::new_coroutine(def, args.clone(), mov))
-                }
-                AggregateKind::CoroutineClosure(def, ref args) => {
-                    Ok(Ty::new_coroutine_closure(def, args.clone()))
-                }
-                AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
-            },
-            Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
-            Rvalue::CopyForDeref(place) => place.ty(locals),
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum AggregateKind {
-    Array(Ty),
-    Tuple,
-    Adt(AdtDef, VariantIdx, GenericArgs, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
-    Closure(ClosureDef, GenericArgs),
-    // FIXME(stable_mir): Movability here is redundant
-    Coroutine(CoroutineDef, GenericArgs, Movability),
-    CoroutineClosure(CoroutineClosureDef, GenericArgs),
-    RawPtr(Ty, Mutability),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum Operand {
-    Copy(Place),
-    Move(Place),
-    Constant(ConstOperand),
-}
-
-#[derive(Clone, Eq, PartialEq, Serialize)]
-pub struct Place {
-    pub local: Local,
-    /// projection out of a place (access a field, deref a pointer, etc)
-    pub projection: Vec<ProjectionElem>,
-}
-
-impl From<Local> for Place {
-    fn from(local: Local) -> Self {
-        Place { local, projection: vec![] }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct ConstOperand {
-    pub span: Span,
-    pub user_ty: Option<UserTypeAnnotationIndex>,
-    pub const_: MirConst,
-}
-
-/// Debug information pertaining to a user variable.
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct VarDebugInfo {
-    /// The variable name.
-    pub name: Symbol,
-
-    /// Source info of the user variable, including the scope
-    /// within which the variable is visible (to debuginfo).
-    pub source_info: SourceInfo,
-
-    /// The user variable's data is split across several fragments,
-    /// each described by a `VarDebugInfoFragment`.
-    pub composite: Option<VarDebugInfoFragment>,
-
-    /// Where the data for this user variable is to be found.
-    pub value: VarDebugInfoContents,
-
-    /// When present, indicates what argument number this variable is in the function that it
-    /// originated from (starting from 1). Note, if MIR inlining is enabled, then this is the
-    /// argument number in the original function before it was inlined.
-    pub argument_index: Option<u16>,
-}
-
-impl VarDebugInfo {
-    /// Return a local variable if this info is related to one.
-    pub fn local(&self) -> Option<Local> {
-        match &self.value {
-            VarDebugInfoContents::Place(place) if place.projection.is_empty() => Some(place.local),
-            VarDebugInfoContents::Place(_) | VarDebugInfoContents::Const(_) => None,
-        }
-    }
-
-    /// Return a constant if this info is related to one.
-    pub fn constant(&self) -> Option<&ConstOperand> {
-        match &self.value {
-            VarDebugInfoContents::Place(_) => None,
-            VarDebugInfoContents::Const(const_op) => Some(const_op),
-        }
-    }
-}
-
-pub type SourceScope = u32;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct SourceInfo {
-    pub span: Span,
-    pub scope: SourceScope,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct VarDebugInfoFragment {
-    pub ty: Ty,
-    pub projection: Vec<ProjectionElem>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum VarDebugInfoContents {
-    Place(Place),
-    Const(ConstOperand),
-}
-
-// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
-// is so it can be used for both Places (for which the projection elements are of type
-// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
-// are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use
-// ProjectionElem for Places.
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum ProjectionElem {
-    /// Dereference projections (e.g. `*_1`) project to the address referenced by the base place.
-    Deref,
-
-    /// A field projection (e.g., `f` in `_1.f`) project to a field in the base place. The field is
-    /// referenced by source-order index rather than the name of the field. The fields type is also
-    /// given.
-    Field(FieldIdx, Ty),
-
-    /// Index into a slice/array. The value of the index is computed at runtime using the `V`
-    /// argument.
-    ///
-    /// Note that this does not also dereference, and so it does not exactly correspond to slice
-    /// indexing in Rust. In other words, in the below Rust code:
-    ///
-    /// ```rust
-    /// let x = &[1, 2, 3, 4];
-    /// let i = 2;
-    /// x[i];
-    /// ```
-    ///
-    /// The `x[i]` is turned into a `Deref` followed by an `Index`, not just an `Index`. The same
-    /// thing is true of the `ConstantIndex` and `Subslice` projections below.
-    Index(Local),
-
-    /// Index into a slice/array given by offsets.
-    ///
-    /// These indices are generated by slice patterns. Easiest to explain by example:
-    ///
-    /// ```ignore (illustrative)
-    /// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false },
-    /// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false },
-    /// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true },
-    /// [_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true },
-    /// ```
-    ConstantIndex {
-        /// index or -index (in Python terms), depending on from_end
-        offset: u64,
-        /// The thing being indexed must be at least this long -- otherwise, the
-        /// projection is UB.
-        ///
-        /// For arrays this is always the exact length.
-        min_length: u64,
-        /// Counting backwards from end? This is always false when indexing an
-        /// array.
-        from_end: bool,
-    },
-
-    /// Projects a slice from the base place.
-    ///
-    /// These indices are generated by slice patterns. If `from_end` is true, this represents
-    /// `slice[from..slice.len() - to]`. Otherwise it represents `array[from..to]`.
-    Subslice {
-        from: u64,
-        to: u64,
-        /// Whether `to` counts from the start or end of the array/slice.
-        from_end: bool,
-    },
-
-    /// "Downcast" to a variant of an enum or a coroutine.
-    Downcast(VariantIdx),
-
-    /// Like an explicit cast from an opaque type to a concrete type, but without
-    /// requiring an intermediate variable.
-    OpaqueCast(Ty),
-
-    /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where
-    /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping
-    /// explicit during optimizations and codegen.
-    ///
-    /// This projection doesn't impact the runtime behavior of the program except for potentially changing
-    /// some type metadata of the interpreter or codegen backend.
-    Subtype(Ty),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct UserTypeProjection {
-    pub base: UserTypeAnnotationIndex,
-
-    pub projection: Opaque,
-}
-
-pub type Local = usize;
-
-pub const RETURN_LOCAL: Local = 0;
-
-/// The source-order index of a field in a variant.
-///
-/// For example, in the following types,
-/// ```ignore(illustrative)
-/// enum Demo1 {
-///    Variant0 { a: bool, b: i32 },
-///    Variant1 { c: u8, d: u64 },
-/// }
-/// struct Demo2 { e: u8, f: u16, g: u8 }
-/// ```
-/// `a`'s `FieldIdx` is `0`,
-/// `b`'s `FieldIdx` is `1`,
-/// `c`'s `FieldIdx` is `0`, and
-/// `g`'s `FieldIdx` is `2`.
-pub type FieldIdx = usize;
-
-type UserTypeAnnotationIndex = usize;
-
-/// The possible branch sites of a [TerminatorKind::SwitchInt].
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct SwitchTargets {
-    /// The conditional branches where the first element represents the value that guards this
-    /// branch, and the second element is the branch target.
-    branches: Vec<(u128, BasicBlockIdx)>,
-    /// The `otherwise` branch which will be taken in case none of the conditional branches are
-    /// satisfied.
-    otherwise: BasicBlockIdx,
-}
-
-impl SwitchTargets {
-    /// All possible targets including the `otherwise` target.
-    pub fn all_targets(&self) -> Successors {
-        self.branches.iter().map(|(_, target)| *target).chain(Some(self.otherwise)).collect()
-    }
-
-    /// The `otherwise` branch target.
-    pub fn otherwise(&self) -> BasicBlockIdx {
-        self.otherwise
-    }
-
-    /// The conditional targets which are only taken if the pattern matches the given value.
-    pub fn branches(&self) -> impl Iterator<Item = (u128, BasicBlockIdx)> {
-        self.branches.iter().copied()
-    }
-
-    /// The number of targets including `otherwise`.
-    pub fn len(&self) -> usize {
-        self.branches.len() + 1
-    }
-
-    /// Create a new SwitchTargets from the given branches and `otherwise` target.
-    pub fn new(branches: Vec<(u128, BasicBlockIdx)>, otherwise: BasicBlockIdx) -> SwitchTargets {
-        SwitchTargets { branches, otherwise }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum BorrowKind {
-    /// Data must be immutable and is aliasable.
-    Shared,
-
-    /// An immutable, aliasable borrow that is discarded after borrow-checking. Can behave either
-    /// like a normal shared borrow or like a special shallow borrow (see [`FakeBorrowKind`]).
-    Fake(FakeBorrowKind),
-
-    /// Data is mutable and not aliasable.
-    Mut {
-        /// `true` if this borrow arose from method-call auto-ref
-        kind: MutBorrowKind,
-    },
-}
-
-impl BorrowKind {
-    pub fn to_mutable_lossy(self) -> Mutability {
-        match self {
-            BorrowKind::Mut { .. } => Mutability::Mut,
-            BorrowKind::Shared => Mutability::Not,
-            // FIXME: There's no type corresponding to a shallow borrow, so use `&` as an approximation.
-            BorrowKind::Fake(_) => Mutability::Not,
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum RawPtrKind {
-    Mut,
-    Const,
-    FakeForPtrMetadata,
-}
-
-impl RawPtrKind {
-    pub fn to_mutable_lossy(self) -> Mutability {
-        match self {
-            RawPtrKind::Mut { .. } => Mutability::Mut,
-            RawPtrKind::Const => Mutability::Not,
-            // FIXME: There's no type corresponding to a shallow borrow, so use `&` as an approximation.
-            RawPtrKind::FakeForPtrMetadata => Mutability::Not,
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum MutBorrowKind {
-    Default,
-    TwoPhaseBorrow,
-    ClosureCapture,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum FakeBorrowKind {
-    /// A shared (deep) borrow. Data must be immutable and is aliasable.
-    Deep,
-    /// The immediately borrowed place must be immutable, but projections from
-    /// it don't need to be. This is used to prevent match guards from replacing
-    /// the scrutinee. For example, a fake borrow of `a.b` doesn't
-    /// conflict with a mutable borrow of `a.b.c`.
-    Shallow,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum Mutability {
-    Not,
-    Mut,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum Safety {
-    Safe,
-    Unsafe,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum PointerCoercion {
-    /// Go from a fn-item type to a fn-pointer type.
-    ReifyFnPointer,
-
-    /// Go from a safe fn pointer to an unsafe fn pointer.
-    UnsafeFnPointer,
-
-    /// Go from a non-capturing closure to a fn pointer or an unsafe fn pointer.
-    /// It cannot convert a closure that requires unsafe.
-    ClosureFnPointer(Safety),
-
-    /// Go from a mut raw pointer to a const raw pointer.
-    MutToConstPointer,
-
-    /// Go from `*const [T; N]` to `*const T`
-    ArrayToPointer,
-
-    /// Unsize a pointer/reference value, e.g., `&[T; n]` to
-    /// `&[T]`. Note that the source could be a thin or wide pointer.
-    /// This will do things like convert thin pointers to wide
-    /// pointers, or convert structs containing thin pointers to
-    /// structs containing wide pointers, or convert between wide
-    /// pointers.
-    Unsize,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum CastKind {
-    // FIXME(smir-rename): rename this to PointerExposeProvenance
-    PointerExposeAddress,
-    PointerWithExposedProvenance,
-    PointerCoercion(PointerCoercion),
-    // FIXME(smir-rename): change this to PointerCoercion(DynStar)
-    DynStar,
-    IntToInt,
-    FloatToInt,
-    FloatToFloat,
-    IntToFloat,
-    PtrToPtr,
-    FnPtrToPtr,
-    Transmute,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum NullOp {
-    /// Returns the size of a value of that type.
-    SizeOf,
-    /// Returns the minimum alignment of a type.
-    AlignOf,
-    /// Returns the offset of a field.
-    OffsetOf(Vec<(VariantIdx, FieldIdx)>),
-    /// cfg!(ub_checks), but at codegen time
-    UbChecks,
-    /// cfg!(contract_checks), but at codegen time
-    ContractChecks,
-}
-
-impl Operand {
-    /// Get the type of an operand relative to the local declaration.
-    ///
-    /// In order to retrieve the correct type, the `locals` argument must match the list of all
-    /// locals from the function body where this operand originates from.
-    ///
-    /// Errors indicate a malformed operand or incompatible locals list.
-    pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
-        match self {
-            Operand::Copy(place) | Operand::Move(place) => place.ty(locals),
-            Operand::Constant(c) => Ok(c.ty()),
-        }
-    }
-}
-
-impl ConstOperand {
-    pub fn ty(&self) -> Ty {
-        self.const_.ty()
-    }
-}
-
-impl Place {
-    /// Resolve down the chain of projections to get the type referenced at the end of it.
-    /// E.g.:
-    /// Calling `ty()` on `var.field` should return the type of `field`.
-    ///
-    /// In order to retrieve the correct type, the `locals` argument must match the list of all
-    /// locals from the function body where this place originates from.
-    pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
-        self.projection.iter().try_fold(locals[self.local].ty, |place_ty, elem| elem.ty(place_ty))
-    }
-}
-
-impl ProjectionElem {
-    /// Get the expected type after applying this projection to a given place type.
-    pub fn ty(&self, place_ty: Ty) -> Result<Ty, Error> {
-        let ty = place_ty;
-        match &self {
-            ProjectionElem::Deref => Self::deref_ty(ty),
-            ProjectionElem::Field(_idx, fty) => Ok(*fty),
-            ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => Self::index_ty(ty),
-            ProjectionElem::Subslice { from, to, from_end } => {
-                Self::subslice_ty(ty, *from, *to, *from_end)
-            }
-            ProjectionElem::Downcast(_) => Ok(ty),
-            ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty),
-        }
-    }
-
-    fn index_ty(ty: Ty) -> Result<Ty, Error> {
-        ty.kind().builtin_index().ok_or_else(|| error!("Cannot index non-array type: {ty:?}"))
-    }
-
-    fn subslice_ty(ty: Ty, from: u64, to: u64, from_end: bool) -> Result<Ty, Error> {
-        let ty_kind = ty.kind();
-        match ty_kind {
-            TyKind::RigidTy(RigidTy::Slice(..)) => Ok(ty),
-            TyKind::RigidTy(RigidTy::Array(inner, _)) if !from_end => Ty::try_new_array(
-                inner,
-                to.checked_sub(from).ok_or_else(|| error!("Subslice overflow: {from}..{to}"))?,
-            ),
-            TyKind::RigidTy(RigidTy::Array(inner, size)) => {
-                let size = size.eval_target_usize()?;
-                let len = size - from - to;
-                Ty::try_new_array(inner, len)
-            }
-            _ => Err(Error(format!("Cannot subslice non-array type: `{ty_kind:?}`"))),
-        }
-    }
-
-    fn deref_ty(ty: Ty) -> Result<Ty, Error> {
-        let deref_ty = ty
-            .kind()
-            .builtin_deref(true)
-            .ok_or_else(|| error!("Cannot dereference type: {ty:?}"))?;
-        Ok(deref_ty.ty)
-    }
-}
diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs
deleted file mode 100644
index 22507a49411..00000000000
--- a/compiler/stable_mir/src/mir/mono.rs
+++ /dev/null
@@ -1,307 +0,0 @@
-use std::fmt::{Debug, Formatter};
-use std::io;
-
-use serde::Serialize;
-
-use crate::abi::FnAbi;
-use crate::crate_def::CrateDef;
-use crate::mir::Body;
-use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
-use crate::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with};
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum MonoItem {
-    Fn(Instance),
-    Static(StaticDef),
-    GlobalAsm(Opaque),
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize)]
-pub struct Instance {
-    /// The type of instance.
-    pub kind: InstanceKind,
-    /// An ID used to get the instance definition from the compiler.
-    /// Do not use this field directly.
-    pub def: InstanceDef,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
-pub enum InstanceKind {
-    /// A user defined item.
-    Item,
-    /// A compiler intrinsic function.
-    Intrinsic,
-    /// A virtual function definition stored in a VTable.
-    /// The `idx` field indicates the position in the VTable for this instance.
-    Virtual { idx: usize },
-    /// A compiler generated shim.
-    Shim,
-}
-
-impl Instance {
-    /// Get the arguments this instance was instantiated with.
-    pub fn args(&self) -> GenericArgs {
-        with(|cx| cx.instance_args(self.def))
-    }
-
-    /// Get the body of an Instance.
-    ///
-    /// The body will be eagerly monomorphized and all constants will already be evaluated.
-    ///
-    /// This method will return the intrinsic fallback body if one was defined.
-    pub fn body(&self) -> Option<Body> {
-        with(|context| context.instance_body(self.def))
-    }
-
-    /// Check whether this instance has a body available.
-    ///
-    /// For intrinsics with fallback body, this will return `true`. It is up to the user to decide
-    /// whether to specialize the intrinsic or to use its fallback body.
-    ///
-    /// For more information on fallback body, see <https://github.com/rust-lang/rust/issues/93145>.
-    ///
-    /// This call is much cheaper than `instance.body().is_some()`, since it doesn't try to build
-    /// the StableMIR body.
-    pub fn has_body(&self) -> bool {
-        with(|cx| cx.has_body(self.def.def_id()))
-    }
-
-    pub fn is_foreign_item(&self) -> bool {
-        with(|cx| cx.is_foreign_item(self.def.def_id()))
-    }
-
-    /// Get the instance type with generic instantiations applied and lifetimes erased.
-    pub fn ty(&self) -> Ty {
-        with(|context| context.instance_ty(self.def))
-    }
-
-    /// Retrieve information about this instance binary interface.
-    pub fn fn_abi(&self) -> Result<FnAbi, Error> {
-        with(|cx| cx.instance_abi(self.def))
-    }
-
-    /// Retrieve the instance's mangled name used for calling the given instance.
-    ///
-    /// This will also look up the correct name of instances from upstream crates.
-    pub fn mangled_name(&self) -> Symbol {
-        with(|context| context.instance_mangled_name(self.def))
-    }
-
-    /// Retrieve the instance name for diagnostic messages.
-    ///
-    /// This will return the specialized name, e.g., `std::vec::Vec<u8>::new`.
-    pub fn name(&self) -> Symbol {
-        with(|context| context.instance_name(self.def, false))
-    }
-
-    /// Return a trimmed name of the given instance including its args.
-    ///
-    /// If a symbol name can only be imported from one place for a type, and as
-    /// long as it was not glob-imported anywhere in the current crate, we trim its
-    /// path and print only the name.
-    pub fn trimmed_name(&self) -> Symbol {
-        with(|context| context.instance_name(self.def, true))
-    }
-
-    /// Retrieve the plain intrinsic name of an instance if it's an intrinsic.
-    ///
-    /// The plain name does not include type arguments (as `trimmed_name` does),
-    /// which is more convenient to match with intrinsic symbols.
-    pub fn intrinsic_name(&self) -> Option<Symbol> {
-        match self.kind {
-            InstanceKind::Intrinsic => {
-                Some(with(|context| context.intrinsic(self.def.def_id()).unwrap().fn_name()))
-            }
-            InstanceKind::Item | InstanceKind::Virtual { .. } | InstanceKind::Shim => None,
-        }
-    }
-
-    /// Resolve an instance starting from a function definition and generic arguments.
-    pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
-        with(|context| {
-            context.resolve_instance(def, args).ok_or_else(|| {
-                crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
-            })
-        })
-    }
-
-    /// Resolve the drop in place for a given type.
-    pub fn resolve_drop_in_place(ty: Ty) -> Instance {
-        with(|cx| cx.resolve_drop_in_place(ty))
-    }
-
-    /// Resolve an instance for a given function pointer.
-    pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
-        with(|context| {
-            context.resolve_for_fn_ptr(def, args).ok_or_else(|| {
-                crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
-            })
-        })
-    }
-
-    /// Resolve a closure with the expected kind.
-    pub fn resolve_closure(
-        def: ClosureDef,
-        args: &GenericArgs,
-        kind: ClosureKind,
-    ) -> Result<Instance, crate::Error> {
-        with(|context| {
-            context.resolve_closure(def, args, kind).ok_or_else(|| {
-                crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
-            })
-        })
-    }
-
-    /// Check whether this instance is an empty shim.
-    ///
-    /// Allow users to check if this shim can be ignored when called directly.
-    ///
-    /// We have decided not to export different types of Shims to StableMIR users, however, this
-    /// is a query that can be very helpful for users when processing DropGlue.
-    ///
-    /// When generating code for a Drop terminator, users can ignore an empty drop glue.
-    /// These shims are only needed to generate a valid Drop call done via VTable.
-    pub fn is_empty_shim(&self) -> bool {
-        self.kind == InstanceKind::Shim
-            && with(|cx| {
-                cx.is_empty_drop_shim(self.def) || cx.is_empty_async_drop_ctor_shim(self.def)
-            })
-    }
-
-    /// Try to constant evaluate the instance into a constant with the given type.
-    ///
-    /// This can be used to retrieve a constant that represents an intrinsic return such as
-    /// `type_id`.
-    pub fn try_const_eval(&self, const_ty: Ty) -> Result<Allocation, Error> {
-        with(|cx| cx.eval_instance(self.def, const_ty))
-    }
-
-    /// Emit the body of this instance if it has one.
-    pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
-        if let Some(body) = self.body() { body.dump(w, &self.name()) } else { Ok(()) }
-    }
-}
-
-impl Debug for Instance {
-    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("Instance")
-            .field("kind", &self.kind)
-            .field("def", &self.mangled_name())
-            .field("args", &self.args())
-            .finish()
-    }
-}
-
-/// Try to convert a crate item into an instance.
-/// The item cannot be generic in order to be converted into an instance.
-impl TryFrom<CrateItem> for Instance {
-    type Error = crate::Error;
-
-    fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
-        with(|context| {
-            let def_id = item.def_id();
-            if !context.requires_monomorphization(def_id) {
-                Ok(context.mono_instance(def_id))
-            } else {
-                Err(Error::new("Item requires monomorphization".to_string()))
-            }
-        })
-    }
-}
-
-/// Try to convert an instance into a crate item.
-/// Only user defined instances can be converted.
-impl TryFrom<Instance> for CrateItem {
-    type Error = crate::Error;
-
-    fn try_from(value: Instance) -> Result<Self, Self::Error> {
-        with(|context| {
-            if value.kind == InstanceKind::Item && context.has_body(value.def.def_id()) {
-                Ok(CrateItem(context.instance_def_id(value.def)))
-            } else {
-                Err(Error::new(format!("Item kind `{:?}` cannot be converted", value.kind)))
-            }
-        })
-    }
-}
-
-impl From<Instance> for MonoItem {
-    fn from(value: Instance) -> Self {
-        MonoItem::Fn(value)
-    }
-}
-
-impl From<StaticDef> for MonoItem {
-    fn from(value: StaticDef) -> Self {
-        MonoItem::Static(value)
-    }
-}
-
-impl From<StaticDef> for CrateItem {
-    fn from(value: StaticDef) -> Self {
-        CrateItem(value.0)
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct InstanceDef(usize);
-
-impl CrateDef for InstanceDef {
-    fn def_id(&self) -> DefId {
-        with(|context| context.instance_def_id(*self))
-    }
-}
-
-crate_def! {
-    /// Holds information about a static variable definition.
-    #[derive(Serialize)]
-    pub StaticDef;
-}
-
-impl TryFrom<CrateItem> for StaticDef {
-    type Error = crate::Error;
-
-    fn try_from(value: CrateItem) -> Result<Self, Self::Error> {
-        if matches!(value.kind(), ItemKind::Static) {
-            Ok(StaticDef(value.0))
-        } else {
-            Err(Error::new(format!("Expected a static item, but found: {value:?}")))
-        }
-    }
-}
-
-impl TryFrom<Instance> for StaticDef {
-    type Error = crate::Error;
-
-    fn try_from(value: Instance) -> Result<Self, Self::Error> {
-        StaticDef::try_from(CrateItem::try_from(value)?)
-    }
-}
-
-impl From<StaticDef> for Instance {
-    fn from(value: StaticDef) -> Self {
-        // A static definition should always be convertible to an instance.
-        with(|cx| cx.mono_instance(value.def_id()))
-    }
-}
-
-impl StaticDef {
-    /// Return the type of this static definition.
-    pub fn ty(&self) -> Ty {
-        with(|cx| cx.def_ty(self.0))
-    }
-
-    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
-    pub fn eval_initializer(&self) -> Result<Allocation, Error> {
-        with(|cx| cx.eval_static_initializer(*self))
-    }
-}
-
-impl IndexedVal for InstanceDef {
-    fn to_val(index: usize) -> Self {
-        InstanceDef(index)
-    }
-    fn to_index(&self) -> usize {
-        self.0
-    }
-}
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
deleted file mode 100644
index 65d9f20f0a3..00000000000
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ /dev/null
@@ -1,462 +0,0 @@
-//! Implement methods to pretty print stable MIR body.
-use std::fmt::Debug;
-use std::io::Write;
-use std::{fmt, io, iter};
-
-use fmt::{Display, Formatter};
-
-use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
-use crate::mir::{
-    Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
-};
-use crate::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst};
-use crate::{Body, CrateDef, Mutability, with};
-
-impl Display for Ty {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        with(|ctx| write!(f, "{}", ctx.ty_pretty(*self)))
-    }
-}
-
-impl Display for AssocKind {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self {
-            AssocKind::Fn => write!(f, "method"),
-            AssocKind::Const => write!(f, "associated const"),
-            AssocKind::Type => write!(f, "associated type"),
-        }
-    }
-}
-
-impl Debug for Place {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        with(|ctx| write!(f, "{}", ctx.place_pretty(self)))
-    }
-}
-
-pub(crate) fn function_body<W: Write>(writer: &mut W, body: &Body, name: &str) -> io::Result<()> {
-    write!(writer, "fn {name}(")?;
-    let mut sep = "";
-    for (index, local) in body.arg_locals().iter().enumerate() {
-        write!(writer, "{}_{}: {}", sep, index + 1, local.ty)?;
-        sep = ", ";
-    }
-    write!(writer, ")")?;
-
-    let return_local = body.ret_local();
-    writeln!(writer, " -> {} {{", return_local.ty)?;
-
-    body.locals().iter().enumerate().try_for_each(|(index, local)| -> io::Result<()> {
-        if index == 0 || index > body.arg_count {
-            writeln!(writer, "    let {}_{}: {};", pretty_mut(local.mutability), index, local.ty)
-        } else {
-            Ok(())
-        }
-    })?;
-
-    body.var_debug_info.iter().try_for_each(|info| {
-        let content = match &info.value {
-            VarDebugInfoContents::Place(place) => {
-                format!("{place:?}")
-            }
-            VarDebugInfoContents::Const(constant) => pretty_mir_const(&constant.const_),
-        };
-        writeln!(writer, "    debug {} => {};", info.name, content)
-    })?;
-
-    body.blocks
-        .iter()
-        .enumerate()
-        .map(|(index, block)| -> io::Result<()> {
-            writeln!(writer, "    bb{index}: {{")?;
-            let _ = block
-                .statements
-                .iter()
-                .map(|statement| -> io::Result<()> {
-                    pretty_statement(writer, &statement.kind)?;
-                    Ok(())
-                })
-                .collect::<Vec<_>>();
-            pretty_terminator(writer, &block.terminator.kind)?;
-            writeln!(writer, "    }}").unwrap();
-            Ok(())
-        })
-        .collect::<Result<Vec<_>, _>>()?;
-    writeln!(writer, "}}")?;
-    Ok(())
-}
-
-fn pretty_statement<W: Write>(writer: &mut W, statement: &StatementKind) -> io::Result<()> {
-    const INDENT: &str = "        ";
-    match statement {
-        StatementKind::Assign(place, rval) => {
-            write!(writer, "{INDENT}{place:?} = ")?;
-            pretty_rvalue(writer, rval)?;
-            writeln!(writer, ";")
-        }
-        // FIXME: Add rest of the statements
-        StatementKind::FakeRead(cause, place) => {
-            writeln!(writer, "{INDENT}FakeRead({cause:?}, {place:?});")
-        }
-        StatementKind::SetDiscriminant { place, variant_index } => {
-            writeln!(writer, "{INDENT}discriminant({place:?} = {};", variant_index.to_index())
-        }
-        StatementKind::Deinit(place) => writeln!(writer, "Deinit({place:?};"),
-        StatementKind::StorageLive(local) => {
-            writeln!(writer, "{INDENT}StorageLive(_{local});")
-        }
-        StatementKind::StorageDead(local) => {
-            writeln!(writer, "{INDENT}StorageDead(_{local});")
-        }
-        StatementKind::Retag(kind, place) => writeln!(writer, "Retag({kind:?}, {place:?});"),
-        StatementKind::PlaceMention(place) => {
-            writeln!(writer, "{INDENT}PlaceMention({place:?};")
-        }
-        StatementKind::ConstEvalCounter => {
-            writeln!(writer, "{INDENT}ConstEvalCounter;")
-        }
-        StatementKind::Nop => writeln!(writer, "{INDENT}nop;"),
-        StatementKind::AscribeUserType { .. }
-        | StatementKind::Coverage(_)
-        | StatementKind::Intrinsic(_) => {
-            // FIX-ME: Make them pretty.
-            writeln!(writer, "{INDENT}{statement:?};")
-        }
-    }
-}
-
-fn pretty_terminator<W: Write>(writer: &mut W, terminator: &TerminatorKind) -> io::Result<()> {
-    pretty_terminator_head(writer, terminator)?;
-    let successors = terminator.successors();
-    let successor_count = successors.len();
-    let labels = pretty_successor_labels(terminator);
-
-    let show_unwind = !matches!(terminator.unwind(), None | Some(UnwindAction::Cleanup(_)));
-    let fmt_unwind = |w: &mut W| -> io::Result<()> {
-        write!(w, "unwind ")?;
-        match terminator.unwind() {
-            None | Some(UnwindAction::Cleanup(_)) => unreachable!(),
-            Some(UnwindAction::Continue) => write!(w, "continue"),
-            Some(UnwindAction::Unreachable) => write!(w, "unreachable"),
-            Some(UnwindAction::Terminate) => write!(w, "terminate"),
-        }
-    };
-
-    match (successor_count, show_unwind) {
-        (0, false) => {}
-        (0, true) => {
-            write!(writer, " -> ")?;
-            fmt_unwind(writer)?;
-        }
-        (1, false) => write!(writer, " -> bb{:?}", successors[0])?,
-        _ => {
-            write!(writer, " -> [")?;
-            for (i, target) in successors.iter().enumerate() {
-                if i > 0 {
-                    write!(writer, ", ")?;
-                }
-                write!(writer, "{}: bb{:?}", labels[i], target)?;
-            }
-            if show_unwind {
-                write!(writer, ", ")?;
-                fmt_unwind(writer)?;
-            }
-            write!(writer, "]")?;
-        }
-    };
-
-    writeln!(writer, ";")
-}
-
-fn pretty_terminator_head<W: Write>(writer: &mut W, terminator: &TerminatorKind) -> io::Result<()> {
-    use self::TerminatorKind::*;
-    const INDENT: &str = "        ";
-    match terminator {
-        Goto { .. } => write!(writer, "{INDENT}goto"),
-        SwitchInt { discr, .. } => {
-            write!(writer, "{INDENT}switchInt({})", pretty_operand(discr))
-        }
-        Resume => write!(writer, "{INDENT}resume"),
-        Abort => write!(writer, "{INDENT}abort"),
-        Return => write!(writer, "{INDENT}return"),
-        Unreachable => write!(writer, "{INDENT}unreachable"),
-        Drop { place, .. } => write!(writer, "{INDENT}drop({place:?})"),
-        Call { func, args, destination, .. } => {
-            write!(writer, "{INDENT}{:?} = {}(", destination, pretty_operand(func))?;
-            let mut args_iter = args.iter();
-            args_iter.next().map_or(Ok(()), |arg| write!(writer, "{}", pretty_operand(arg)))?;
-            args_iter.try_for_each(|arg| write!(writer, ", {}", pretty_operand(arg)))?;
-            write!(writer, ")")
-        }
-        Assert { cond, expected, msg, target: _, unwind: _ } => {
-            write!(writer, "{INDENT}assert(")?;
-            if !expected {
-                write!(writer, "!")?;
-            }
-            write!(writer, "{}, ", pretty_operand(cond))?;
-            pretty_assert_message(writer, msg)?;
-            write!(writer, ")")
-        }
-        InlineAsm { .. } => write!(writer, "{INDENT}InlineAsm"),
-    }
-}
-
-fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec<String> {
-    use self::TerminatorKind::*;
-    match terminator {
-        Call { target: None, unwind: UnwindAction::Cleanup(_), .. }
-        | InlineAsm { destination: None, .. } => vec!["unwind".into()],
-        Resume | Abort | Return | Unreachable | Call { target: None, unwind: _, .. } => vec![],
-        Goto { .. } => vec!["".to_string()],
-        SwitchInt { targets, .. } => targets
-            .branches()
-            .map(|(val, _target)| format!("{val}"))
-            .chain(iter::once("otherwise".into()))
-            .collect(),
-        Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()],
-        Call { target: Some(_), unwind: UnwindAction::Cleanup(_), .. } => {
-            vec!["return".into(), "unwind".into()]
-        }
-        Drop { unwind: _, .. } | Call { target: Some(_), unwind: _, .. } => vec!["return".into()],
-        Assert { unwind: UnwindAction::Cleanup(_), .. } => {
-            vec!["success".into(), "unwind".into()]
-        }
-        Assert { unwind: _, .. } => vec!["success".into()],
-        InlineAsm { destination: Some(_), .. } => vec!["goto".into(), "unwind".into()],
-    }
-}
-
-fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::Result<()> {
-    match msg {
-        AssertMessage::BoundsCheck { len, index } => {
-            let pretty_len = pretty_operand(len);
-            let pretty_index = pretty_operand(index);
-            write!(
-                writer,
-                "\"index out of bounds: the length is {{}} but the index is {{}}\", {pretty_len}, {pretty_index}"
-            )
-        }
-        AssertMessage::Overflow(BinOp::Add, l, r) => {
-            let pretty_l = pretty_operand(l);
-            let pretty_r = pretty_operand(r);
-            write!(
-                writer,
-                "\"attempt to compute `{{}} + {{}}`, which would overflow\", {pretty_l}, {pretty_r}"
-            )
-        }
-        AssertMessage::Overflow(BinOp::Sub, l, r) => {
-            let pretty_l = pretty_operand(l);
-            let pretty_r = pretty_operand(r);
-            write!(
-                writer,
-                "\"attempt to compute `{{}} - {{}}`, which would overflow\", {pretty_l}, {pretty_r}"
-            )
-        }
-        AssertMessage::Overflow(BinOp::Mul, l, r) => {
-            let pretty_l = pretty_operand(l);
-            let pretty_r = pretty_operand(r);
-            write!(
-                writer,
-                "\"attempt to compute `{{}} * {{}}`, which would overflow\", {pretty_l}, {pretty_r}"
-            )
-        }
-        AssertMessage::Overflow(BinOp::Div, l, r) => {
-            let pretty_l = pretty_operand(l);
-            let pretty_r = pretty_operand(r);
-            write!(
-                writer,
-                "\"attempt to compute `{{}} / {{}}`, which would overflow\", {pretty_l}, {pretty_r}"
-            )
-        }
-        AssertMessage::Overflow(BinOp::Rem, l, r) => {
-            let pretty_l = pretty_operand(l);
-            let pretty_r = pretty_operand(r);
-            write!(
-                writer,
-                "\"attempt to compute `{{}} % {{}}`, which would overflow\", {pretty_l}, {pretty_r}"
-            )
-        }
-        AssertMessage::Overflow(BinOp::Shr, _, r) => {
-            let pretty_r = pretty_operand(r);
-            write!(writer, "\"attempt to shift right by `{{}}`, which would overflow\", {pretty_r}")
-        }
-        AssertMessage::Overflow(BinOp::Shl, _, r) => {
-            let pretty_r = pretty_operand(r);
-            write!(writer, "\"attempt to shift left by `{{}}`, which would overflow\", {pretty_r}")
-        }
-        AssertMessage::Overflow(op, _, _) => unreachable!("`{:?}` cannot overflow", op),
-        AssertMessage::OverflowNeg(op) => {
-            let pretty_op = pretty_operand(op);
-            write!(writer, "\"attempt to negate `{{}}`, which would overflow\", {pretty_op}")
-        }
-        AssertMessage::DivisionByZero(op) => {
-            let pretty_op = pretty_operand(op);
-            write!(writer, "\"attempt to divide `{{}}` by zero\", {pretty_op}")
-        }
-        AssertMessage::RemainderByZero(op) => {
-            let pretty_op = pretty_operand(op);
-            write!(
-                writer,
-                "\"attempt to calculate the remainder of `{{}}` with a divisor of zero\", {pretty_op}"
-            )
-        }
-        AssertMessage::MisalignedPointerDereference { required, found } => {
-            let pretty_required = pretty_operand(required);
-            let pretty_found = pretty_operand(found);
-            write!(
-                writer,
-                "\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}"
-            )
-        }
-        AssertMessage::NullPointerDereference => {
-            write!(writer, "\"null pointer dereference occurred\"")
-        }
-        AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
-            write!(writer, "{}", msg.description().unwrap())
-        }
-    }
-}
-
-fn pretty_operand(operand: &Operand) -> String {
-    match operand {
-        Operand::Copy(copy) => {
-            format!("{copy:?}")
-        }
-        Operand::Move(mv) => {
-            format!("move {mv:?}")
-        }
-        Operand::Constant(cnst) => pretty_mir_const(&cnst.const_),
-    }
-}
-
-fn pretty_mir_const(literal: &MirConst) -> String {
-    with(|cx| cx.mir_const_pretty(literal))
-}
-
-fn pretty_ty_const(ct: &TyConst) -> String {
-    with(|cx| cx.ty_const_pretty(ct.id))
-}
-
-fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
-    match rval {
-        Rvalue::AddressOf(mutability, place) => {
-            write!(writer, "&raw {} {:?}", pretty_raw_ptr_kind(*mutability), place)
-        }
-        Rvalue::Aggregate(aggregate_kind, operands) => {
-            // FIXME: Add pretty_aggregate function that returns a pretty string
-            pretty_aggregate(writer, aggregate_kind, operands)
-        }
-        Rvalue::BinaryOp(bin, op1, op2) => {
-            write!(writer, "{:?}({}, {})", bin, pretty_operand(op1), pretty_operand(op2))
-        }
-        Rvalue::Cast(_, op, ty) => {
-            write!(writer, "{} as {}", pretty_operand(op), ty)
-        }
-        Rvalue::CheckedBinaryOp(bin, op1, op2) => {
-            write!(writer, "Checked{:?}({}, {})", bin, pretty_operand(op1), pretty_operand(op2))
-        }
-        Rvalue::CopyForDeref(deref) => {
-            write!(writer, "CopyForDeref({deref:?})")
-        }
-        Rvalue::Discriminant(place) => {
-            write!(writer, "discriminant({place:?})")
-        }
-        Rvalue::Len(len) => {
-            write!(writer, "len({len:?})")
-        }
-        Rvalue::Ref(_, borrowkind, place) => {
-            let kind = match borrowkind {
-                BorrowKind::Shared => "&",
-                BorrowKind::Fake(FakeBorrowKind::Deep) => "&fake ",
-                BorrowKind::Fake(FakeBorrowKind::Shallow) => "&fake shallow ",
-                BorrowKind::Mut { .. } => "&mut ",
-            };
-            write!(writer, "{kind}{place:?}")
-        }
-        Rvalue::Repeat(op, cnst) => {
-            write!(writer, "[{}; {}]", pretty_operand(op), pretty_ty_const(cnst))
-        }
-        Rvalue::ShallowInitBox(_, _) => Ok(()),
-        Rvalue::ThreadLocalRef(item) => {
-            write!(writer, "thread_local_ref{item:?}")
-        }
-        Rvalue::NullaryOp(nul, ty) => {
-            write!(writer, "{nul:?}::<{ty}>() \" \"")
-        }
-        Rvalue::UnaryOp(un, op) => {
-            write!(writer, "{:?}({})", un, pretty_operand(op))
-        }
-        Rvalue::Use(op) => write!(writer, "{}", pretty_operand(op)),
-    }
-}
-
-fn pretty_aggregate<W: Write>(
-    writer: &mut W,
-    aggregate_kind: &AggregateKind,
-    operands: &Vec<Operand>,
-) -> io::Result<()> {
-    let suffix = match aggregate_kind {
-        AggregateKind::Array(_) => {
-            write!(writer, "[")?;
-            "]"
-        }
-        AggregateKind::Tuple => {
-            write!(writer, "(")?;
-            ")"
-        }
-        AggregateKind::Adt(def, var, _, _, _) => {
-            if def.kind() == AdtKind::Enum {
-                write!(writer, "{}::{}", def.name(), def.variant(*var).unwrap().name())?;
-            } else {
-                write!(writer, "{}", def.variant(*var).unwrap().name())?;
-            }
-            if operands.is_empty() {
-                return Ok(());
-            }
-            // FIXME: Change this once we have CtorKind in StableMIR.
-            write!(writer, "(")?;
-            ")"
-        }
-        AggregateKind::Closure(def, _) => {
-            write!(writer, "{{closure@{}}}(", def.span().diagnostic())?;
-            ")"
-        }
-        AggregateKind::Coroutine(def, _, _) => {
-            write!(writer, "{{coroutine@{}}}(", def.span().diagnostic())?;
-            ")"
-        }
-        AggregateKind::CoroutineClosure(def, _) => {
-            write!(writer, "{{coroutine-closure@{}}}(", def.span().diagnostic())?;
-            ")"
-        }
-        AggregateKind::RawPtr(ty, mutability) => {
-            write!(
-                writer,
-                "*{} {ty} from (",
-                if *mutability == Mutability::Mut { "mut" } else { "const" }
-            )?;
-            ")"
-        }
-    };
-    let mut separator = "";
-    for op in operands {
-        write!(writer, "{}{}", separator, pretty_operand(op))?;
-        separator = ", ";
-    }
-    write!(writer, "{suffix}")
-}
-
-fn pretty_mut(mutability: Mutability) -> &'static str {
-    match mutability {
-        Mutability::Not => " ",
-        Mutability::Mut => "mut ",
-    }
-}
-
-fn pretty_raw_ptr_kind(kind: RawPtrKind) -> &'static str {
-    match kind {
-        RawPtrKind::Const => "const",
-        RawPtrKind::Mut => "mut",
-        RawPtrKind::FakeForPtrMetadata => "const (fake)",
-    }
-}
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
deleted file mode 100644
index 9d2368ba332..00000000000
--- a/compiler/stable_mir/src/mir/visit.rs
+++ /dev/null
@@ -1,586 +0,0 @@
-//! # The Stable MIR Visitor
-//!
-//! ## Overview
-//!
-//! We currently only support an immutable visitor.
-//! The structure of this visitor is similar to the ones internal to `rustc`,
-//! and it follows the following conventions:
-//!
-//! For every mir item, the trait has a `visit_<item>` and a `super_<item>` method.
-//! - `visit_<item>`, by default, calls `super_<item>`
-//! - `super_<item>`, by default, destructures the `<item>` and calls `visit_<sub_item>` for
-//!   all sub-items that compose the original item.
-//!
-//! In order to implement a visitor, override the `visit_*` methods for the types you are
-//! interested in analyzing, and invoke (within that method call)
-//! `self.super_*` to continue to the traverse.
-//! Avoid calling `super` methods in other circumstances.
-//!
-//! For the most part, we do not destructure things external to the
-//! MIR, e.g., types, spans, etc, but simply visit them and stop.
-//! This avoids duplication with other visitors like `TypeFoldable`.
-//!
-//! ## Updating
-//!
-//! The code is written in a very deliberate style intended to minimize
-//! the chance of things being overlooked.
-//!
-//! Use pattern matching to reference fields and ensure that all
-//! matches are exhaustive.
-//!
-//! For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
-//! That means you never write `..` to skip over fields, nor do you write `_`
-//! to skip over variants in a `match`.
-//!
-//! The only place that `_` is acceptable is to match a field (or
-//! variant argument) that does not require visiting.
-
-use crate::mir::*;
-use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst};
-use crate::{Error, Opaque, Span};
-
-macro_rules! make_mir_visitor {
-    ($visitor_trait_name:ident, $($mutability:ident)?) => {
-        pub trait $visitor_trait_name {
-            fn visit_body(&mut self, body: &$($mutability)? Body) {
-                self.super_body(body)
-            }
-
-            fn visit_basic_block(&mut self, bb: &$($mutability)? BasicBlock) {
-                self.super_basic_block(bb)
-            }
-
-            fn visit_ret_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) {
-                self.super_ret_decl(local, decl)
-            }
-
-            fn visit_arg_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) {
-                self.super_arg_decl(local, decl)
-            }
-
-            fn visit_local_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) {
-                self.super_local_decl(local, decl)
-            }
-
-            fn visit_statement(&mut self, stmt: &$($mutability)? Statement, location: Location) {
-                self.super_statement(stmt, location)
-            }
-
-            fn visit_terminator(&mut self, term: &$($mutability)? Terminator, location: Location) {
-                self.super_terminator(term, location)
-            }
-
-            fn visit_span(&mut self, span: &$($mutability)? Span) {
-                self.super_span(span)
-            }
-
-            fn visit_place(&mut self, place: &$($mutability)? Place, ptx: PlaceContext, location: Location) {
-                self.super_place(place, ptx, location)
-            }
-
-            visit_place_fns!($($mutability)?);
-
-            fn visit_local(&mut self, local: &$($mutability)? Local, ptx: PlaceContext, location: Location) {
-                let _ = (local, ptx, location);
-            }
-
-            fn visit_rvalue(&mut self, rvalue: &$($mutability)? Rvalue, location: Location) {
-                self.super_rvalue(rvalue, location)
-            }
-
-            fn visit_operand(&mut self, operand: &$($mutability)? Operand, location: Location) {
-                self.super_operand(operand, location)
-            }
-
-            fn visit_user_type_projection(&mut self, projection: &$($mutability)? UserTypeProjection) {
-                self.super_user_type_projection(projection)
-            }
-
-            fn visit_ty(&mut self, ty: &$($mutability)? Ty, location: Location) {
-                let _ = location;
-                self.super_ty(ty)
-            }
-
-            fn visit_const_operand(&mut self, constant: &$($mutability)? ConstOperand, location: Location) {
-                self.super_const_operand(constant, location)
-            }
-
-            fn visit_mir_const(&mut self, constant: &$($mutability)? MirConst, location: Location) {
-                self.super_mir_const(constant, location)
-            }
-
-            fn visit_ty_const(&mut self, constant: &$($mutability)? TyConst, location: Location) {
-                let _ = location;
-                self.super_ty_const(constant)
-            }
-
-            fn visit_region(&mut self, region: &$($mutability)? Region, location: Location) {
-                let _ = location;
-                self.super_region(region)
-            }
-
-            fn visit_args(&mut self, args: &$($mutability)? GenericArgs, location: Location) {
-                let _ = location;
-                self.super_args(args)
-            }
-
-            fn visit_assert_msg(&mut self, msg: &$($mutability)? AssertMessage, location: Location) {
-                self.super_assert_msg(msg, location)
-            }
-
-            fn visit_var_debug_info(&mut self, var_debug_info: &$($mutability)? VarDebugInfo) {
-                self.super_var_debug_info(var_debug_info);
-            }
-
-            fn super_body(&mut self, body: &$($mutability)? Body) {
-                super_body!(self, body, $($mutability)?);
-            }
-
-            fn super_basic_block(&mut self, bb: &$($mutability)? BasicBlock) {
-                let BasicBlock { statements, terminator } = bb;
-                for stmt in statements {
-                    self.visit_statement(stmt, Location(stmt.span));
-                }
-                self.visit_terminator(terminator, Location(terminator.span));
-            }
-
-            fn super_local_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) {
-                let _ = local;
-                let LocalDecl { ty, span, .. } = decl;
-                self.visit_ty(ty, Location(*span));
-            }
-
-            fn super_ret_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) {
-                self.super_local_decl(local, decl)
-            }
-
-            fn super_arg_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) {
-                self.super_local_decl(local, decl)
-            }
-
-            fn super_statement(&mut self, stmt: &$($mutability)? Statement, location: Location) {
-                let Statement { kind, span } = stmt;
-                self.visit_span(span);
-                match kind {
-                    StatementKind::Assign(place, rvalue) => {
-                        self.visit_place(place, PlaceContext::MUTATING, location);
-                        self.visit_rvalue(rvalue, location);
-                    }
-                    StatementKind::FakeRead(_, place) | StatementKind::PlaceMention(place) => {
-                        self.visit_place(place, PlaceContext::NON_MUTATING, location);
-                    }
-                    StatementKind::SetDiscriminant { place, .. }
-                    | StatementKind::Deinit(place)
-                    | StatementKind::Retag(_, place) => {
-                        self.visit_place(place, PlaceContext::MUTATING, location);
-                    }
-                    StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
-                        self.visit_local(local, PlaceContext::NON_USE, location);
-                    }
-                    StatementKind::AscribeUserType { place, projections, variance: _ } => {
-                        self.visit_place(place, PlaceContext::NON_USE, location);
-                        self.visit_user_type_projection(projections);
-                    }
-                    StatementKind::Coverage(coverage) => visit_opaque(coverage),
-                    StatementKind::Intrinsic(intrisic) => match intrisic {
-                        NonDivergingIntrinsic::Assume(operand) => {
-                            self.visit_operand(operand, location);
-                        }
-                        NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
-                            src,
-                            dst,
-                            count,
-                        }) => {
-                            self.visit_operand(src, location);
-                            self.visit_operand(dst, location);
-                            self.visit_operand(count, location);
-                        }
-                    },
-                    StatementKind::ConstEvalCounter | StatementKind::Nop => {}
-                }
-            }
-
-            fn super_terminator(&mut self, term: &$($mutability)? Terminator, location: Location) {
-                let Terminator { kind, span } = term;
-                self.visit_span(span);
-                match kind {
-                    TerminatorKind::Goto { .. }
-                    | TerminatorKind::Resume
-                    | TerminatorKind::Abort
-                    | TerminatorKind::Unreachable => {}
-                    TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
-                        self.visit_operand(cond, location);
-                        self.visit_assert_msg(msg, location);
-                    }
-                    TerminatorKind::Drop { place, target: _, unwind: _ } => {
-                        self.visit_place(place, PlaceContext::MUTATING, location);
-                    }
-                    TerminatorKind::Call { func, args, destination, target: _, unwind: _ } => {
-                        self.visit_operand(func, location);
-                        for arg in args {
-                            self.visit_operand(arg, location);
-                        }
-                        self.visit_place(destination, PlaceContext::MUTATING, location);
-                    }
-                    TerminatorKind::InlineAsm { operands, .. } => {
-                        for op in operands {
-                            let InlineAsmOperand { in_value, out_place, raw_rpr: _ } = op;
-                            if let Some(input) = in_value {
-                                self.visit_operand(input, location);
-                            }
-                            if let Some(output) = out_place {
-                                self.visit_place(output, PlaceContext::MUTATING, location);
-                            }
-                        }
-                    }
-                    TerminatorKind::Return => {
-                        let $($mutability)? local = RETURN_LOCAL;
-                        self.visit_local(&$($mutability)? local, PlaceContext::NON_MUTATING, location);
-                    }
-                    TerminatorKind::SwitchInt { discr, targets: _ } => {
-                        self.visit_operand(discr, location);
-                    }
-                }
-            }
-
-            fn super_span(&mut self, span: &$($mutability)? Span) {
-                let _ = span;
-            }
-
-            fn super_rvalue(&mut self, rvalue: &$($mutability)? Rvalue, location: Location) {
-                match rvalue {
-                    Rvalue::AddressOf(mutability, place) => {
-                        let pcx = PlaceContext { is_mut: *mutability == RawPtrKind::Mut };
-                        self.visit_place(place, pcx, location);
-                    }
-                    Rvalue::Aggregate(_, operands) => {
-                        for op in operands {
-                            self.visit_operand(op, location);
-                        }
-                    }
-                    Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
-                        self.visit_operand(lhs, location);
-                        self.visit_operand(rhs, location);
-                    }
-                    Rvalue::Cast(_, op, ty) => {
-                        self.visit_operand(op, location);
-                        self.visit_ty(ty, location);
-                    }
-                    Rvalue::CopyForDeref(place) | Rvalue::Discriminant(place) | Rvalue::Len(place) => {
-                        self.visit_place(place, PlaceContext::NON_MUTATING, location);
-                    }
-                    Rvalue::Ref(region, kind, place) => {
-                        self.visit_region(region, location);
-                        let pcx = PlaceContext { is_mut: matches!(kind, BorrowKind::Mut { .. }) };
-                        self.visit_place(place, pcx, location);
-                    }
-                    Rvalue::Repeat(op, constant) => {
-                        self.visit_operand(op, location);
-                        self.visit_ty_const(constant, location);
-                    }
-                    Rvalue::ShallowInitBox(op, ty) => {
-                        self.visit_ty(ty, location);
-                        self.visit_operand(op, location)
-                    }
-                    Rvalue::ThreadLocalRef(_) => {}
-                    Rvalue::NullaryOp(_, ty) => {
-                        self.visit_ty(ty, location);
-                    }
-                    Rvalue::UnaryOp(_, op) | Rvalue::Use(op) => {
-                        self.visit_operand(op, location);
-                    }
-                }
-            }
-
-            fn super_operand(&mut self, operand: &$($mutability)? Operand, location: Location) {
-                match operand {
-                    Operand::Copy(place) | Operand::Move(place) => {
-                        self.visit_place(place, PlaceContext::NON_MUTATING, location)
-                    }
-                    Operand::Constant(constant) => {
-                        self.visit_const_operand(constant, location);
-                    }
-                }
-            }
-
-            fn super_user_type_projection(&mut self, projection: &$($mutability)? UserTypeProjection) {
-                // This is a no-op on mir::Visitor.
-                let _ = projection;
-            }
-
-            fn super_ty(&mut self, ty: &$($mutability)? Ty) {
-                let _ = ty;
-            }
-
-            fn super_const_operand(&mut self, constant: &$($mutability)? ConstOperand, location: Location) {
-                let ConstOperand { span, user_ty: _, const_ } = constant;
-                self.visit_span(span);
-                self.visit_mir_const(const_, location);
-            }
-
-            fn super_mir_const(&mut self, constant: &$($mutability)? MirConst, location: Location) {
-                let MirConst { kind: _, ty, id: _ } = constant;
-                self.visit_ty(ty, location);
-            }
-
-            fn super_ty_const(&mut self, constant: &$($mutability)? TyConst) {
-                let _ = constant;
-            }
-
-            fn super_region(&mut self, region: &$($mutability)? Region) {
-                let _ = region;
-            }
-
-            fn super_args(&mut self, args: &$($mutability)? GenericArgs) {
-                let _ = args;
-            }
-
-            fn super_var_debug_info(&mut self, var_debug_info: &$($mutability)? VarDebugInfo) {
-                let VarDebugInfo { source_info, composite, value, name: _, argument_index: _ } =
-                    var_debug_info;
-                self.visit_span(&$($mutability)? source_info.span);
-                let location = Location(source_info.span);
-                if let Some(composite) = composite {
-                    self.visit_ty(&$($mutability)? composite.ty, location);
-                }
-                match value {
-                    VarDebugInfoContents::Place(place) => {
-                        self.visit_place(place, PlaceContext::NON_USE, location);
-                    }
-                    VarDebugInfoContents::Const(constant) => {
-                        self.visit_mir_const(&$($mutability)? constant.const_, location);
-                    }
-                }
-            }
-
-            fn super_assert_msg(&mut self, msg: &$($mutability)? AssertMessage, location: Location) {
-                match msg {
-                    AssertMessage::BoundsCheck { len, index } => {
-                        self.visit_operand(len, location);
-                        self.visit_operand(index, location);
-                    }
-                    AssertMessage::Overflow(_, left, right) => {
-                        self.visit_operand(left, location);
-                        self.visit_operand(right, location);
-                    }
-                    AssertMessage::OverflowNeg(op)
-                    | AssertMessage::DivisionByZero(op)
-                    | AssertMessage::RemainderByZero(op) => {
-                        self.visit_operand(op, location);
-                    }
-                    AssertMessage::ResumedAfterReturn(_)
-                    | AssertMessage::ResumedAfterPanic(_)
-                    | AssertMessage::NullPointerDereference => {
-                        //nothing to visit
-                    }
-                    AssertMessage::MisalignedPointerDereference { required, found } => {
-                        self.visit_operand(required, location);
-                        self.visit_operand(found, location);
-                    }
-                }
-            }
-        }
-    };
-}
-
-macro_rules! super_body {
-    ($self:ident, $body:ident, mut) => {
-        for bb in $body.blocks.iter_mut() {
-            $self.visit_basic_block(bb);
-        }
-
-        $self.visit_ret_decl(RETURN_LOCAL, $body.ret_local_mut());
-
-        for (idx, arg) in $body.arg_locals_mut().iter_mut().enumerate() {
-            $self.visit_arg_decl(idx + 1, arg)
-        }
-
-        let local_start = $body.arg_count + 1;
-        for (idx, arg) in $body.inner_locals_mut().iter_mut().enumerate() {
-            $self.visit_local_decl(idx + local_start, arg)
-        }
-
-        for info in $body.var_debug_info.iter_mut() {
-            $self.visit_var_debug_info(info);
-        }
-
-        $self.visit_span(&mut $body.span)
-    };
-
-    ($self:ident, $body:ident, ) => {
-        let Body { blocks, locals: _, arg_count, var_debug_info, spread_arg: _, span } = $body;
-
-        for bb in blocks {
-            $self.visit_basic_block(bb);
-        }
-
-        $self.visit_ret_decl(RETURN_LOCAL, $body.ret_local());
-
-        for (idx, arg) in $body.arg_locals().iter().enumerate() {
-            $self.visit_arg_decl(idx + 1, arg)
-        }
-
-        let local_start = arg_count + 1;
-        for (idx, arg) in $body.inner_locals().iter().enumerate() {
-            $self.visit_local_decl(idx + local_start, arg)
-        }
-
-        for info in var_debug_info.iter() {
-            $self.visit_var_debug_info(info);
-        }
-
-        $self.visit_span(span)
-    };
-}
-
-macro_rules! visit_place_fns {
-    (mut) => {
-        fn super_place(&mut self, place: &mut Place, ptx: PlaceContext, location: Location) {
-            self.visit_local(&mut place.local, ptx, location);
-
-            for elem in place.projection.iter_mut() {
-                self.visit_projection_elem(elem, ptx, location);
-            }
-        }
-
-        // We don't have to replicate the `process_projection()` like we did in
-        // `rustc_middle::mir::visit.rs` here because the `projection` field in `Place`
-        // of Stable-MIR is not an immutable borrow, unlike in `Place` of MIR.
-        fn visit_projection_elem(
-            &mut self,
-            elem: &mut ProjectionElem,
-            ptx: PlaceContext,
-            location: Location,
-        ) {
-            self.super_projection_elem(elem, ptx, location)
-        }
-
-        fn super_projection_elem(
-            &mut self,
-            elem: &mut ProjectionElem,
-            ptx: PlaceContext,
-            location: Location,
-        ) {
-            match elem {
-                ProjectionElem::Deref => {}
-                ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location),
-                ProjectionElem::Index(local) => self.visit_local(local, ptx, location),
-                ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {}
-                ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {}
-                ProjectionElem::Downcast(_idx) => {}
-                ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location),
-                ProjectionElem::Subtype(ty) => self.visit_ty(ty, location),
-            }
-        }
-    };
-
-    () => {
-        fn super_place(&mut self, place: &Place, ptx: PlaceContext, location: Location) {
-            self.visit_local(&place.local, ptx, location);
-
-            for (idx, elem) in place.projection.iter().enumerate() {
-                let place_ref =
-                    PlaceRef { local: place.local, projection: &place.projection[..idx] };
-                self.visit_projection_elem(place_ref, elem, ptx, location);
-            }
-        }
-
-        fn visit_projection_elem<'a>(
-            &mut self,
-            place_ref: PlaceRef<'a>,
-            elem: &ProjectionElem,
-            ptx: PlaceContext,
-            location: Location,
-        ) {
-            let _ = place_ref;
-            self.super_projection_elem(elem, ptx, location);
-        }
-
-        fn super_projection_elem(
-            &mut self,
-            elem: &ProjectionElem,
-            ptx: PlaceContext,
-            location: Location,
-        ) {
-            match elem {
-                ProjectionElem::Deref => {}
-                ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location),
-                ProjectionElem::Index(local) => self.visit_local(local, ptx, location),
-                ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {}
-                ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {}
-                ProjectionElem::Downcast(_idx) => {}
-                ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location),
-                ProjectionElem::Subtype(ty) => self.visit_ty(ty, location),
-            }
-        }
-    };
-}
-
-make_mir_visitor!(MirVisitor,);
-make_mir_visitor!(MutMirVisitor, mut);
-
-/// This function is a no-op that gets used to ensure this visitor is kept up-to-date.
-///
-/// The idea is that whenever we replace an Opaque type by a real type, the compiler will fail
-/// when trying to invoke `visit_opaque`.
-///
-/// If you are here because your compilation is broken, replace the failing call to `visit_opaque()`
-/// by a `visit_<CONSTRUCT>` for your construct.
-fn visit_opaque(_: &Opaque) {}
-
-/// The location of a statement / terminator in the code and the CFG.
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct Location(Span);
-
-impl Location {
-    pub fn span(&self) -> Span {
-        self.0
-    }
-}
-
-/// Location of the statement at the given index for a given basic block. Assumes that `stmt_idx`
-/// and `bb_idx` are valid for a given body.
-pub fn statement_location(body: &Body, bb_idx: &BasicBlockIdx, stmt_idx: usize) -> Location {
-    let bb = &body.blocks[*bb_idx];
-    let stmt = &bb.statements[stmt_idx];
-    Location(stmt.span)
-}
-
-/// Location of the terminator for a given basic block. Assumes that `bb_idx` is valid for a given
-/// body.
-pub fn terminator_location(body: &Body, bb_idx: &BasicBlockIdx) -> Location {
-    let bb = &body.blocks[*bb_idx];
-    let terminator = &bb.terminator;
-    Location(terminator.span)
-}
-
-/// Reference to a place used to represent a partial projection.
-pub struct PlaceRef<'a> {
-    pub local: Local,
-    pub projection: &'a [ProjectionElem],
-}
-
-impl PlaceRef<'_> {
-    /// Get the type of this place.
-    pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
-        self.projection.iter().try_fold(locals[self.local].ty, |place_ty, elem| elem.ty(place_ty))
-    }
-}
-
-/// Information about a place's usage.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct PlaceContext {
-    /// Whether the access is mutable or not. Keep this private so we can increment the type in a
-    /// backward compatible manner.
-    is_mut: bool,
-}
-
-impl PlaceContext {
-    const MUTATING: Self = PlaceContext { is_mut: true };
-    const NON_MUTATING: Self = PlaceContext { is_mut: false };
-    const NON_USE: Self = PlaceContext { is_mut: false };
-
-    pub fn is_mutating(&self) -> bool {
-        self.is_mut
-    }
-}
diff --git a/compiler/stable_mir/src/target.rs b/compiler/stable_mir/src/target.rs
deleted file mode 100644
index 32c3a2a9122..00000000000
--- a/compiler/stable_mir/src/target.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-//! Provide information about the machine that this is being compiled into.
-
-use serde::Serialize;
-
-use crate::compiler_interface::with;
-
-/// The properties of the target machine being compiled into.
-#[derive(Clone, PartialEq, Eq, Serialize)]
-pub struct MachineInfo {
-    pub endian: Endian,
-    pub pointer_width: MachineSize,
-}
-
-impl MachineInfo {
-    pub fn target() -> MachineInfo {
-        with(|cx| cx.target_info())
-    }
-
-    pub fn target_endianness() -> Endian {
-        with(|cx| cx.target_info().endian)
-    }
-
-    pub fn target_pointer_width() -> MachineSize {
-        with(|cx| cx.target_info().pointer_width)
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Serialize)]
-pub enum Endian {
-    Little,
-    Big,
-}
-
-/// Represent the size of a component.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
-pub struct MachineSize {
-    num_bits: usize,
-}
-
-impl MachineSize {
-    #[inline(always)]
-    pub fn bytes(self) -> usize {
-        self.num_bits / 8
-    }
-
-    #[inline(always)]
-    pub fn bits(self) -> usize {
-        self.num_bits
-    }
-
-    #[inline(always)]
-    pub fn from_bits(num_bits: usize) -> MachineSize {
-        MachineSize { num_bits }
-    }
-
-    #[inline]
-    pub fn unsigned_int_max(self) -> Option<u128> {
-        (self.num_bits <= 128).then(|| u128::MAX >> (128 - self.bits()))
-    }
-}
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
deleted file mode 100644
index 25ec4a440d6..00000000000
--- a/compiler/stable_mir/src/ty.rs
+++ /dev/null
@@ -1,1622 +0,0 @@
-use std::fmt::{self, Debug, Display, Formatter};
-use std::ops::Range;
-
-use serde::Serialize;
-
-use super::mir::{Body, Mutability, Safety};
-use super::{DefId, Error, Symbol, with};
-use crate::abi::{FnAbi, Layout};
-use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType};
-use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
-use crate::mir::mono::StaticDef;
-use crate::target::MachineInfo;
-use crate::{Filename, Opaque};
-
-#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
-pub struct Ty(usize);
-
-impl Debug for Ty {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Ty").field("id", &self.0).field("kind", &self.kind()).finish()
-    }
-}
-
-/// Constructors for `Ty`.
-impl Ty {
-    /// Create a new type from a given kind.
-    pub fn from_rigid_kind(kind: RigidTy) -> Ty {
-        with(|cx| cx.new_rigid_ty(kind))
-    }
-
-    /// Create a new array type.
-    pub fn try_new_array(elem_ty: Ty, size: u64) -> Result<Ty, Error> {
-        Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, TyConst::try_from_target_usize(size)?)))
-    }
-
-    /// Create a new array type from Const length.
-    pub fn new_array_with_const_len(elem_ty: Ty, len: TyConst) -> Ty {
-        Ty::from_rigid_kind(RigidTy::Array(elem_ty, len))
-    }
-
-    /// Create a new pointer type.
-    pub fn new_ptr(pointee_ty: Ty, mutability: Mutability) -> Ty {
-        Ty::from_rigid_kind(RigidTy::RawPtr(pointee_ty, mutability))
-    }
-
-    /// Create a new reference type.
-    pub fn new_ref(reg: Region, pointee_ty: Ty, mutability: Mutability) -> Ty {
-        Ty::from_rigid_kind(RigidTy::Ref(reg, pointee_ty, mutability))
-    }
-
-    /// Create a new pointer type.
-    pub fn new_tuple(tys: &[Ty]) -> Ty {
-        Ty::from_rigid_kind(RigidTy::Tuple(Vec::from(tys)))
-    }
-
-    /// Create a new closure type.
-    pub fn new_closure(def: ClosureDef, args: GenericArgs) -> Ty {
-        Ty::from_rigid_kind(RigidTy::Closure(def, args))
-    }
-
-    /// Create a new coroutine type.
-    pub fn new_coroutine(def: CoroutineDef, args: GenericArgs, mov: Movability) -> Ty {
-        Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
-    }
-
-    /// Create a new closure type.
-    pub fn new_coroutine_closure(def: CoroutineClosureDef, args: GenericArgs) -> Ty {
-        Ty::from_rigid_kind(RigidTy::CoroutineClosure(def, args))
-    }
-
-    /// Create a new box type that represents `Box<T>`, for the given inner type `T`.
-    pub fn new_box(inner_ty: Ty) -> Ty {
-        with(|cx| cx.new_box_ty(inner_ty))
-    }
-
-    /// Create a type representing `usize`.
-    pub fn usize_ty() -> Ty {
-        Ty::from_rigid_kind(RigidTy::Uint(UintTy::Usize))
-    }
-
-    /// Create a type representing `bool`.
-    pub fn bool_ty() -> Ty {
-        Ty::from_rigid_kind(RigidTy::Bool)
-    }
-
-    /// Create a type representing a signed integer.
-    pub fn signed_ty(inner: IntTy) -> Ty {
-        Ty::from_rigid_kind(RigidTy::Int(inner))
-    }
-
-    /// Create a type representing an unsigned integer.
-    pub fn unsigned_ty(inner: UintTy) -> Ty {
-        Ty::from_rigid_kind(RigidTy::Uint(inner))
-    }
-
-    /// Get a type layout.
-    pub fn layout(self) -> Result<Layout, Error> {
-        with(|cx| cx.ty_layout(self))
-    }
-}
-
-impl Ty {
-    pub fn kind(&self) -> TyKind {
-        with(|context| context.ty_kind(*self))
-    }
-}
-
-/// Represents a pattern in the type system
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum Pattern {
-    Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
-}
-
-/// Represents a constant in the type system
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct TyConst {
-    pub(crate) kind: TyConstKind,
-    pub id: TyConstId,
-}
-
-impl TyConst {
-    pub fn new(kind: TyConstKind, id: TyConstId) -> TyConst {
-        Self { kind, id }
-    }
-
-    /// Retrieve the constant kind.
-    pub fn kind(&self) -> &TyConstKind {
-        &self.kind
-    }
-
-    /// Creates an interned usize constant.
-    pub fn try_from_target_usize(val: u64) -> Result<Self, Error> {
-        with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize))
-    }
-
-    /// Try to evaluate to a target `usize`.
-    pub fn eval_target_usize(&self) -> Result<u64, Error> {
-        with(|cx| cx.eval_target_usize_ty(self))
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum TyConstKind {
-    Param(ParamConst),
-    Bound(DebruijnIndex, BoundVar),
-    Unevaluated(ConstDef, GenericArgs),
-
-    // FIXME: These should be a valtree
-    Value(Ty, Allocation),
-    ZSTValue(Ty),
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct TyConstId(usize);
-
-/// Represents a constant in MIR
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct MirConst {
-    /// The constant kind.
-    pub(crate) kind: ConstantKind,
-    /// The constant type.
-    pub(crate) ty: Ty,
-    /// Used for internal tracking of the internal constant.
-    pub id: MirConstId,
-}
-
-impl MirConst {
-    /// Build a constant. Note that this should only be used by the compiler.
-    pub fn new(kind: ConstantKind, ty: Ty, id: MirConstId) -> MirConst {
-        MirConst { kind, ty, id }
-    }
-
-    /// Retrieve the constant kind.
-    pub fn kind(&self) -> &ConstantKind {
-        &self.kind
-    }
-
-    /// Get the constant type.
-    pub fn ty(&self) -> Ty {
-        self.ty
-    }
-
-    /// Try to evaluate to a target `usize`.
-    pub fn eval_target_usize(&self) -> Result<u64, Error> {
-        with(|cx| cx.eval_target_usize(self))
-    }
-
-    /// Create a constant that represents a new zero-sized constant of type T.
-    /// Fails if the type is not a ZST or if it doesn't have a known size.
-    pub fn try_new_zero_sized(ty: Ty) -> Result<MirConst, Error> {
-        with(|cx| cx.try_new_const_zst(ty))
-    }
-
-    /// Build a new constant that represents the given string.
-    ///
-    /// Note that there is no guarantee today about duplication of the same constant.
-    /// I.e.: Calling this function multiple times with the same argument may or may not return
-    /// the same allocation.
-    pub fn from_str(value: &str) -> MirConst {
-        with(|cx| cx.new_const_str(value))
-    }
-
-    /// Build a new constant that represents the given boolean value.
-    pub fn from_bool(value: bool) -> MirConst {
-        with(|cx| cx.new_const_bool(value))
-    }
-
-    /// Build a new constant that represents the given unsigned integer.
-    pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
-        with(|cx| cx.try_new_const_uint(value, uint_ty))
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
-pub struct MirConstId(usize);
-
-type Ident = Opaque;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct Region {
-    pub kind: RegionKind,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum RegionKind {
-    ReEarlyParam(EarlyParamRegion),
-    ReBound(DebruijnIndex, BoundRegion),
-    ReStatic,
-    RePlaceholder(Placeholder<BoundRegion>),
-    ReErased,
-}
-
-pub(crate) type DebruijnIndex = u32;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct EarlyParamRegion {
-    pub index: u32,
-    pub name: Symbol,
-}
-
-pub(crate) type BoundVar = u32;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct BoundRegion {
-    pub var: BoundVar,
-    pub kind: BoundRegionKind,
-}
-
-pub(crate) type UniverseIndex = u32;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct Placeholder<T> {
-    pub universe: UniverseIndex,
-    pub bound: T,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Serialize)]
-pub struct Span(usize);
-
-impl Debug for Span {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Span")
-            .field("id", &self.0)
-            .field("repr", &with(|cx| cx.span_to_string(*self)))
-            .finish()
-    }
-}
-
-impl Span {
-    /// Return filename for diagnostic purposes
-    pub fn get_filename(&self) -> Filename {
-        with(|c| c.get_filename(self))
-    }
-
-    /// Return lines that correspond to this `Span`
-    pub fn get_lines(&self) -> LineInfo {
-        with(|c| c.get_lines(self))
-    }
-
-    /// Return the span location to be printed in diagnostic messages.
-    ///
-    /// This may leak local file paths and should not be used to build artifacts that may be
-    /// distributed.
-    pub fn diagnostic(&self) -> String {
-        with(|c| c.span_to_string(*self))
-    }
-}
-
-#[derive(Clone, Copy, Debug, Serialize)]
-/// Information you get from `Span` in a struct form.
-/// Line and col start from 1.
-pub struct LineInfo {
-    pub start_line: usize,
-    pub start_col: usize,
-    pub end_line: usize,
-    pub end_col: usize,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum TyKind {
-    RigidTy(RigidTy),
-    Alias(AliasKind, AliasTy),
-    Param(ParamTy),
-    Bound(usize, BoundTy),
-}
-
-impl TyKind {
-    pub fn rigid(&self) -> Option<&RigidTy> {
-        if let TyKind::RigidTy(inner) = self { Some(inner) } else { None }
-    }
-
-    #[inline]
-    pub fn is_unit(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Tuple(data)) if data.is_empty())
-    }
-
-    #[inline]
-    pub fn is_bool(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Bool))
-    }
-
-    #[inline]
-    pub fn is_char(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Char))
-    }
-
-    #[inline]
-    pub fn is_trait(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Dynamic(_, _, DynKind::Dyn)))
-    }
-
-    #[inline]
-    pub fn is_enum(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Enum)
-    }
-
-    #[inline]
-    pub fn is_struct(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Struct)
-    }
-
-    #[inline]
-    pub fn is_union(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Union)
-    }
-
-    #[inline]
-    pub fn is_adt(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Adt(..)))
-    }
-
-    #[inline]
-    pub fn is_ref(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Ref(..)))
-    }
-
-    #[inline]
-    pub fn is_fn(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::FnDef(..)))
-    }
-
-    #[inline]
-    pub fn is_fn_ptr(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::FnPtr(..)))
-    }
-
-    #[inline]
-    pub fn is_primitive(&self) -> bool {
-        matches!(
-            self,
-            TyKind::RigidTy(
-                RigidTy::Bool
-                    | RigidTy::Char
-                    | RigidTy::Int(_)
-                    | RigidTy::Uint(_)
-                    | RigidTy::Float(_)
-            )
-        )
-    }
-
-    #[inline]
-    pub fn is_float(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Float(_)))
-    }
-
-    #[inline]
-    pub fn is_integral(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Int(_) | RigidTy::Uint(_)))
-    }
-
-    #[inline]
-    pub fn is_numeric(&self) -> bool {
-        self.is_integral() || self.is_float()
-    }
-
-    #[inline]
-    pub fn is_signed(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Int(_)))
-    }
-
-    #[inline]
-    pub fn is_str(&self) -> bool {
-        *self == TyKind::RigidTy(RigidTy::Str)
-    }
-
-    #[inline]
-    pub fn is_cstr(&self) -> bool {
-        let TyKind::RigidTy(RigidTy::Adt(def, _)) = self else {
-            return false;
-        };
-        with(|cx| cx.adt_is_cstr(*def))
-    }
-
-    #[inline]
-    pub fn is_slice(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Slice(_)))
-    }
-
-    #[inline]
-    pub fn is_array(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Array(..)))
-    }
-
-    #[inline]
-    pub fn is_mutable_ptr(&self) -> bool {
-        matches!(
-            self,
-            TyKind::RigidTy(RigidTy::RawPtr(_, Mutability::Mut))
-                | TyKind::RigidTy(RigidTy::Ref(_, _, Mutability::Mut))
-        )
-    }
-
-    #[inline]
-    pub fn is_raw_ptr(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::RawPtr(..)))
-    }
-
-    /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
-    #[inline]
-    pub fn is_any_ptr(&self) -> bool {
-        self.is_ref() || self.is_raw_ptr() || self.is_fn_ptr()
-    }
-
-    #[inline]
-    pub fn is_coroutine(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Coroutine(..)))
-    }
-
-    #[inline]
-    pub fn is_closure(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Closure(..)))
-    }
-
-    #[inline]
-    pub fn is_box(&self) -> bool {
-        match self {
-            TyKind::RigidTy(RigidTy::Adt(def, _)) => def.is_box(),
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_simd(&self) -> bool {
-        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.is_simd())
-    }
-
-    pub fn trait_principal(&self) -> Option<Binder<ExistentialTraitRef>> {
-        if let TyKind::RigidTy(RigidTy::Dynamic(predicates, _, _)) = self {
-            if let Some(Binder { value: ExistentialPredicate::Trait(trait_ref), bound_vars }) =
-                predicates.first()
-            {
-                Some(Binder { value: trait_ref.clone(), bound_vars: bound_vars.clone() })
-            } else {
-                None
-            }
-        } else {
-            None
-        }
-    }
-
-    /// Returns the type of `ty[i]` for builtin types.
-    pub fn builtin_index(&self) -> Option<Ty> {
-        match self.rigid()? {
-            RigidTy::Array(ty, _) | RigidTy::Slice(ty) => Some(*ty),
-            _ => None,
-        }
-    }
-
-    /// Returns the type and mutability of `*ty` for builtin types.
-    ///
-    /// The parameter `explicit` indicates if this is an *explicit* dereference.
-    /// Some types -- notably raw ptrs -- can only be dereferenced explicitly.
-    pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut> {
-        match self.rigid()? {
-            RigidTy::Adt(def, args) if def.is_box() => {
-                Some(TypeAndMut { ty: *args.0.first()?.ty()?, mutability: Mutability::Not })
-            }
-            RigidTy::Ref(_, ty, mutability) => {
-                Some(TypeAndMut { ty: *ty, mutability: *mutability })
-            }
-            RigidTy::RawPtr(ty, mutability) if explicit => {
-                Some(TypeAndMut { ty: *ty, mutability: *mutability })
-            }
-            _ => None,
-        }
-    }
-
-    /// Get the function signature for function like types (Fn, FnPtr, and Closure)
-    pub fn fn_sig(&self) -> Option<PolyFnSig> {
-        match self {
-            TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
-            TyKind::RigidTy(RigidTy::FnPtr(sig)) => Some(sig.clone()),
-            TyKind::RigidTy(RigidTy::Closure(_def, args)) => Some(with(|cx| cx.closure_sig(args))),
-            _ => None,
-        }
-    }
-
-    /// Get the discriminant type for this type.
-    pub fn discriminant_ty(&self) -> Option<Ty> {
-        self.rigid().map(|ty| with(|cx| cx.rigid_ty_discriminant_ty(ty)))
-    }
-
-    /// Deconstruct a function type if this is one.
-    pub fn fn_def(&self) -> Option<(FnDef, &GenericArgs)> {
-        if let TyKind::RigidTy(RigidTy::FnDef(def, args)) = self {
-            Some((*def, args))
-        } else {
-            None
-        }
-    }
-}
-
-pub struct TypeAndMut {
-    pub ty: Ty,
-    pub mutability: Mutability,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum RigidTy {
-    Bool,
-    Char,
-    Int(IntTy),
-    Uint(UintTy),
-    Float(FloatTy),
-    Adt(AdtDef, GenericArgs),
-    Foreign(ForeignDef),
-    Str,
-    Array(Ty, TyConst),
-    Pat(Ty, Pattern),
-    Slice(Ty),
-    RawPtr(Ty, Mutability),
-    Ref(Region, Ty, Mutability),
-    FnDef(FnDef, GenericArgs),
-    FnPtr(PolyFnSig),
-    Closure(ClosureDef, GenericArgs),
-    // FIXME(stable_mir): Movability here is redundant
-    Coroutine(CoroutineDef, GenericArgs, Movability),
-    CoroutineClosure(CoroutineClosureDef, GenericArgs),
-    Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
-    Never,
-    Tuple(Vec<Ty>),
-    CoroutineWitness(CoroutineWitnessDef, GenericArgs),
-}
-
-impl RigidTy {
-    /// Get the discriminant type for this type.
-    pub fn discriminant_ty(&self) -> Ty {
-        with(|cx| cx.rigid_ty_discriminant_ty(self))
-    }
-}
-
-impl From<RigidTy> for TyKind {
-    fn from(value: RigidTy) -> Self {
-        TyKind::RigidTy(value)
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
-pub enum IntTy {
-    Isize,
-    I8,
-    I16,
-    I32,
-    I64,
-    I128,
-}
-
-impl IntTy {
-    pub fn num_bytes(self) -> usize {
-        match self {
-            IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes(),
-            IntTy::I8 => 1,
-            IntTy::I16 => 2,
-            IntTy::I32 => 4,
-            IntTy::I64 => 8,
-            IntTy::I128 => 16,
-        }
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
-pub enum UintTy {
-    Usize,
-    U8,
-    U16,
-    U32,
-    U64,
-    U128,
-}
-
-impl UintTy {
-    pub fn num_bytes(self) -> usize {
-        match self {
-            UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes(),
-            UintTy::U8 => 1,
-            UintTy::U16 => 2,
-            UintTy::U32 => 4,
-            UintTy::U64 => 8,
-            UintTy::U128 => 16,
-        }
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
-pub enum FloatTy {
-    F16,
-    F32,
-    F64,
-    F128,
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
-pub enum Movability {
-    Static,
-    Movable,
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub ForeignModuleDef;
-}
-
-impl ForeignModuleDef {
-    pub fn module(&self) -> ForeignModule {
-        with(|cx| cx.foreign_module(*self))
-    }
-}
-
-pub struct ForeignModule {
-    pub def_id: ForeignModuleDef,
-    pub abi: Abi,
-}
-
-impl ForeignModule {
-    pub fn items(&self) -> Vec<ForeignDef> {
-        with(|cx| cx.foreign_items(self.def_id))
-    }
-}
-
-crate_def_with_ty! {
-    /// Hold information about a ForeignItem in a crate.
-    #[derive(Serialize)]
-    pub ForeignDef;
-}
-
-impl ForeignDef {
-    pub fn kind(&self) -> ForeignItemKind {
-        with(|cx| cx.foreign_item_kind(*self))
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
-pub enum ForeignItemKind {
-    Fn(FnDef),
-    Static(StaticDef),
-    Type(Ty),
-}
-
-crate_def_with_ty! {
-    /// Hold information about a function definition in a crate.
-    #[derive(Serialize)]
-    pub FnDef;
-}
-
-impl FnDef {
-    // Get the function body if available.
-    pub fn body(&self) -> Option<Body> {
-        with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
-    }
-
-    // Check if the function body is available.
-    pub fn has_body(&self) -> bool {
-        with(|ctx| ctx.has_body(self.0))
-    }
-
-    /// Get the information of the intrinsic if this function is a definition of one.
-    pub fn as_intrinsic(&self) -> Option<IntrinsicDef> {
-        with(|cx| cx.intrinsic(self.def_id()))
-    }
-
-    /// Check if the function is an intrinsic.
-    #[inline]
-    pub fn is_intrinsic(&self) -> bool {
-        self.as_intrinsic().is_some()
-    }
-
-    /// Get the function signature for this function definition.
-    pub fn fn_sig(&self) -> PolyFnSig {
-        let kind = self.ty().kind();
-        kind.fn_sig().unwrap()
-    }
-}
-
-crate_def_with_ty! {
-    #[derive(Serialize)]
-    pub IntrinsicDef;
-}
-
-impl IntrinsicDef {
-    /// Returns the plain name of the intrinsic.
-    /// e.g., `transmute` for `core::intrinsics::transmute`.
-    pub fn fn_name(&self) -> Symbol {
-        with(|cx| cx.intrinsic_name(*self))
-    }
-
-    /// Returns whether the intrinsic has no meaningful body and all backends
-    /// need to shim all calls to it.
-    pub fn must_be_overridden(&self) -> bool {
-        with(|cx| !cx.has_body(self.0))
-    }
-}
-
-impl From<IntrinsicDef> for FnDef {
-    fn from(def: IntrinsicDef) -> Self {
-        FnDef(def.0)
-    }
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub ClosureDef;
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub CoroutineDef;
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub CoroutineClosureDef;
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub ParamDef;
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub BrNamedDef;
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub AdtDef;
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
-pub enum AdtKind {
-    Enum,
-    Union,
-    Struct,
-}
-
-impl AdtDef {
-    pub fn kind(&self) -> AdtKind {
-        with(|cx| cx.adt_kind(*self))
-    }
-
-    /// Retrieve the type of this Adt.
-    pub fn ty(&self) -> Ty {
-        with(|cx| cx.def_ty(self.0))
-    }
-
-    /// Retrieve the type of this Adt by instantiating and normalizing it with the given arguments.
-    ///
-    /// This will assume the type can be instantiated with these arguments.
-    pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
-        with(|cx| cx.def_ty_with_args(self.0, args))
-    }
-
-    pub fn is_box(&self) -> bool {
-        with(|cx| cx.adt_is_box(*self))
-    }
-
-    pub fn is_simd(&self) -> bool {
-        with(|cx| cx.adt_is_simd(*self))
-    }
-
-    /// The number of variants in this ADT.
-    pub fn num_variants(&self) -> usize {
-        with(|cx| cx.adt_variants_len(*self))
-    }
-
-    /// Retrieve the variants in this ADT.
-    pub fn variants(&self) -> Vec<VariantDef> {
-        self.variants_iter().collect()
-    }
-
-    /// Iterate over the variants in this ADT.
-    pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> {
-        (0..self.num_variants())
-            .map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
-    }
-
-    pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
-        (idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
-    }
-}
-
-/// Definition of a variant, which can be either a struct / union field or an enum variant.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct VariantDef {
-    /// The variant index.
-    ///
-    /// ## Warning
-    /// Do not access this field directly!
-    pub idx: VariantIdx,
-    /// The data type where this variant comes from.
-    /// For now, we use this to retrieve information about the variant itself so we don't need to
-    /// cache more information.
-    ///
-    /// ## Warning
-    /// Do not access this field directly!
-    pub adt_def: AdtDef,
-}
-
-impl VariantDef {
-    pub fn name(&self) -> Symbol {
-        with(|cx| cx.variant_name(*self))
-    }
-
-    /// Retrieve all the fields in this variant.
-    // We expect user to cache this and use it directly since today it is expensive to generate all
-    // fields name.
-    pub fn fields(&self) -> Vec<FieldDef> {
-        with(|cx| cx.variant_fields(*self))
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct FieldDef {
-    /// The field definition.
-    ///
-    /// ## Warning
-    /// Do not access this field directly! This is public for the compiler to have access to it.
-    pub def: DefId,
-
-    /// The field name.
-    pub name: Symbol,
-}
-
-impl FieldDef {
-    /// Retrieve the type of this field instantiating and normalizing it with the given arguments.
-    ///
-    /// This will assume the type can be instantiated with these arguments.
-    pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
-        with(|cx| cx.def_ty_with_args(self.def, args))
-    }
-
-    /// Retrieve the type of this field.
-    pub fn ty(&self) -> Ty {
-        with(|cx| cx.def_ty(self.def))
-    }
-}
-
-impl Display for AdtKind {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        f.write_str(match self {
-            AdtKind::Enum => "enum",
-            AdtKind::Union => "union",
-            AdtKind::Struct => "struct",
-        })
-    }
-}
-
-impl AdtKind {
-    pub fn is_enum(&self) -> bool {
-        matches!(self, AdtKind::Enum)
-    }
-
-    pub fn is_struct(&self) -> bool {
-        matches!(self, AdtKind::Struct)
-    }
-
-    pub fn is_union(&self) -> bool {
-        matches!(self, AdtKind::Union)
-    }
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub AliasDef;
-}
-
-crate_def! {
-    /// A trait's definition.
-    #[derive(Serialize)]
-    pub TraitDef;
-}
-
-impl_crate_def_items! {
-    TraitDef;
-}
-
-impl TraitDef {
-    pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
-        with(|cx| cx.trait_decl(trait_def))
-    }
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub GenericDef;
-}
-
-crate_def_with_ty! {
-    #[derive(Serialize)]
-    pub ConstDef;
-}
-
-crate_def! {
-    /// A trait impl definition.
-    #[derive(Serialize)]
-    pub ImplDef;
-}
-
-impl_crate_def_items! {
-    ImplDef;
-}
-
-impl ImplDef {
-    /// Retrieve information about this implementation.
-    pub fn trait_impl(&self) -> ImplTrait {
-        with(|cx| cx.trait_impl(self))
-    }
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub RegionDef;
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub CoroutineWitnessDef;
-}
-
-/// A list of generic arguments.
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct GenericArgs(pub Vec<GenericArgKind>);
-
-impl std::ops::Index<ParamTy> for GenericArgs {
-    type Output = Ty;
-
-    fn index(&self, index: ParamTy) -> &Self::Output {
-        self.0[index.index as usize].expect_ty()
-    }
-}
-
-impl std::ops::Index<ParamConst> for GenericArgs {
-    type Output = TyConst;
-
-    fn index(&self, index: ParamConst) -> &Self::Output {
-        self.0[index.index as usize].expect_const()
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum GenericArgKind {
-    Lifetime(Region),
-    Type(Ty),
-    Const(TyConst),
-}
-
-impl GenericArgKind {
-    /// Panic if this generic argument is not a type, otherwise
-    /// return the type.
-    #[track_caller]
-    pub fn expect_ty(&self) -> &Ty {
-        match self {
-            GenericArgKind::Type(ty) => ty,
-            _ => panic!("{self:?}"),
-        }
-    }
-
-    /// Panic if this generic argument is not a const, otherwise
-    /// return the const.
-    #[track_caller]
-    pub fn expect_const(&self) -> &TyConst {
-        match self {
-            GenericArgKind::Const(c) => c,
-            _ => panic!("{self:?}"),
-        }
-    }
-
-    /// Return the generic argument type if applicable, otherwise return `None`.
-    pub fn ty(&self) -> Option<&Ty> {
-        match self {
-            GenericArgKind::Type(ty) => Some(ty),
-            _ => None,
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum TermKind {
-    Type(Ty),
-    Const(TyConst),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum AliasKind {
-    Projection,
-    Inherent,
-    Opaque,
-    Weak,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct AliasTy {
-    pub def_id: AliasDef,
-    pub args: GenericArgs,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct AliasTerm {
-    pub def_id: AliasDef,
-    pub args: GenericArgs,
-}
-
-pub type PolyFnSig = Binder<FnSig>;
-
-impl PolyFnSig {
-    /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
-    ///
-    /// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi`
-    /// instead, where the instance is an `InstanceKind::Virtual`.
-    pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
-        with(|cx| cx.fn_ptr_abi(self))
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct FnSig {
-    pub inputs_and_output: Vec<Ty>,
-    pub c_variadic: bool,
-    pub safety: Safety,
-    pub abi: Abi,
-}
-
-impl FnSig {
-    pub fn output(&self) -> Ty {
-        self.inputs_and_output[self.inputs_and_output.len() - 1]
-    }
-
-    pub fn inputs(&self) -> &[Ty] {
-        &self.inputs_and_output[..self.inputs_and_output.len() - 1]
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
-pub enum Abi {
-    Rust,
-    C { unwind: bool },
-    Cdecl { unwind: bool },
-    Stdcall { unwind: bool },
-    Fastcall { unwind: bool },
-    Vectorcall { unwind: bool },
-    Thiscall { unwind: bool },
-    Aapcs { unwind: bool },
-    Win64 { unwind: bool },
-    SysV64 { unwind: bool },
-    PtxKernel,
-    Msp430Interrupt,
-    X86Interrupt,
-    GpuKernel,
-    EfiApi,
-    AvrInterrupt,
-    AvrNonBlockingInterrupt,
-    CCmseNonSecureCall,
-    CCmseNonSecureEntry,
-    System { unwind: bool },
-    RustIntrinsic,
-    RustCall,
-    Unadjusted,
-    RustCold,
-    RiscvInterruptM,
-    RiscvInterruptS,
-}
-
-/// A binder represents a possibly generic type and its bound vars.
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct Binder<T> {
-    pub value: T,
-    pub bound_vars: Vec<BoundVariableKind>,
-}
-
-impl<T> Binder<T> {
-    /// Create a new binder with the given bound vars.
-    pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
-        Binder { value, bound_vars }
-    }
-
-    /// Create a new binder with no bounded variable.
-    pub fn dummy(value: T) -> Self {
-        Binder { value, bound_vars: vec![] }
-    }
-
-    pub fn skip_binder(self) -> T {
-        self.value
-    }
-
-    pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
-    where
-        F: FnOnce(&T) -> U,
-    {
-        let Binder { value, bound_vars } = self;
-        let new_value = f(value);
-        Binder { value: new_value, bound_vars: bound_vars.clone() }
-    }
-
-    pub fn map_bound<F, U>(self, f: F) -> Binder<U>
-    where
-        F: FnOnce(T) -> U,
-    {
-        let Binder { value, bound_vars } = self;
-        let new_value = f(value);
-        Binder { value: new_value, bound_vars }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct EarlyBinder<T> {
-    pub value: T,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum BoundVariableKind {
-    Ty(BoundTyKind),
-    Region(BoundRegionKind),
-    Const,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
-pub enum BoundTyKind {
-    Anon,
-    Param(ParamDef, String),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum BoundRegionKind {
-    BrAnon,
-    BrNamed(BrNamedDef, String),
-    BrEnv,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum DynKind {
-    Dyn,
-    DynStar,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum ExistentialPredicate {
-    Trait(ExistentialTraitRef),
-    Projection(ExistentialProjection),
-    AutoTrait(TraitDef),
-}
-
-/// An existential reference to a trait where `Self` is not included.
-///
-/// The `generic_args` will include any other known argument.
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct ExistentialTraitRef {
-    pub def_id: TraitDef,
-    pub generic_args: GenericArgs,
-}
-
-impl Binder<ExistentialTraitRef> {
-    pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
-        self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
-    }
-}
-
-impl ExistentialTraitRef {
-    pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
-        TraitRef::new(self.def_id, self_ty, &self.generic_args)
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct ExistentialProjection {
-    pub def_id: TraitDef,
-    pub generic_args: GenericArgs,
-    pub term: TermKind,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct ParamTy {
-    pub index: u32,
-    pub name: String,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct BoundTy {
-    pub var: usize,
-    pub kind: BoundTyKind,
-}
-
-pub type Bytes = Vec<Option<u8>>;
-
-/// Size in bytes.
-pub type Size = usize;
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
-pub struct Prov(pub AllocId);
-
-pub type Align = u64;
-pub type Promoted = u32;
-pub type InitMaskMaterialized = Vec<u64>;
-
-/// Stores the provenance information of pointers stored in memory.
-#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
-pub struct ProvenanceMap {
-    /// Provenance in this map applies from the given offset for an entire pointer-size worth of
-    /// bytes. Two entries in this map are always at least a pointer size apart.
-    pub ptrs: Vec<(Size, Prov)>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
-pub struct Allocation {
-    pub bytes: Bytes,
-    pub provenance: ProvenanceMap,
-    pub align: Align,
-    pub mutability: Mutability,
-}
-
-impl Allocation {
-    /// Get a vector of bytes for an Allocation that has been fully initialized
-    pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
-        self.bytes
-            .iter()
-            .copied()
-            .collect::<Option<Vec<_>>>()
-            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
-    }
-
-    /// Read a uint value from the specified range.
-    pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
-        if range.end - range.start > 16 {
-            return Err(error!("Allocation is bigger than largest integer"));
-        }
-        if range.end > self.bytes.len() {
-            return Err(error!(
-                "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
-                self.bytes.len(),
-                range
-            ));
-        }
-        let raw = self.bytes[range]
-            .iter()
-            .copied()
-            .collect::<Option<Vec<_>>>()
-            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
-        read_target_uint(&raw)
-    }
-
-    /// Read this allocation and try to convert it to an unassigned integer.
-    pub fn read_uint(&self) -> Result<u128, Error> {
-        if self.bytes.len() > 16 {
-            return Err(error!("Allocation is bigger than largest integer"));
-        }
-        let raw = self.raw_bytes()?;
-        read_target_uint(&raw)
-    }
-
-    /// Read this allocation and try to convert it to a signed integer.
-    pub fn read_int(&self) -> Result<i128, Error> {
-        if self.bytes.len() > 16 {
-            return Err(error!("Allocation is bigger than largest integer"));
-        }
-        let raw = self.raw_bytes()?;
-        read_target_int(&raw)
-    }
-
-    /// Read this allocation and try to convert it to a boolean.
-    pub fn read_bool(&self) -> Result<bool, Error> {
-        match self.read_int()? {
-            0 => Ok(false),
-            1 => Ok(true),
-            val => Err(error!("Unexpected value for bool: `{val}`")),
-        }
-    }
-
-    /// Read this allocation as a pointer and return whether it represents a `null` pointer.
-    pub fn is_null(&self) -> Result<bool, Error> {
-        let len = self.bytes.len();
-        let ptr_len = MachineInfo::target_pointer_width().bytes();
-        if len != ptr_len {
-            return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
-        }
-        Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum ConstantKind {
-    Ty(TyConst),
-    Allocated(Allocation),
-    Unevaluated(UnevaluatedConst),
-    Param(ParamConst),
-    /// Store ZST constants.
-    /// We have to special handle these constants since its type might be generic.
-    ZeroSized,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct ParamConst {
-    pub index: u32,
-    pub name: String,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct UnevaluatedConst {
-    pub def: ConstDef,
-    pub args: GenericArgs,
-    pub promoted: Option<Promoted>,
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
-pub enum TraitSpecializationKind {
-    None,
-    Marker,
-    AlwaysApplicable,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct TraitDecl {
-    pub def_id: TraitDef,
-    pub safety: Safety,
-    pub paren_sugar: bool,
-    pub has_auto_impl: bool,
-    pub is_marker: bool,
-    pub is_coinductive: bool,
-    pub skip_array_during_method_dispatch: bool,
-    pub skip_boxed_slice_during_method_dispatch: bool,
-    pub specialization_kind: TraitSpecializationKind,
-    pub must_implement_one_of: Option<Vec<Ident>>,
-    pub implement_via_object: bool,
-    pub deny_explicit_impl: bool,
-}
-
-impl TraitDecl {
-    pub fn generics_of(&self) -> Generics {
-        with(|cx| cx.generics_of(self.def_id.0))
-    }
-
-    pub fn predicates_of(&self) -> GenericPredicates {
-        with(|cx| cx.predicates_of(self.def_id.0))
-    }
-
-    pub fn explicit_predicates_of(&self) -> GenericPredicates {
-        with(|cx| cx.explicit_predicates_of(self.def_id.0))
-    }
-}
-
-pub type ImplTrait = EarlyBinder<TraitRef>;
-
-/// A complete reference to a trait, i.e., one where `Self` is known.
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct TraitRef {
-    pub def_id: TraitDef,
-    /// The generic arguments for this definition.
-    /// The first element must always be type, and it represents `Self`.
-    args: GenericArgs,
-}
-
-impl TraitRef {
-    pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
-        let mut args = vec![GenericArgKind::Type(self_ty)];
-        args.extend_from_slice(&gen_args.0);
-        TraitRef { def_id, args: GenericArgs(args) }
-    }
-
-    pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
-        match &args.0[..] {
-            [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
-            _ => Err(()),
-        }
-    }
-
-    pub fn args(&self) -> &GenericArgs {
-        &self.args
-    }
-
-    pub fn self_ty(&self) -> Ty {
-        let GenericArgKind::Type(self_ty) = self.args.0[0] else {
-            panic!("Self must be a type, but found: {:?}", self.args.0[0])
-        };
-        self_ty
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct Generics {
-    pub parent: Option<GenericDef>,
-    pub parent_count: usize,
-    pub params: Vec<GenericParamDef>,
-    pub param_def_id_to_index: Vec<(GenericDef, u32)>,
-    pub has_self: bool,
-    pub has_late_bound_regions: Option<Span>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum GenericParamDefKind {
-    Lifetime,
-    Type { has_default: bool, synthetic: bool },
-    Const { has_default: bool },
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct GenericParamDef {
-    pub name: super::Symbol,
-    pub def_id: GenericDef,
-    pub index: u32,
-    pub pure_wrt_drop: bool,
-    pub kind: GenericParamDefKind,
-}
-
-pub struct GenericPredicates {
-    pub parent: Option<TraitDef>,
-    pub predicates: Vec<(PredicateKind, Span)>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum PredicateKind {
-    Clause(ClauseKind),
-    DynCompatible(TraitDef),
-    SubType(SubtypePredicate),
-    Coerce(CoercePredicate),
-    ConstEquate(TyConst, TyConst),
-    Ambiguous,
-    AliasRelate(TermKind, TermKind, AliasRelationDirection),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum ClauseKind {
-    Trait(TraitPredicate),
-    RegionOutlives(RegionOutlivesPredicate),
-    TypeOutlives(TypeOutlivesPredicate),
-    Projection(ProjectionPredicate),
-    ConstArgHasType(TyConst, Ty),
-    WellFormed(GenericArgKind),
-    ConstEvaluatable(TyConst),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum ClosureKind {
-    Fn,
-    FnMut,
-    FnOnce,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct SubtypePredicate {
-    pub a: Ty,
-    pub b: Ty,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct CoercePredicate {
-    pub a: Ty,
-    pub b: Ty,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum AliasRelationDirection {
-    Equate,
-    Subtype,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct TraitPredicate {
-    pub trait_ref: TraitRef,
-    pub polarity: PredicatePolarity,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct OutlivesPredicate<A, B>(pub A, pub B);
-
-pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
-pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct ProjectionPredicate {
-    pub projection_term: AliasTerm,
-    pub term: TermKind,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum ImplPolarity {
-    Positive,
-    Negative,
-    Reservation,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum PredicatePolarity {
-    Positive,
-    Negative,
-}
-
-pub trait IndexedVal {
-    fn to_val(index: usize) -> Self;
-
-    fn to_index(&self) -> usize;
-}
-
-macro_rules! index_impl {
-    ($name:ident) => {
-        impl IndexedVal for $name {
-            fn to_val(index: usize) -> Self {
-                $name(index)
-            }
-            fn to_index(&self) -> usize {
-                self.0
-            }
-        }
-    };
-}
-
-index_impl!(TyConstId);
-index_impl!(MirConstId);
-index_impl!(Ty);
-index_impl!(Span);
-
-/// The source-order index of a variant in a type.
-///
-/// For example, in the following types,
-/// ```ignore(illustrative)
-/// enum Demo1 {
-///    Variant0 { a: bool, b: i32 },
-///    Variant1 { c: u8, d: u64 },
-/// }
-/// struct Demo2 { e: u8, f: u16, g: u8 }
-/// ```
-/// `a` is in the variant with the `VariantIdx` of `0`,
-/// `c` is in the variant with the `VariantIdx` of `1`, and
-/// `g` is in the variant with the `VariantIdx` of `0`.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
-pub struct VariantIdx(usize);
-
-index_impl!(VariantIdx);
-
-crate_def! {
-    /// Hold infomation about an Opaque definition, particularly useful in `RPITIT`.
-    #[derive(Serialize)]
-    pub OpaqueDef;
-}
-
-crate_def! {
-    #[derive(Serialize)]
-    pub AssocDef;
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub struct AssocItem {
-    pub def_id: AssocDef,
-    pub name: Symbol,
-    pub kind: AssocKind,
-    pub container: AssocItemContainer,
-
-    /// If this is an item in an impl of a trait then this is the `DefId` of
-    /// the associated item on the trait that this implements.
-    pub trait_item_def_id: Option<AssocDef>,
-
-    /// Whether this is a method with an explicit self
-    /// as its first parameter, allowing method calls.
-    pub fn_has_self_parameter: bool,
-
-    /// `Some` if the associated item (an associated type) comes from the
-    /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData`
-    /// provides additional information about its source.
-    pub opt_rpitit_info: Option<ImplTraitInTraitData>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum AssocKind {
-    Const,
-    Fn,
-    Type,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum AssocItemContainer {
-    Trait,
-    Impl,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
-pub enum ImplTraitInTraitData {
-    Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
-    Impl { fn_def_id: FnDef },
-}
-
-impl AssocItem {
-    pub fn is_impl_trait_in_trait(&self) -> bool {
-        self.opt_rpitit_info.is_some()
-    }
-}
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
deleted file mode 100644
index 8463174f9a4..00000000000
--- a/compiler/stable_mir/src/visitor.rs
+++ /dev/null
@@ -1,224 +0,0 @@
-use std::ops::ControlFlow;
-
-use super::ty::{
-    Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
-    MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
-};
-use crate::Opaque;
-use crate::ty::TyConst;
-
-pub trait Visitor: Sized {
-    type Break;
-    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break> {
-        ty.super_visit(self)
-    }
-    fn visit_const(&mut self, c: &TyConst) -> ControlFlow<Self::Break> {
-        c.super_visit(self)
-    }
-    fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break> {
-        reg.super_visit(self)
-    }
-}
-
-pub trait Visitable {
-    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        self.super_visit(visitor)
-    }
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
-}
-
-impl Visitable for Ty {
-    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        visitor.visit_ty(self)
-    }
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match self.kind() {
-            super::ty::TyKind::RigidTy(ty) => ty.visit(visitor)?,
-            super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor)?,
-            super::ty::TyKind::Param(_) | super::ty::TyKind::Bound(_, _) => {}
-        }
-        ControlFlow::Continue(())
-    }
-}
-
-impl Visitable for TyConst {
-    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        visitor.visit_const(self)
-    }
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match &self.kind {
-            crate::ty::TyConstKind::Param(_) | crate::ty::TyConstKind::Bound(_, _) => {}
-            crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
-            crate::ty::TyConstKind::Value(ty, alloc) => {
-                alloc.visit(visitor)?;
-                ty.visit(visitor)?;
-            }
-            crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
-        }
-        ControlFlow::Continue(())
-    }
-}
-
-impl Visitable for MirConst {
-    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        self.super_visit(visitor)
-    }
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match &self.kind() {
-            super::ty::ConstantKind::Ty(ct) => ct.visit(visitor)?,
-            super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
-            super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
-            super::ty::ConstantKind::Param(_) | super::ty::ConstantKind::ZeroSized => {}
-        }
-        self.ty().visit(visitor)
-    }
-}
-
-impl Visitable for Opaque {
-    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
-        ControlFlow::Continue(())
-    }
-}
-
-impl Visitable for Allocation {
-    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
-        ControlFlow::Continue(())
-    }
-}
-
-impl Visitable for UnevaluatedConst {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        let UnevaluatedConst { def, args, promoted } = self;
-        def.visit(visitor)?;
-        args.visit(visitor)?;
-        promoted.visit(visitor)
-    }
-}
-
-impl Visitable for ConstDef {
-    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
-        ControlFlow::Continue(())
-    }
-}
-
-impl<T: Visitable> Visitable for Option<T> {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match self {
-            Some(val) => val.visit(visitor),
-            None => ControlFlow::Continue(()),
-        }
-    }
-}
-
-impl Visitable for Promoted {
-    fn super_visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
-        ControlFlow::Continue(())
-    }
-}
-
-impl Visitable for GenericArgs {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        self.0.visit(visitor)
-    }
-}
-
-impl Visitable for Region {
-    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        visitor.visit_reg(self)
-    }
-
-    fn super_visit<V: Visitor>(&self, _: &mut V) -> ControlFlow<V::Break> {
-        ControlFlow::Continue(())
-    }
-}
-
-impl Visitable for GenericArgKind {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match self {
-            GenericArgKind::Lifetime(lt) => lt.visit(visitor),
-            GenericArgKind::Type(t) => t.visit(visitor),
-            GenericArgKind::Const(c) => c.visit(visitor),
-        }
-    }
-}
-
-impl Visitable for RigidTy {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match self {
-            RigidTy::Bool
-            | RigidTy::Char
-            | RigidTy::Int(_)
-            | RigidTy::Uint(_)
-            | RigidTy::Float(_)
-            | RigidTy::Never
-            | RigidTy::Foreign(_)
-            | RigidTy::Str => ControlFlow::Continue(()),
-            RigidTy::Array(t, c) => {
-                t.visit(visitor)?;
-                c.visit(visitor)
-            }
-            RigidTy::Pat(t, _p) => t.visit(visitor),
-            RigidTy::Slice(inner) => inner.visit(visitor),
-            RigidTy::RawPtr(ty, _) => ty.visit(visitor),
-            RigidTy::Ref(reg, ty, _) => {
-                reg.visit(visitor)?;
-                ty.visit(visitor)
-            }
-            RigidTy::Adt(_, args)
-            | RigidTy::Closure(_, args)
-            | RigidTy::Coroutine(_, args, _)
-            | RigidTy::CoroutineWitness(_, args)
-            | RigidTy::CoroutineClosure(_, args)
-            | RigidTy::FnDef(_, args) => args.visit(visitor),
-            RigidTy::FnPtr(sig) => sig.visit(visitor),
-            RigidTy::Dynamic(pred, r, _) => {
-                pred.visit(visitor)?;
-                r.visit(visitor)
-            }
-            RigidTy::Tuple(fields) => fields.visit(visitor),
-        }
-    }
-}
-
-impl<T: Visitable> Visitable for Vec<T> {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        for arg in self {
-            arg.visit(visitor)?;
-        }
-        ControlFlow::Continue(())
-    }
-}
-
-impl<T: Visitable> Visitable for Binder<T> {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        self.value.visit(visitor)
-    }
-}
-
-impl Visitable for ExistentialPredicate {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match self {
-            ExistentialPredicate::Trait(tr) => tr.generic_args.visit(visitor),
-            ExistentialPredicate::Projection(p) => {
-                p.term.visit(visitor)?;
-                p.generic_args.visit(visitor)
-            }
-            ExistentialPredicate::AutoTrait(_) => ControlFlow::Continue(()),
-        }
-    }
-}
-
-impl Visitable for TermKind {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match self {
-            TermKind::Type(t) => t.visit(visitor),
-            TermKind::Const(c) => c.visit(visitor),
-        }
-    }
-}
-
-impl Visitable for FnSig {
-    fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        self.inputs_and_output.visit(visitor)
-    }
-}