about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_smir/src/lib.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs22
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs181
-rw-r--r--compiler/stable_mir/src/fold.rs245
-rw-r--r--compiler/stable_mir/src/lib.rs4
-rw-r--r--compiler/stable_mir/src/mir/body.rs2
-rw-r--r--compiler/stable_mir/src/ty.rs42
-rw-r--r--compiler/stable_mir/src/visitor.rs4
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs46
10 files changed, 144 insertions, 404 deletions
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index c24b9efe865..dcf6b904077 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -13,6 +13,7 @@
 #![cfg_attr(not(bootstrap), doc(rust_logo))]
 #![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
 #![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(rustc::usage_of_ty_tykind)]
 
 pub mod rustc_internal;
 
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index f42a9739320..2f2dac3c06d 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -4,7 +4,7 @@
 //! due to incomplete stable coverage.
 
 // Prefer importing stable_mir over internal rustc constructs to make this file more readable.
-use crate::rustc_smir::{MaybeStable, Tables};
+use crate::rustc_smir::Tables;
 use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
 use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty};
 use stable_mir::DefId;
@@ -31,7 +31,7 @@ impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
         match self {
             GenericArgKind::Lifetime(reg) => reg.internal(tables).into(),
             GenericArgKind::Type(ty) => ty.internal(tables).into(),
-            GenericArgKind::Const(cnst) => cnst.internal(tables).into(),
+            GenericArgKind::Const(cnst) => ty_const(cnst, tables).into(),
         }
     }
 }
@@ -46,16 +46,22 @@ impl<'tcx> RustcInternal<'tcx> for Region {
 impl<'tcx> RustcInternal<'tcx> for Ty {
     type T = InternalTy<'tcx>;
     fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        match tables.types[self.0] {
-            MaybeStable::Stable(_) => todo!(),
-            MaybeStable::Rustc(ty) => ty,
+        tables.types[self.0]
+    }
+}
+
+fn ty_const<'tcx>(constant: &Const, tables: &mut Tables<'tcx>) -> rustc_ty::Const<'tcx> {
+    match constant.internal(tables) {
+        rustc_middle::mir::Const::Ty(c) => c,
+        cnst => {
+            panic!("Trying to covert constant `{constant:?}` to type constant, but found {cnst:?}")
         }
     }
 }
 
 impl<'tcx> RustcInternal<'tcx> for Const {
-    type T = rustc_ty::Const<'tcx>;
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
-        todo!()
+    type T = rustc_middle::mir::Const<'tcx>;
+    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        tables.constants[self.id]
     }
 }
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index d3ea8cdc699..7c0d811fa48 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -169,6 +169,7 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
         spans: IndexMap::default(),
         types: vec![],
         instances: IndexMap::default(),
+        constants: IndexMap::default(),
     }));
     stable_mir::run(&tables, || init(&tables, f));
 }
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index d5a5f800a40..3498b6a2f6e 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -20,7 +20,8 @@ use rustc_target::abi::FieldIdx;
 use stable_mir::mir::mono::InstanceDef;
 use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
 use stable_mir::ty::{
-    FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy,
+    Const, ConstId, ConstantKind, FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy,
+    Span, TyKind, UintTy,
 };
 use stable_mir::{self, opaque, Context, Filename};
 use std::cell::RefCell;
@@ -147,14 +148,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
 
     fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
         let mut tables = self.0.borrow_mut();
-        tables.types[ty.0].clone().stable(&mut *tables)
-    }
-
-    fn mk_ty(&self, kind: TyKind) -> stable_mir::ty::Ty {
-        let mut tables = self.0.borrow_mut();
-        let n = tables.types.len();
-        tables.types.push(MaybeStable::Stable(kind));
-        stable_mir::ty::Ty(n)
+        tables.types[ty.0].kind().stable(&mut *tables)
     }
 
     fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
@@ -213,8 +207,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
     fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
         let mut tables = self.0.borrow_mut();
         let instance = tables.instances[def];
-        let ty = instance.ty(tables.tcx, ParamEnv::empty());
-        tables.intern_ty(ty)
+        instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables)
     }
 
     fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
@@ -252,33 +245,6 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
     }
 }
 
-#[derive(Clone)]
-pub enum MaybeStable<S, R> {
-    Stable(S),
-    Rustc(R),
-}
-
-impl<'tcx, S, R> MaybeStable<S, R> {
-    fn stable(self, tables: &mut Tables<'tcx>) -> S
-    where
-        R: Stable<'tcx, T = S>,
-    {
-        match self {
-            MaybeStable::Stable(s) => s,
-            MaybeStable::Rustc(r) => r.stable(tables),
-        }
-    }
-}
-
-impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {
-    fn eq(&self, other: &R) -> bool {
-        match self {
-            MaybeStable::Stable(_) => false,
-            MaybeStable::Rustc(r) => r == other,
-        }
-    }
-}
-
 pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
 
 pub struct Tables<'tcx> {
@@ -286,8 +252,9 @@ pub struct Tables<'tcx> {
     pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
     pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
     pub(crate) spans: IndexMap<rustc_span::Span, Span>,
-    pub(crate) types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
+    pub(crate) types: Vec<Ty<'tcx>>,
     pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
+    pub(crate) constants: IndexMap<mir::Const<'tcx>, ConstId>,
 }
 
 impl<'tcx> Tables<'tcx> {
@@ -296,9 +263,13 @@ impl<'tcx> Tables<'tcx> {
             return stable_mir::ty::Ty(id);
         }
         let id = self.types.len();
-        self.types.push(MaybeStable::Rustc(ty));
+        self.types.push(ty);
         stable_mir::ty::Ty(id)
     }
+
+    fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
+        self.constants.create_or_fetch(constant)
+    }
 }
 
 /// Build a stable mir crate from a given crate number.
@@ -338,7 +309,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
                 .local_decls
                 .iter()
                 .map(|decl| stable_mir::mir::LocalDecl {
-                    ty: tables.intern_ty(decl.ty),
+                    ty: decl.ty.stable(tables),
                     span: decl.source_info.span.stable(tables),
                 })
                 .collect(),
@@ -436,7 +407,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
             Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
                 cast_kind.stable(tables),
                 op.stable(tables),
-                tables.intern_ty(*ty),
+                ty.stable(tables),
             ),
             BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
                 bin_op.stable(tables),
@@ -449,7 +420,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 ops.1.stable(tables),
             ),
             NullaryOp(null_op, ty) => {
-                stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), tables.intern_ty(*ty))
+                stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables))
             }
             UnaryOp(un_op, op) => {
                 stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables))
@@ -460,7 +431,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
             }
             ShallowInitBox(op, ty) => {
-                stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), tables.intern_ty(*ty))
+                stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
             }
             CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
         }
@@ -604,7 +575,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use stable_mir::ty::TermKind;
         match self {
-            ty::TermKind::Ty(ty) => TermKind::Type(tables.intern_ty(*ty)),
+            ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)),
             ty::TermKind::Const(cnst) => {
                 let cnst = cnst.stable(tables);
                 TermKind::Const(cnst)
@@ -885,7 +856,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         match self {
             mir::AggregateKind::Array(ty) => {
-                stable_mir::mir::AggregateKind::Array(tables.intern_ty(*ty))
+                stable_mir::mir::AggregateKind::Array(ty.stable(tables))
             }
             mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
             mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
@@ -1053,7 +1024,7 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
         use stable_mir::ty::GenericArgKind;
         match self {
             ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)),
-            ty::GenericArgKind::Type(ty) => GenericArgKind::Type(tables.intern_ty(*ty)),
+            ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)),
             ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)),
         }
     }
@@ -1099,11 +1070,7 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
         use stable_mir::ty::{Abi, FnSig};
 
         FnSig {
-            inputs_and_output: self
-                .inputs_and_output
-                .iter()
-                .map(|ty| tables.intern_ty(ty))
-                .collect(),
+            inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(),
             c_variadic: self.c_variadic,
             unsafety: self.unsafety.stable(tables),
             abi: match self.abi {
@@ -1241,9 +1208,16 @@ impl<'tcx> Stable<'tcx> for hir::Movability {
 }
 
 impl<'tcx> Stable<'tcx> for Ty<'tcx> {
+    type T = stable_mir::ty::Ty;
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        tables.intern_ty(*self)
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
     type T = stable_mir::ty::TyKind;
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        match self.kind() {
+        match self {
             ty::Bool => TyKind::RigidTy(RigidTy::Bool),
             ty::Char => TyKind::RigidTy(RigidTy::Char),
             ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))),
@@ -1256,15 +1230,15 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
             ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))),
             ty::Str => TyKind::RigidTy(RigidTy::Str),
             ty::Array(ty, constant) => {
-                TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables)))
+                TyKind::RigidTy(RigidTy::Array(ty.stable(tables), constant.stable(tables)))
             }
-            ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(tables.intern_ty(*ty))),
+            ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))),
             ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => {
-                TyKind::RigidTy(RigidTy::RawPtr(tables.intern_ty(*ty), mutbl.stable(tables)))
+                TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables)))
             }
             ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
                 region.stable(tables),
-                tables.intern_ty(*ty),
+                ty.stable(tables),
                 mutbl.stable(tables),
             )),
             ty::FnDef(def_id, generic_args) => {
@@ -1291,9 +1265,9 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
                 movability.stable(tables),
             )),
             ty::Never => TyKind::RigidTy(RigidTy::Never),
-            ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple(
-                fields.iter().map(|ty| tables.intern_ty(ty)).collect(),
-            )),
+            ty::Tuple(fields) => {
+                TyKind::RigidTy(RigidTy::Tuple(fields.iter().map(|ty| ty.stable(tables)).collect()))
+            }
             ty::Alias(alias_kind, alias_ty) => {
                 TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables))
             }
@@ -1312,32 +1286,32 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
     type T = stable_mir::ty::Const;
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        stable_mir::ty::Const {
-            literal: match self.kind() {
-                ty::Value(val) => {
-                    let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
-                    stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
-                        self.ty(),
-                        const_val,
-                        tables,
-                    ))
-                }
-                ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
-                ty::ErrorCt(_) => unreachable!(),
-                ty::InferCt(_) => unreachable!(),
-                ty::BoundCt(_, _) => unimplemented!(),
-                ty::PlaceholderCt(_) => unimplemented!(),
-                ty::Unevaluated(uv) => {
-                    stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
-                        def: tables.const_def(uv.def),
-                        args: uv.args.stable(tables),
-                        promoted: None,
-                    })
-                }
-                ty::ExprCt(_) => unimplemented!(),
-            },
-            ty: tables.intern_ty(self.ty()),
-        }
+        let kind = match self.kind() {
+            ty::Value(val) => {
+                let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
+                stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
+                    self.ty(),
+                    const_val,
+                    tables,
+                ))
+            }
+            ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
+            ty::ErrorCt(_) => unreachable!(),
+            ty::InferCt(_) => unreachable!(),
+            ty::BoundCt(_, _) => unimplemented!(),
+            ty::PlaceholderCt(_) => unimplemented!(),
+            ty::Unevaluated(uv) => {
+                stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
+                    def: tables.const_def(uv.def),
+                    args: uv.args.stable(tables),
+                    promoted: None,
+                })
+            }
+            ty::ExprCt(_) => unimplemented!(),
+        };
+        let ty = self.ty().stable(tables);
+        let id = tables.intern_const(mir::Const::Ty(*self));
+        Const::new(kind, ty, id)
     }
 }
 
@@ -1422,22 +1396,23 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         match *self {
             mir::Const::Ty(c) => c.stable(tables),
-            mir::Const::Unevaluated(unev_const, ty) => stable_mir::ty::Const {
-                literal: stable_mir::ty::ConstantKind::Unevaluated(
-                    stable_mir::ty::UnevaluatedConst {
+            mir::Const::Unevaluated(unev_const, ty) => {
+                let kind =
+                    stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
                         def: tables.const_def(unev_const.def),
                         args: unev_const.args.stable(tables),
                         promoted: unev_const.promoted.map(|u| u.as_u32()),
-                    },
-                ),
-                ty: tables.intern_ty(ty),
-            },
-            mir::Const::Val(val, ty) => stable_mir::ty::Const {
-                literal: stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
-                    ty, val, tables,
-                )),
-                ty: tables.intern_ty(ty),
-            },
+                    });
+                let ty = ty.stable(tables);
+                let id = tables.intern_const(*self);
+                Const::new(kind, ty, id)
+            }
+            mir::Const::Val(val, ty) => {
+                let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables));
+                let ty = ty.stable(tables);
+                let id = tables.intern_const(*self);
+                Const::new(kind, ty, id)
+            }
         }
     }
 }
@@ -1560,7 +1535,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
             TypeOutlives(type_outlives) => {
                 let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
                 stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
-                    tables.intern_ty(a),
+                    a.stable(tables),
                     b.stable(tables),
                 ))
             }
@@ -1569,7 +1544,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
             }
             ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
                 const_.stable(tables),
-                tables.intern_ty(ty),
+                ty.stable(tables),
             ),
             WellFormed(generic_arg) => {
                 stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables))
@@ -1599,7 +1574,7 @@ impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
-        stable_mir::ty::SubtypePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) }
+        stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) }
     }
 }
 
@@ -1608,7 +1583,7 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         let ty::CoercePredicate { a, b } = self;
-        stable_mir::ty::CoercePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) }
+        stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) }
     }
 }
 
diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs
deleted file mode 100644
index ca6ea92c4a1..00000000000
--- a/compiler/stable_mir/src/fold.rs
+++ /dev/null
@@ -1,245 +0,0 @@
-use std::ops::ControlFlow;
-
-use crate::Opaque;
-
-use super::ty::{
-    Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
-    GenericArgs, Promoted, Region, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
-};
-
-pub trait Folder: Sized {
-    type Break;
-    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
-        ty.super_fold(self)
-    }
-    fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
-        c.super_fold(self)
-    }
-    fn fold_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break, Region> {
-        reg.super_fold(self)
-    }
-}
-
-pub trait Foldable: Sized + Clone {
-    fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        self.super_fold(folder)
-    }
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self>;
-}
-
-impl Foldable for Ty {
-    fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        folder.fold_ty(self)
-    }
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let mut kind = self.kind();
-        match &mut kind {
-            super::ty::TyKind::RigidTy(ty) => *ty = ty.fold(folder)?,
-            super::ty::TyKind::Alias(_, alias) => alias.args = alias.args.fold(folder)?,
-            super::ty::TyKind::Param(_) => {}
-            super::ty::TyKind::Bound(_, _) => {}
-        }
-        ControlFlow::Continue(kind.into())
-    }
-}
-
-impl Foldable for Const {
-    fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        folder.fold_const(self)
-    }
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let mut this = self.clone();
-        match &mut this.literal {
-            super::ty::ConstantKind::Allocated(alloc) => *alloc = alloc.fold(folder)?,
-            super::ty::ConstantKind::Unevaluated(uv) => *uv = uv.fold(folder)?,
-            super::ty::ConstantKind::Param(_) => {}
-        }
-        this.ty = this.ty.fold(folder)?;
-        ControlFlow::Continue(this)
-    }
-}
-
-impl Foldable for Opaque {
-    fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(self.clone())
-    }
-}
-
-impl Foldable for Allocation {
-    fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(self.clone())
-    }
-}
-
-impl Foldable for UnevaluatedConst {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let UnevaluatedConst { def, args, promoted } = self;
-        ControlFlow::Continue(UnevaluatedConst {
-            def: def.fold(folder)?,
-            args: args.fold(folder)?,
-            promoted: promoted.fold(folder)?,
-        })
-    }
-}
-
-impl Foldable for ConstDef {
-    fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(*self)
-    }
-}
-
-impl<T: Foldable> Foldable for Option<T> {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(match self {
-            Some(val) => Some(val.fold(folder)?),
-            None => None,
-        })
-    }
-}
-
-impl Foldable for Promoted {
-    fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(*self)
-    }
-}
-
-impl Foldable for GenericArgs {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(GenericArgs(self.0.fold(folder)?))
-    }
-}
-
-impl Foldable for Region {
-    fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        folder.fold_reg(self)
-    }
-    fn super_fold<V: Folder>(&self, _: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(self.clone())
-    }
-}
-
-impl Foldable for GenericArgKind {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let mut this = self.clone();
-        match &mut this {
-            GenericArgKind::Lifetime(lt) => *lt = lt.fold(folder)?,
-            GenericArgKind::Type(t) => *t = t.fold(folder)?,
-            GenericArgKind::Const(c) => *c = c.fold(folder)?,
-        }
-        ControlFlow::Continue(this)
-    }
-}
-
-impl Foldable for RigidTy {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let mut this = self.clone();
-        match &mut this {
-            RigidTy::Bool
-            | RigidTy::Char
-            | RigidTy::Int(_)
-            | RigidTy::Uint(_)
-            | RigidTy::Float(_)
-            | RigidTy::Never
-            | RigidTy::Foreign(_)
-            | RigidTy::Str => {}
-            RigidTy::Array(t, c) => {
-                *t = t.fold(folder)?;
-                *c = c.fold(folder)?;
-            }
-            RigidTy::Slice(inner) => *inner = inner.fold(folder)?,
-            RigidTy::RawPtr(ty, _) => *ty = ty.fold(folder)?,
-            RigidTy::Ref(reg, ty, _) => {
-                *reg = reg.fold(folder)?;
-                *ty = ty.fold(folder)?
-            }
-            RigidTy::FnDef(_, args) => *args = args.fold(folder)?,
-            RigidTy::FnPtr(sig) => *sig = sig.fold(folder)?,
-            RigidTy::Closure(_, args) => *args = args.fold(folder)?,
-            RigidTy::Coroutine(_, args, _) => *args = args.fold(folder)?,
-            RigidTy::Dynamic(pred, r, _) => {
-                *pred = pred.fold(folder)?;
-                *r = r.fold(folder)?;
-            }
-            RigidTy::Tuple(fields) => *fields = fields.fold(folder)?,
-            RigidTy::Adt(_, args) => *args = args.fold(folder)?,
-        }
-        ControlFlow::Continue(this)
-    }
-}
-
-impl<T: Foldable> Foldable for Vec<T> {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let mut this = self.clone();
-        for arg in &mut this {
-            *arg = arg.fold(folder)?;
-        }
-        ControlFlow::Continue(this)
-    }
-}
-
-impl<T: Foldable> Foldable for Binder<T> {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(Self {
-            value: self.value.fold(folder)?,
-            bound_vars: self.bound_vars.clone(),
-        })
-    }
-}
-
-impl Foldable for ExistentialPredicate {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        let mut this = self.clone();
-        match &mut this {
-            ExistentialPredicate::Trait(tr) => tr.generic_args = tr.generic_args.fold(folder)?,
-            ExistentialPredicate::Projection(p) => {
-                p.term = p.term.fold(folder)?;
-                p.generic_args = p.generic_args.fold(folder)?;
-            }
-            ExistentialPredicate::AutoTrait(_) => {}
-        }
-        ControlFlow::Continue(this)
-    }
-}
-
-impl Foldable for TermKind {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(match self {
-            TermKind::Type(t) => TermKind::Type(t.fold(folder)?),
-            TermKind::Const(c) => TermKind::Const(c.fold(folder)?),
-        })
-    }
-}
-
-impl Foldable for FnSig {
-    fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(Self {
-            inputs_and_output: self.inputs_and_output.fold(folder)?,
-            c_variadic: self.c_variadic,
-            unsafety: self.unsafety,
-            abi: self.abi.clone(),
-        })
-    }
-}
-
-pub enum Never {}
-
-/// In order to instantiate a `Foldable`'s generic parameters with specific arguments,
-/// `GenericArgs` can be used as a `Folder` that replaces all mentions of generic params
-/// with the entries in its list.
-impl Folder for GenericArgs {
-    type Break = Never;
-
-    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
-        ControlFlow::Continue(match ty.kind() {
-            TyKind::Param(p) => self[p],
-            _ => *ty,
-        })
-    }
-
-    fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
-        ControlFlow::Continue(match &c.literal {
-            ConstantKind::Param(p) => self[p.clone()].clone(),
-            _ => c.clone(),
-        })
-    }
-}
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index 8cacbdbda48..38915afaa0c 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -32,7 +32,6 @@ use self::ty::{
 extern crate scoped_tls;
 
 pub mod error;
-pub mod fold;
 pub mod mir;
 pub mod ty;
 pub mod visitor;
@@ -215,9 +214,6 @@ pub trait Context {
     /// Obtain the representation of a type.
     fn ty_kind(&self, ty: Ty) -> TyKind;
 
-    /// Create a new `Ty` from scratch without information from rustc.
-    fn mk_ty(&self, kind: TyKind) -> Ty;
-
     /// Get the body of an Instance.
     /// FIXME: Monomorphize the body.
     fn instance_body(&self, instance: InstanceDef) -> Body;
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 5eee1ec00df..fc617513aee 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -477,7 +477,7 @@ impl Operand {
 
 impl Constant {
     pub fn ty(&self) -> Ty {
-        self.literal.ty
+        self.literal.ty()
     }
 }
 
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 8f7f8bd4e38..f1af09fac66 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -21,16 +21,44 @@ impl Ty {
     }
 }
 
-impl From<TyKind> for Ty {
-    fn from(value: TyKind) -> Self {
-        with(|context| context.mk_ty(value))
+/// Represents a constant in MIR or from the Type system.
+#[derive(Clone, Debug)]
+pub struct Const {
+    /// The constant kind.
+    kind: ConstantKind,
+    /// The constant type.
+    ty: Ty,
+    /// Used for internal tracking of the internal constant.
+    pub id: ConstId,
+}
+
+impl Const {
+    /// Build a constant. Note that this should only be used by the compiler.
+    pub fn new(kind: ConstantKind, ty: Ty, id: ConstId) -> Const {
+        Const { 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
     }
 }
 
-#[derive(Debug, Clone)]
-pub struct Const {
-    pub literal: ConstantKind,
-    pub ty: Ty,
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct ConstId(pub usize);
+
+impl IndexedVal for ConstId {
+    fn to_val(index: usize) -> Self {
+        ConstId(index)
+    }
+    fn to_index(&self) -> usize {
+        self.0
+    }
 }
 
 type Ident = Opaque;
diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs
index a6020cc5bd9..c337f5b68d3 100644
--- a/compiler/stable_mir/src/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -47,12 +47,12 @@ impl Visitable for Const {
         visitor.visit_const(self)
     }
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
-        match &self.literal {
+        match &self.kind() {
             super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?,
             super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?,
             super::ty::ConstantKind::Param(_) => {}
         }
-        self.ty.visit(visitor)
+        self.ty().visit(visitor)
     }
 }
 
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 3cb71b5a025..60c6053d295 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -22,8 +22,8 @@ extern crate stable_mir;
 use rustc_hir::def::DefKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
-
-use stable_mir::fold::Foldable;
+use stable_mir::mir::mono::Instance;
+use stable_mir::ty::{RigidTy, TyKind};
 use std::assert_matches::assert_matches;
 use std::io::Write;
 use std::ops::ControlFlow;
@@ -119,40 +119,18 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
     }
 
     let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap();
-    for block in monomorphic.body().blocks {
+    let instance = Instance::try_from(monomorphic.clone()).unwrap();
+    for block in instance.body().blocks {
         match &block.terminator.kind {
-            stable_mir::mir::TerminatorKind::Call { func, .. } => match func {
-                stable_mir::mir::Operand::Constant(c) => match &c.literal.literal {
-                    stable_mir::ty::ConstantKind::Allocated(alloc) => {
-                        assert!(alloc.bytes.is_empty());
-                        match c.literal.ty.kind() {
-                            stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::FnDef(
-                                def,
-                                mut args,
-                            )) => {
-                                let func = def.body();
-                                match func.locals[1].ty
-                                    .fold(&mut args)
-                                    .continue_value()
-                                    .unwrap()
-                                    .kind()
-                                {
-                                    stable_mir::ty::TyKind::RigidTy(
-                                        stable_mir::ty::RigidTy::Uint(_),
-                                    ) => {}
-                                    stable_mir::ty::TyKind::RigidTy(
-                                        stable_mir::ty::RigidTy::Tuple(_),
-                                    ) => {}
-                                    other => panic!("{other:?}"),
-                                }
-                            }
-                            other => panic!("{other:?}"),
-                        }
-                    }
+            stable_mir::mir::TerminatorKind::Call { func, .. } => {
+                let TyKind::RigidTy(ty) = func.ty(&body.locals).kind() else { unreachable!() };
+                let RigidTy::FnDef(def, args) = ty else { unreachable!() };
+                let next_func = Instance::resolve(def, &args).unwrap();
+                match next_func.body().locals[1].ty.kind() {
+                    TyKind::RigidTy(RigidTy::Uint(_)) | TyKind::RigidTy(RigidTy::Tuple(_)) => {}
                     other => panic!("{other:?}"),
-                },
-                other => panic!("{other:?}"),
-            },
+                }
+            }
             stable_mir::mir::TerminatorKind::Return => {}
             other => panic!("{other:?}"),
         }