summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_smir/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_smir/src')
-rw-r--r--compiler/rustc_smir/src/lib.rs6
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs444
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs39
-rw-r--r--compiler/rustc_smir/src/rustc_internal/pretty.rs20
-rw-r--r--compiler/rustc_smir/src/rustc_smir/alloc.rs44
-rw-r--r--compiler/rustc_smir/src/rustc_smir/builder.rs29
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs555
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/abi.rs242
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/error.rs22
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs746
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mod.rs74
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs829
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs1781
13 files changed, 3111 insertions, 1720 deletions
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index dcf6b9040..ddd5ea551 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -10,9 +10,9 @@
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![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 7cfdbbbf7..bbc98af45 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -6,11 +6,28 @@
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
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;
+use rustc_span::Symbol;
+use stable_mir::abi::Layout;
+use stable_mir::mir::alloc::AllocId;
+use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
+use stable_mir::mir::{Mutability, Safety};
+use stable_mir::ty::{
+ Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
+ DynKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
+ GenericArgKind, GenericArgs, IndexedVal, IntTy, Movability, Region, RigidTy, Span, TermKind,
+ TraitRef, Ty, UintTy, VariantDef, VariantIdx,
+};
+use stable_mir::{CrateItem, DefId};
use super::RustcInternal;
+impl<'tcx> RustcInternal<'tcx> for CrateItem {
+ type T = rustc_span::def_id::DefId;
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ self.0.internal(tables)
+ }
+}
+
impl<'tcx> RustcInternal<'tcx> for DefId {
type T = rustc_span::def_id::DefId;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
@@ -38,8 +55,9 @@ impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
impl<'tcx> RustcInternal<'tcx> for Region {
type T = rustc_ty::Region<'tcx>;
- fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
- todo!()
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ // Cannot recover region. Use erased instead.
+ tables.tcx.lifetimes.re_erased
}
}
@@ -50,6 +68,154 @@ impl<'tcx> RustcInternal<'tcx> for Ty {
}
}
+impl<'tcx> RustcInternal<'tcx> for RigidTy {
+ type T = rustc_ty::TyKind<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ RigidTy::Bool => rustc_ty::TyKind::Bool,
+ RigidTy::Char => rustc_ty::TyKind::Char,
+ RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables)),
+ RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables)),
+ RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables)),
+ RigidTy::Never => rustc_ty::TyKind::Never,
+ RigidTy::Array(ty, cnst) => {
+ rustc_ty::TyKind::Array(ty.internal(tables), ty_const(cnst, tables))
+ }
+ RigidTy::Adt(def, args) => {
+ rustc_ty::TyKind::Adt(def.internal(tables), args.internal(tables))
+ }
+ RigidTy::Str => rustc_ty::TyKind::Str,
+ RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables)),
+ RigidTy::RawPtr(ty, mutability) => rustc_ty::TyKind::RawPtr(rustc_ty::TypeAndMut {
+ ty: ty.internal(tables),
+ mutbl: mutability.internal(tables),
+ }),
+ RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref(
+ region.internal(tables),
+ ty.internal(tables),
+ mutability.internal(tables),
+ ),
+ RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables)),
+ RigidTy::FnDef(def, args) => {
+ rustc_ty::TyKind::FnDef(def.0.internal(tables), args.internal(tables))
+ }
+ RigidTy::FnPtr(sig) => rustc_ty::TyKind::FnPtr(sig.internal(tables)),
+ RigidTy::Closure(def, args) => {
+ rustc_ty::TyKind::Closure(def.0.internal(tables), args.internal(tables))
+ }
+ RigidTy::Coroutine(def, args, mov) => rustc_ty::TyKind::Coroutine(
+ def.0.internal(tables),
+ args.internal(tables),
+ mov.internal(tables),
+ ),
+ RigidTy::CoroutineWitness(def, args) => {
+ rustc_ty::TyKind::CoroutineWitness(def.0.internal(tables), args.internal(tables))
+ }
+ RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic(
+ tables.tcx.mk_poly_existential_predicates(&predicate.internal(tables)),
+ region.internal(tables),
+ dyn_kind.internal(tables),
+ ),
+ RigidTy::Tuple(tys) => {
+ rustc_ty::TyKind::Tuple(tables.tcx.mk_type_list(&tys.internal(tables)))
+ }
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for IntTy {
+ type T = rustc_ty::IntTy;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ IntTy::Isize => rustc_ty::IntTy::Isize,
+ IntTy::I8 => rustc_ty::IntTy::I8,
+ IntTy::I16 => rustc_ty::IntTy::I16,
+ IntTy::I32 => rustc_ty::IntTy::I32,
+ IntTy::I64 => rustc_ty::IntTy::I64,
+ IntTy::I128 => rustc_ty::IntTy::I128,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for UintTy {
+ type T = rustc_ty::UintTy;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ UintTy::Usize => rustc_ty::UintTy::Usize,
+ UintTy::U8 => rustc_ty::UintTy::U8,
+ UintTy::U16 => rustc_ty::UintTy::U16,
+ UintTy::U32 => rustc_ty::UintTy::U32,
+ UintTy::U64 => rustc_ty::UintTy::U64,
+ UintTy::U128 => rustc_ty::UintTy::U128,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for FloatTy {
+ type T = rustc_ty::FloatTy;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ FloatTy::F32 => rustc_ty::FloatTy::F32,
+ FloatTy::F64 => rustc_ty::FloatTy::F64,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for Mutability {
+ type T = rustc_ty::Mutability;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ Mutability::Not => rustc_ty::Mutability::Not,
+ Mutability::Mut => rustc_ty::Mutability::Mut,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for Movability {
+ type T = rustc_ty::Movability;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ Movability::Static => rustc_ty::Movability::Static,
+ Movability::Movable => rustc_ty::Movability::Movable,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for FnSig {
+ type T = rustc_ty::FnSig<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ rustc_ty::FnSig {
+ inputs_and_output: tables.tcx.mk_type_list(&self.inputs_and_output.internal(tables)),
+ c_variadic: self.c_variadic,
+ unsafety: self.unsafety.internal(tables),
+ abi: self.abi.internal(tables),
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for VariantIdx {
+ type T = rustc_target::abi::VariantIdx;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ rustc_target::abi::VariantIdx::from(self.to_index())
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for VariantDef {
+ type T = &'tcx rustc_ty::VariantDef;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ self.adt_def.internal(tables).variant(self.idx.internal(tables))
+ }
+}
+
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,
@@ -65,3 +231,273 @@ impl<'tcx> RustcInternal<'tcx> for Const {
tables.constants[self.id]
}
}
+
+impl<'tcx> RustcInternal<'tcx> for MonoItem {
+ type T = rustc_middle::mir::mono::MonoItem<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::mono as rustc_mono;
+ match self {
+ MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables)),
+ MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables)),
+ MonoItem::GlobalAsm(_) => {
+ unimplemented!()
+ }
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for Instance {
+ type T = rustc_ty::Instance<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables.instances[self.def]
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for StaticDef {
+ type T = rustc_span::def_id::DefId;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ self.0.internal(tables)
+ }
+}
+
+#[allow(rustc::usage_of_qualified_ty)]
+impl<'tcx, T> RustcInternal<'tcx> for Binder<T>
+where
+ T: RustcInternal<'tcx>,
+ T::T: rustc_ty::TypeVisitable<rustc_ty::TyCtxt<'tcx>>,
+{
+ type T = rustc_ty::Binder<'tcx, T::T>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ rustc_ty::Binder::bind_with_vars(
+ self.value.internal(tables),
+ tables.tcx.mk_bound_variable_kinds_from_iter(
+ self.bound_vars.iter().map(|bound| bound.internal(tables)),
+ ),
+ )
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
+ type T = rustc_ty::BoundVariableKind;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind {
+ BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon,
+ BoundTyKind::Param(def, symbol) => {
+ rustc_ty::BoundTyKind::Param(def.0.internal(tables), Symbol::intern(symbol))
+ }
+ }),
+ BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind {
+ BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::BrAnon,
+ BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::BrNamed(
+ def.0.internal(tables),
+ Symbol::intern(symbol),
+ ),
+ BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::BrEnv,
+ }),
+ BoundVariableKind::Const => rustc_ty::BoundVariableKind::Const,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for DynKind {
+ type T = rustc_ty::DynKind;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ DynKind::Dyn => rustc_ty::DynKind::Dyn,
+ DynKind::DynStar => rustc_ty::DynKind::DynStar,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for ExistentialPredicate {
+ type T = rustc_ty::ExistentialPredicate<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ExistentialPredicate::Trait(trait_ref) => {
+ rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables))
+ }
+ ExistentialPredicate::Projection(proj) => {
+ rustc_ty::ExistentialPredicate::Projection(proj.internal(tables))
+ }
+ ExistentialPredicate::AutoTrait(trait_def) => {
+ rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables))
+ }
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for ExistentialProjection {
+ type T = rustc_ty::ExistentialProjection<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ rustc_ty::ExistentialProjection {
+ def_id: self.def_id.0.internal(tables),
+ args: self.generic_args.internal(tables),
+ term: self.term.internal(tables),
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for TermKind {
+ type T = rustc_ty::Term<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ TermKind::Type(ty) => ty.internal(tables).into(),
+ TermKind::Const(const_) => ty_const(const_, tables).into(),
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for ExistentialTraitRef {
+ type T = rustc_ty::ExistentialTraitRef<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ rustc_ty::ExistentialTraitRef {
+ def_id: self.def_id.0.internal(tables),
+ args: self.generic_args.internal(tables),
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for TraitRef {
+ type T = rustc_ty::TraitRef<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ rustc_ty::TraitRef::new(
+ tables.tcx,
+ self.def_id.0.internal(tables),
+ self.args().internal(tables),
+ )
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for AllocId {
+ type T = rustc_middle::mir::interpret::AllocId;
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables.alloc_ids[*self]
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for ClosureKind {
+ type T = rustc_ty::ClosureKind;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ClosureKind::Fn => rustc_ty::ClosureKind::Fn,
+ ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut,
+ ClosureKind::FnOnce => rustc_ty::ClosureKind::FnOnce,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for AdtDef {
+ type T = rustc_ty::AdtDef<'tcx>;
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables.tcx.adt_def(self.0.internal(&mut *tables))
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for Abi {
+ type T = rustc_target::spec::abi::Abi;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match *self {
+ Abi::Rust => rustc_target::spec::abi::Abi::Rust,
+ Abi::C { unwind } => rustc_target::spec::abi::Abi::C { unwind },
+ Abi::Cdecl { unwind } => rustc_target::spec::abi::Abi::Cdecl { unwind },
+ Abi::Stdcall { unwind } => rustc_target::spec::abi::Abi::Stdcall { unwind },
+ Abi::Fastcall { unwind } => rustc_target::spec::abi::Abi::Fastcall { unwind },
+ Abi::Vectorcall { unwind } => rustc_target::spec::abi::Abi::Vectorcall { unwind },
+ Abi::Thiscall { unwind } => rustc_target::spec::abi::Abi::Thiscall { unwind },
+ Abi::Aapcs { unwind } => rustc_target::spec::abi::Abi::Aapcs { unwind },
+ Abi::Win64 { unwind } => rustc_target::spec::abi::Abi::Win64 { unwind },
+ Abi::SysV64 { unwind } => rustc_target::spec::abi::Abi::SysV64 { unwind },
+ Abi::PtxKernel => rustc_target::spec::abi::Abi::PtxKernel,
+ Abi::Msp430Interrupt => rustc_target::spec::abi::Abi::Msp430Interrupt,
+ Abi::X86Interrupt => rustc_target::spec::abi::Abi::X86Interrupt,
+ Abi::AmdGpuKernel => rustc_target::spec::abi::Abi::AmdGpuKernel,
+ Abi::EfiApi => rustc_target::spec::abi::Abi::EfiApi,
+ Abi::AvrInterrupt => rustc_target::spec::abi::Abi::AvrInterrupt,
+ Abi::AvrNonBlockingInterrupt => rustc_target::spec::abi::Abi::AvrNonBlockingInterrupt,
+ Abi::CCmseNonSecureCall => rustc_target::spec::abi::Abi::CCmseNonSecureCall,
+ Abi::Wasm => rustc_target::spec::abi::Abi::Wasm,
+ Abi::System { unwind } => rustc_target::spec::abi::Abi::System { unwind },
+ Abi::RustIntrinsic => rustc_target::spec::abi::Abi::RustIntrinsic,
+ Abi::RustCall => rustc_target::spec::abi::Abi::RustCall,
+ Abi::PlatformIntrinsic => rustc_target::spec::abi::Abi::PlatformIntrinsic,
+ Abi::Unadjusted => rustc_target::spec::abi::Abi::Unadjusted,
+ Abi::RustCold => rustc_target::spec::abi::Abi::RustCold,
+ Abi::RiscvInterruptM => rustc_target::spec::abi::Abi::RiscvInterruptM,
+ Abi::RiscvInterruptS => rustc_target::spec::abi::Abi::RiscvInterruptS,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for Safety {
+ type T = rustc_hir::Unsafety;
+
+ fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ Safety::Unsafe => rustc_hir::Unsafety::Unsafe,
+ Safety::Normal => rustc_hir::Unsafety::Normal,
+ }
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for Span {
+ type T = rustc_span::Span;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables[*self]
+ }
+}
+
+impl<'tcx> RustcInternal<'tcx> for Layout {
+ type T = rustc_target::abi::Layout<'tcx>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables.layouts[*self]
+ }
+}
+
+impl<'tcx, T> RustcInternal<'tcx> for &T
+where
+ T: RustcInternal<'tcx>,
+{
+ type T = T::T;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ (*self).internal(tables)
+ }
+}
+
+impl<'tcx, T> RustcInternal<'tcx> for Option<T>
+where
+ T: RustcInternal<'tcx>,
+{
+ type T = Option<T::T>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ self.as_ref().map(|inner| inner.internal(tables))
+ }
+}
+
+impl<'tcx, T> RustcInternal<'tcx> for Vec<T>
+where
+ T: RustcInternal<'tcx>,
+{
+ type T = Vec<T::T>;
+
+ fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ self.iter().map(|e| e.internal(tables)).collect()
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 4d2a51822..4bac98909 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -3,7 +3,7 @@
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.
-use crate::rustc_smir::{Stable, Tables, TablesWrapper};
+use crate::rustc_smir::{context::TablesWrapper, Stable, Tables};
use rustc_data_structures::fx;
use rustc_data_structures::fx::FxIndexMap;
use rustc_middle::mir::interpret::AllocId;
@@ -12,7 +12,9 @@ use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::{CrateNum, DefId};
use rustc_span::Span;
use scoped_tls::scoped_thread_local;
+use stable_mir::abi::Layout;
use stable_mir::ty::IndexedVal;
+use stable_mir::Error;
use std::cell::Cell;
use std::cell::RefCell;
use std::fmt::Debug;
@@ -20,12 +22,13 @@ use std::hash::Hash;
use std::ops::Index;
mod internal;
+pub mod pretty;
-pub fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
+pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
with_tables(|tables| item.stable(tables))
}
-pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: &S) -> S::T {
+pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: S) -> S::T {
with_tables(|tables| item.internal(tables))
}
@@ -104,6 +107,10 @@ impl<'tcx> Tables<'tcx> {
stable_mir::ty::RegionDef(self.create_def_id(did))
}
+ pub fn coroutine_witness_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineWitnessDef {
+ stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did))
+ }
+
pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
stable_mir::ty::Prov(self.create_alloc_id(aid))
}
@@ -112,7 +119,7 @@ impl<'tcx> Tables<'tcx> {
self.def_ids.create_or_fetch(did)
}
- fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId {
+ pub(crate) fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId {
self.alloc_ids.create_or_fetch(aid)
}
@@ -130,6 +137,10 @@ impl<'tcx> Tables<'tcx> {
pub(crate) fn static_def(&mut self, did: DefId) -> stable_mir::mir::mono::StaticDef {
stable_mir::mir::mono::StaticDef(self.create_def_id(did))
}
+
+ pub(crate) fn layout_id(&mut self, layout: rustc_target::abi::Layout<'tcx>) -> Layout {
+ self.layouts.create_or_fetch(layout)
+ }
}
pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
@@ -140,12 +151,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
// datastructures and stable MIR datastructures
scoped_thread_local! (static TLV: Cell<*const ()>);
-pub(crate) fn init<'tcx>(tables: &TablesWrapper<'tcx>, f: impl FnOnce()) {
+pub(crate) fn init<'tcx, F, T>(tables: &TablesWrapper<'tcx>, f: F) -> T
+where
+ F: FnOnce() -> T,
+{
assert!(!TLV.is_set());
let ptr = tables as *const _ as *const ();
- TLV.set(&Cell::new(ptr), || {
- f();
- });
+ TLV.set(&Cell::new(ptr), || f())
}
/// Loads the current context and calls a function with it.
@@ -161,7 +173,10 @@ pub(crate) fn with_tables<'tcx, R>(f: impl FnOnce(&mut Tables<'tcx>) -> R) -> R
})
}
-pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
+pub fn run<F, T>(tcx: TyCtxt<'_>, f: F) -> Result<T, Error>
+where
+ F: FnOnce() -> T,
+{
let tables = TablesWrapper(RefCell::new(Tables {
tcx,
def_ids: IndexMap::default(),
@@ -170,8 +185,9 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
types: IndexMap::default(),
instances: IndexMap::default(),
constants: IndexMap::default(),
+ layouts: IndexMap::default(),
}));
- stable_mir::run(&tables, || init(&tables, f));
+ stable_mir::compiler_interface::run(&tables, || init(&tables, f))
}
#[macro_export]
@@ -237,7 +253,8 @@ macro_rules! run {
queries.global_ctxt().unwrap().enter(|tcx| {
rustc_internal::run(tcx, || {
self.result = Some((self.callback)(tcx));
- });
+ })
+ .unwrap();
if self.result.as_ref().is_some_and(|val| val.is_continue()) {
Compilation::Continue
} else {
diff --git a/compiler/rustc_smir/src/rustc_internal/pretty.rs b/compiler/rustc_smir/src/rustc_internal/pretty.rs
new file mode 100644
index 000000000..3ef2d28ea
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_internal/pretty.rs
@@ -0,0 +1,20 @@
+use std::io;
+
+use super::run;
+use rustc_middle::ty::TyCtxt;
+
+pub fn write_smir_pretty<'tcx, W: io::Write>(tcx: TyCtxt<'tcx>, w: &mut W) -> io::Result<()> {
+ writeln!(
+ w,
+ "// WARNING: This is highly experimental output it's intended for stable-mir developers only."
+ )?;
+ writeln!(
+ w,
+ "// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir."
+ )?;
+ let _ = run(tcx, || {
+ let items = stable_mir::all_local_items();
+ let _ = items.iter().map(|item| -> io::Result<()> { item.dump(w) }).collect::<Vec<_>>();
+ });
+ Ok(())
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs
index 63a2a1450..48cb164c3 100644
--- a/compiler/rustc_smir/src/rustc_smir/alloc.rs
+++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs
@@ -2,6 +2,7 @@ use rustc_middle::mir::{
interpret::{alloc_range, AllocRange, Pointer},
ConstValue,
};
+use stable_mir::Error;
use crate::rustc_smir::{Stable, Tables};
use stable_mir::mir::Mutability;
@@ -26,33 +27,47 @@ pub fn new_allocation<'tcx>(
const_value: ConstValue<'tcx>,
tables: &mut Tables<'tcx>,
) -> Allocation {
- match const_value {
+ try_new_allocation(ty, const_value, tables).unwrap()
+}
+
+#[allow(rustc::usage_of_qualified_ty)]
+pub fn try_new_allocation<'tcx>(
+ ty: rustc_middle::ty::Ty<'tcx>,
+ const_value: ConstValue<'tcx>,
+ tables: &mut Tables<'tcx>,
+) -> Result<Allocation, Error> {
+ Ok(match const_value {
ConstValue::Scalar(scalar) => {
let size = scalar.size();
let align = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
- .unwrap()
+ .map_err(|e| e.stable(tables))?
.align;
let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi);
allocation
.write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar)
- .unwrap();
+ .map_err(|e| e.stable(tables))?;
allocation.stable(tables)
}
ConstValue::ZeroSized => {
- let align =
- tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align;
+ let align = tables
+ .tcx
+ .layout_of(rustc_middle::ty::ParamEnv::empty().and(ty))
+ .map_err(|e| e.stable(tables))?
+ .align;
new_empty_allocation(align.abi)
}
ConstValue::Slice { data, meta } => {
let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data);
- let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::ZERO);
+ let ptr = Pointer::new(alloc_id.into(), rustc_target::abi::Size::ZERO);
let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
let scalar_meta =
rustc_middle::mir::interpret::Scalar::from_target_usize(meta, &tables.tcx);
- let layout =
- tables.tcx.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)).unwrap();
+ let layout = tables
+ .tcx
+ .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
+ .map_err(|e| e.stable(tables))?;
let mut allocation =
rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
allocation
@@ -61,14 +76,14 @@ pub fn new_allocation<'tcx>(
alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
scalar_ptr,
)
- .unwrap();
+ .map_err(|e| e.stable(tables))?;
allocation
.write_scalar(
&tables.tcx,
alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()),
scalar_meta,
)
- .unwrap();
+ .map_err(|e| e.stable(tables))?;
allocation.stable(tables)
}
ConstValue::Indirect { alloc_id, offset } => {
@@ -76,11 +91,11 @@ pub fn new_allocation<'tcx>(
let ty_size = tables
.tcx
.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
- .unwrap()
+ .map_err(|e| e.stable(tables))?
.size;
allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
}
- }
+ })
}
/// Creates an `Allocation` only from information within the `AllocRange`.
@@ -112,7 +127,10 @@ pub(super) fn allocation_filter<'tcx>(
.iter()
.filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end())
{
- ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), tables.prov(*prov)));
+ ptrs.push((
+ offset.bytes_usize() - alloc_range.start.bytes_usize(),
+ tables.prov(prov.alloc_id()),
+ ));
}
Allocation {
bytes: bytes,
diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs
index 8ff3958da..039bdec4c 100644
--- a/compiler/rustc_smir/src/rustc_smir/builder.rs
+++ b/compiler/rustc_smir/src/rustc_smir/builder.rs
@@ -6,7 +6,7 @@
use crate::rustc_smir::{Stable, Tables};
use rustc_middle::mir;
use rustc_middle::mir::visit::MutVisitor;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
/// Builds a monomorphic body for a given instance.
pub struct BodyBuilder<'tcx> {
@@ -19,10 +19,15 @@ impl<'tcx> BodyBuilder<'tcx> {
BodyBuilder { tcx, instance }
}
+ /// Build a stable monomorphic body for a given instance based on the MIR body.
+ ///
+ /// Note that we skip instantiation for static and constants. Trying to do so can cause ICE.
+ ///
+ /// We do monomorphize non-generic functions to eval unevaluated constants.
pub fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
let mut body = self.tcx.instance_mir(self.instance.def).clone();
- let generics = self.tcx.generics_of(self.instance.def_id());
- if generics.requires_monomorphization(self.tcx) {
+ if self.tcx.def_kind(self.instance.def_id()).is_fn_like() || !self.instance.args.is_empty()
+ {
self.visit_body(&mut body);
}
body.stable(tables)
@@ -49,6 +54,24 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
*ty = self.monomorphize(*ty);
}
+ fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) {
+ let const_ = self.monomorphize(constant.const_);
+ let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), None) {
+ Ok(v) => v,
+ Err(mir::interpret::ErrorHandled::Reported(..)) => return,
+ Err(mir::interpret::ErrorHandled::TooGeneric(..)) => {
+ unreachable!("Failed to evaluate instance constant: {:?}", const_)
+ }
+ };
+ let ty = constant.ty();
+ constant.const_ = mir::Const::Val(val, ty);
+ self.super_constant(constant, location);
+ }
+
+ fn visit_args(&mut self, args: &mut GenericArgsRef<'tcx>, _: mir::Location) {
+ *args = self.monomorphize(*args);
+ }
+
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
new file mode 100644
index 000000000..f84c466cc
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -0,0 +1,555 @@
+//! Implementation of `[stable_mir::compiler_interface::Context]` trait.
+//!
+//! This trait is currently the main interface between the Rust compiler,
+//! and the `stable_mir` crate.
+
+#![allow(rustc::usage_of_qualified_ty)]
+
+use rustc_abi::HasDataLayout;
+use rustc_middle::ty;
+use rustc_middle::ty::layout::{
+ FnAbiOf, FnAbiOfHelpers, HasParamEnv, HasTyCtxt, LayoutOf, LayoutOfHelpers,
+};
+use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
+use rustc_middle::ty::{
+ GenericPredicates, Instance, List, ParamEnv, ScalarInt, TyCtxt, TypeVisitableExt, ValTree,
+};
+use rustc_span::def_id::LOCAL_CRATE;
+use stable_mir::abi::{FnAbi, Layout, LayoutShape};
+use stable_mir::compiler_interface::Context;
+use stable_mir::mir::alloc::GlobalAlloc;
+use stable_mir::mir::mono::{InstanceDef, StaticDef};
+use stable_mir::mir::Body;
+use stable_mir::target::{MachineInfo, MachineSize};
+use stable_mir::ty::{
+ AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs,
+ LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef,
+};
+use stable_mir::{Crate, CrateItem, DefId, Error, Filename, ItemKind, Symbol};
+use std::cell::RefCell;
+
+use crate::rustc_internal::{internal, RustcInternal};
+use crate::rustc_smir::builder::BodyBuilder;
+use crate::rustc_smir::{alloc, new_item_kind, smir_crate, Stable, Tables};
+
+impl<'tcx> Context for TablesWrapper<'tcx> {
+ fn target_info(&self) -> MachineInfo {
+ let mut tables = self.0.borrow_mut();
+ MachineInfo {
+ endian: tables.tcx.data_layout.endian.stable(&mut *tables),
+ pointer_width: MachineSize::from_bits(
+ tables.tcx.data_layout.pointer_size.bits().try_into().unwrap(),
+ ),
+ }
+ }
+
+ fn entry_fn(&self) -> Option<stable_mir::CrateItem> {
+ let mut tables = self.0.borrow_mut();
+ let tcx = tables.tcx;
+ Some(tables.crate_item(tcx.entry_fn(())?.0))
+ }
+
+ fn all_local_items(&self) -> stable_mir::CrateItems {
+ let mut tables = self.0.borrow_mut();
+ tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect()
+ }
+
+ fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables[item];
+ tables.tcx.instance_mir(rustc_middle::ty::InstanceDef::Item(def_id)).stable(&mut tables)
+ }
+
+ fn has_body(&self, def: DefId) -> bool {
+ let tables = self.0.borrow();
+ let def_id = tables[def];
+ tables.tcx.is_mir_available(def_id)
+ }
+
+ fn all_trait_decls(&self) -> stable_mir::TraitDecls {
+ let mut tables = self.0.borrow_mut();
+ tables
+ .tcx
+ .traits(LOCAL_CRATE)
+ .iter()
+ .map(|trait_def_id| tables.trait_def(*trait_def_id))
+ .collect()
+ }
+
+ fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables[trait_def.0];
+ let trait_def = tables.tcx.trait_def(def_id);
+ trait_def.stable(&mut *tables)
+ }
+
+ fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls {
+ let mut tables = self.0.borrow_mut();
+ tables
+ .tcx
+ .trait_impls_in_crate(LOCAL_CRATE)
+ .iter()
+ .map(|impl_def_id| tables.impl_def(*impl_def_id))
+ .collect()
+ }
+
+ fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables[impl_def.0];
+ let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap();
+ impl_trait.stable(&mut *tables)
+ }
+
+ fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables[def_id];
+ let generics = tables.tcx.generics_of(def_id);
+ generics.stable(&mut *tables)
+ }
+
+ fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables[def_id];
+ let GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id);
+ stable_mir::ty::GenericPredicates {
+ parent: parent.map(|did| tables.trait_def(did)),
+ predicates: predicates
+ .iter()
+ .map(|(clause, span)| {
+ (
+ clause.as_predicate().kind().skip_binder().stable(&mut *tables),
+ span.stable(&mut *tables),
+ )
+ })
+ .collect(),
+ }
+ }
+
+ fn explicit_predicates_of(
+ &self,
+ def_id: stable_mir::DefId,
+ ) -> stable_mir::ty::GenericPredicates {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables[def_id];
+ let GenericPredicates { parent, predicates } = tables.tcx.explicit_predicates_of(def_id);
+ stable_mir::ty::GenericPredicates {
+ parent: parent.map(|did| tables.trait_def(did)),
+ predicates: predicates
+ .iter()
+ .map(|(clause, span)| {
+ (
+ clause.as_predicate().kind().skip_binder().stable(&mut *tables),
+ span.stable(&mut *tables),
+ )
+ })
+ .collect(),
+ }
+ }
+
+ fn local_crate(&self) -> stable_mir::Crate {
+ let tables = self.0.borrow();
+ smir_crate(tables.tcx, LOCAL_CRATE)
+ }
+
+ fn external_crates(&self) -> Vec<stable_mir::Crate> {
+ let tables = self.0.borrow();
+ tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
+ }
+
+ fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
+ let tables = self.0.borrow();
+ let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
+ .iter()
+ .chain(tables.tcx.crates(()).iter())
+ .map(|crate_num| {
+ let crate_name = tables.tcx.crate_name(*crate_num).to_string();
+ (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
+ })
+ .flatten()
+ .collect();
+ crates
+ }
+
+ fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol {
+ let tables = self.0.borrow();
+ if trimmed {
+ with_forced_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
+ } else {
+ with_no_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
+ }
+ }
+
+ fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
+ let tables = self.0.borrow();
+ tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
+ }
+
+ fn get_filename(&self, span: &Span) -> Filename {
+ let tables = self.0.borrow();
+ tables
+ .tcx
+ .sess
+ .source_map()
+ .span_to_filename(tables[*span])
+ .display(rustc_span::FileNameDisplayPreference::Local)
+ .to_string()
+ }
+
+ fn get_lines(&self, span: &Span) -> LineInfo {
+ let tables = self.0.borrow();
+ let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]);
+ LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
+ }
+
+ fn item_kind(&self, item: CrateItem) -> ItemKind {
+ let tables = self.0.borrow();
+ new_item_kind(tables.tcx.def_kind(tables[item.0]))
+ }
+
+ fn is_foreign_item(&self, item: DefId) -> bool {
+ let tables = self.0.borrow();
+ tables.tcx.is_foreign_item(tables[item])
+ }
+
+ fn adt_kind(&self, def: AdtDef) -> AdtKind {
+ let mut tables = self.0.borrow_mut();
+ def.internal(&mut *tables).adt_kind().stable(&mut *tables)
+ }
+
+ fn adt_is_box(&self, def: AdtDef) -> bool {
+ let mut tables = self.0.borrow_mut();
+ def.internal(&mut *tables).is_box()
+ }
+
+ fn adt_is_simd(&self, def: AdtDef) -> bool {
+ let mut tables = self.0.borrow_mut();
+ def.internal(&mut *tables).repr().simd()
+ }
+
+ fn adt_is_cstr(&self, def: AdtDef) -> bool {
+ let mut tables = self.0.borrow_mut();
+ let def_id = def.0.internal(&mut *tables);
+ tables.tcx.lang_items().c_str() == Some(def_id)
+ }
+
+ fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
+ let mut tables = self.0.borrow_mut();
+ let def_id = def.0.internal(&mut *tables);
+ let sig = tables.tcx.fn_sig(def_id).instantiate(tables.tcx, args.internal(&mut *tables));
+ sig.stable(&mut *tables)
+ }
+
+ fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig {
+ let mut tables = self.0.borrow_mut();
+ let args_ref = args.internal(&mut *tables);
+ let sig = args_ref.as_closure().sig();
+ sig.stable(&mut *tables)
+ }
+
+ fn adt_variants_len(&self, def: AdtDef) -> usize {
+ let mut tables = self.0.borrow_mut();
+ def.internal(&mut *tables).variants().len()
+ }
+
+ fn variant_name(&self, def: VariantDef) -> Symbol {
+ let mut tables = self.0.borrow_mut();
+ def.internal(&mut *tables).name.to_string()
+ }
+
+ fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef> {
+ let mut tables = self.0.borrow_mut();
+ def.internal(&mut *tables).fields.iter().map(|f| f.stable(&mut *tables)).collect()
+ }
+
+ fn eval_target_usize(&self, cnst: &Const) -> Result<u64, Error> {
+ let mut tables = self.0.borrow_mut();
+ let mir_const = cnst.internal(&mut *tables);
+ mir_const
+ .try_eval_target_usize(tables.tcx, ParamEnv::empty())
+ .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
+ }
+
+ fn usize_to_const(&self, val: u64) -> Result<Const, Error> {
+ let mut tables = self.0.borrow_mut();
+ let ty = tables.tcx.types.usize;
+ let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size;
+
+ let scalar = ScalarInt::try_from_uint(val, size).ok_or_else(|| {
+ Error::new(format!("Value overflow: cannot convert `{val}` to usize."))
+ })?;
+ Ok(rustc_middle::ty::Const::new_value(tables.tcx, ValTree::from_scalar_int(scalar), ty)
+ .stable(&mut *tables))
+ }
+
+ fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty {
+ let mut tables = self.0.borrow_mut();
+ let internal_kind = kind.internal(&mut *tables);
+ tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables)
+ }
+
+ fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty {
+ let mut tables = self.0.borrow_mut();
+ let inner = ty.internal(&mut *tables);
+ ty::Ty::new_box(tables.tcx, inner).stable(&mut *tables)
+ }
+
+ fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty {
+ let mut tables = self.0.borrow_mut();
+ tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables)
+ }
+
+ fn def_ty_with_args(&self, item: stable_mir::DefId, args: &GenericArgs) -> stable_mir::ty::Ty {
+ let mut tables = self.0.borrow_mut();
+ let args = args.internal(&mut *tables);
+ let def_ty = tables.tcx.type_of(item.internal(&mut *tables));
+ def_ty.instantiate(tables.tcx, args).stable(&mut *tables)
+ }
+
+ fn const_literal(&self, cnst: &stable_mir::ty::Const) -> String {
+ internal(cnst).to_string()
+ }
+
+ fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
+ let mut tables = self.0.borrow_mut();
+ tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
+ }
+
+ fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
+ let mut tables = self.0.borrow_mut();
+ tables.types[ty].kind().stable(&mut *tables)
+ }
+
+ fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty {
+ let mut tables = self.0.borrow_mut();
+ let internal_kind = ty.internal(&mut *tables);
+ let internal_ty = tables.tcx.mk_ty_from_kind(internal_kind);
+ internal_ty.discriminant_ty(tables.tcx).stable(&mut *tables)
+ }
+
+ fn instance_body(&self, def: InstanceDef) -> Option<Body> {
+ let mut tables = self.0.borrow_mut();
+ let instance = tables.instances[def];
+ tables
+ .has_body(instance)
+ .then(|| BodyBuilder::new(tables.tcx, instance).build(&mut *tables))
+ }
+
+ fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
+ let mut tables = self.0.borrow_mut();
+ let instance = tables.instances[def];
+ assert!(!instance.has_non_region_param(), "{instance:?} needs further substitution");
+ instance.ty(tables.tcx, ParamEnv::reveal_all()).stable(&mut *tables)
+ }
+
+ fn instance_args(&self, def: InstanceDef) -> GenericArgs {
+ let mut tables = self.0.borrow_mut();
+ let instance = tables.instances[def];
+ instance.args.stable(&mut *tables)
+ }
+
+ fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error> {
+ let mut tables = self.0.borrow_mut();
+ let instance = tables.instances[def];
+ Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables))
+ }
+
+ fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables.instances[def].def_id();
+ tables.create_def_id(def_id)
+ }
+
+ fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol {
+ let tables = self.0.borrow_mut();
+ let instance = tables.instances[instance];
+ tables.tcx.symbol_name(instance).name.to_string()
+ }
+
+ fn is_empty_drop_shim(&self, def: InstanceDef) -> bool {
+ let tables = self.0.borrow_mut();
+ let instance = tables.instances[def];
+ matches!(instance.def, ty::InstanceDef::DropGlue(_, None))
+ }
+
+ fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance {
+ let mut tables = self.0.borrow_mut();
+ let def_id = tables[def_id];
+ Instance::mono(tables.tcx, def_id).stable(&mut *tables)
+ }
+
+ fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
+ let tables = self.0.borrow();
+ let def_id = tables[def_id];
+ let generics = tables.tcx.generics_of(def_id);
+ let result = generics.requires_monomorphization(tables.tcx);
+ result
+ }
+
+ fn resolve_instance(
+ &self,
+ def: stable_mir::ty::FnDef,
+ args: &stable_mir::ty::GenericArgs,
+ ) -> Option<stable_mir::mir::mono::Instance> {
+ let mut tables = self.0.borrow_mut();
+ let def_id = def.0.internal(&mut *tables);
+ let args_ref = args.internal(&mut *tables);
+ match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
+ Ok(Some(instance)) => Some(instance.stable(&mut *tables)),
+ Ok(None) | Err(_) => None,
+ }
+ }
+
+ fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance {
+ let mut tables = self.0.borrow_mut();
+ let internal_ty = ty.internal(&mut *tables);
+ let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty);
+ instance.stable(&mut *tables)
+ }
+
+ fn resolve_for_fn_ptr(
+ &self,
+ def: FnDef,
+ args: &GenericArgs,
+ ) -> Option<stable_mir::mir::mono::Instance> {
+ let mut tables = self.0.borrow_mut();
+ let def_id = def.0.internal(&mut *tables);
+ let args_ref = args.internal(&mut *tables);
+ Instance::resolve_for_fn_ptr(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref)
+ .stable(&mut *tables)
+ }
+
+ fn resolve_closure(
+ &self,
+ def: ClosureDef,
+ args: &GenericArgs,
+ kind: ClosureKind,
+ ) -> Option<stable_mir::mir::mono::Instance> {
+ let mut tables = self.0.borrow_mut();
+ let def_id = def.0.internal(&mut *tables);
+ let args_ref = args.internal(&mut *tables);
+ let closure_kind = kind.internal(&mut *tables);
+ Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables)
+ }
+
+ fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result<Allocation, Error> {
+ let mut tables = self.0.borrow_mut();
+ let instance = tables.instances[def];
+ let result = tables.tcx.const_eval_instance(
+ ParamEnv::reveal_all(),
+ instance,
+ Some(tables.tcx.def_span(instance.def_id())),
+ );
+ result
+ .map(|const_val| {
+ alloc::try_new_allocation(const_ty.internal(&mut *tables), const_val, &mut *tables)
+ })
+ .map_err(|e| e.stable(&mut *tables))?
+ }
+
+ fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
+ let mut tables = self.0.borrow_mut();
+ let def_id = def.0.internal(&mut *tables);
+ tables.tcx.eval_static_initializer(def_id).stable(&mut *tables)
+ }
+
+ fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc {
+ let mut tables = self.0.borrow_mut();
+ let alloc_id = alloc.internal(&mut *tables);
+ tables.tcx.global_alloc(alloc_id).stable(&mut *tables)
+ }
+
+ fn vtable_allocation(
+ &self,
+ global_alloc: &GlobalAlloc,
+ ) -> Option<stable_mir::mir::alloc::AllocId> {
+ let mut tables = self.0.borrow_mut();
+ let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { return None };
+ let alloc_id = tables
+ .tcx
+ .vtable_allocation((ty.internal(&mut *tables), trait_ref.internal(&mut *tables)));
+ Some(alloc_id.stable(&mut *tables))
+ }
+
+ fn krate(&self, def_id: stable_mir::DefId) -> Crate {
+ let tables = self.0.borrow();
+ smir_crate(tables.tcx, tables[def_id].krate)
+ }
+
+ /// Retrieve the instance name for diagnostic messages.
+ ///
+ /// This will return the specialized name, e.g., `Vec<char>::new`.
+ fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol {
+ let tables = self.0.borrow_mut();
+ let instance = tables.instances[def];
+ if trimmed {
+ with_forced_trimmed_paths!(
+ tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
+ )
+ } else {
+ with_no_trimmed_paths!(
+ tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
+ )
+ }
+ }
+
+ fn ty_layout(&self, ty: Ty) -> Result<Layout, Error> {
+ let mut tables = self.0.borrow_mut();
+ let ty = ty.internal(&mut *tables);
+ let layout = tables.layout_of(ty)?.layout;
+ Ok(layout.stable(&mut *tables))
+ }
+
+ fn layout_shape(&self, id: Layout) -> LayoutShape {
+ let mut tables = self.0.borrow_mut();
+ id.internal(&mut *tables).0.stable(&mut *tables)
+ }
+}
+
+pub struct TablesWrapper<'tcx>(pub RefCell<Tables<'tcx>>);
+
+/// Implement error handling for extracting function ABI information.
+impl<'tcx> FnAbiOfHelpers<'tcx> for Tables<'tcx> {
+ type FnAbiOfResult = Result<&'tcx rustc_target::abi::call::FnAbi<'tcx, ty::Ty<'tcx>>, Error>;
+
+ #[inline]
+ fn handle_fn_abi_err(
+ &self,
+ err: ty::layout::FnAbiError<'tcx>,
+ _span: rustc_span::Span,
+ fn_abi_request: ty::layout::FnAbiRequest<'tcx>,
+ ) -> Error {
+ Error::new(format!("Failed to get ABI for `{fn_abi_request:?}`: {err:?}"))
+ }
+}
+
+impl<'tcx> LayoutOfHelpers<'tcx> for Tables<'tcx> {
+ type LayoutOfResult = Result<ty::layout::TyAndLayout<'tcx>, Error>;
+
+ #[inline]
+ fn handle_layout_err(
+ &self,
+ err: ty::layout::LayoutError<'tcx>,
+ _span: rustc_span::Span,
+ ty: ty::Ty<'tcx>,
+ ) -> Error {
+ Error::new(format!("Failed to get layout for `{ty}`: {err}"))
+ }
+}
+
+impl<'tcx> HasParamEnv<'tcx> for Tables<'tcx> {
+ fn param_env(&self) -> ty::ParamEnv<'tcx> {
+ ty::ParamEnv::reveal_all()
+ }
+}
+
+impl<'tcx> HasTyCtxt<'tcx> for Tables<'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+}
+
+impl<'tcx> HasDataLayout for Tables<'tcx> {
+ fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
+ self.tcx.data_layout()
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
new file mode 100644
index 000000000..632e97b32
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
@@ -0,0 +1,242 @@
+//! Conversion of internal Rust compiler `rustc_target::abi` and `rustc_abi` items to stable ones.
+
+#![allow(rustc::usage_of_qualified_ty)]
+
+use crate::rustc_smir::{Stable, Tables};
+use rustc_middle::ty;
+use rustc_target::abi::call::Conv;
+use stable_mir::abi::{
+ ArgAbi, CallConvention, FieldsShape, FnAbi, Layout, LayoutShape, PassMode, TagEncoding,
+ TyAndLayout, ValueAbi, VariantsShape,
+};
+use stable_mir::ty::{Align, IndexedVal, Size, VariantIdx};
+use stable_mir::{opaque, Opaque};
+
+impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx {
+ type T = VariantIdx;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ VariantIdx::to_val(self.as_usize())
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
+ type T = stable_mir::target::Endian;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ rustc_abi::Endian::Little => stable_mir::target::Endian::Little,
+ rustc_abi::Endian::Big => stable_mir::target::Endian::Big,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_target::abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
+ type T = TyAndLayout;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ TyAndLayout { ty: self.ty.stable(tables), layout: self.layout.stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_target::abi::Layout<'tcx> {
+ type T = Layout;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables.layout_id(*self)
+ }
+}
+
+impl<'tcx> Stable<'tcx>
+ for rustc_abi::LayoutS<rustc_target::abi::FieldIdx, rustc_target::abi::VariantIdx>
+{
+ type T = LayoutShape;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ LayoutShape {
+ fields: self.fields.stable(tables),
+ variants: self.variants.stable(tables),
+ abi: self.abi.stable(tables),
+ abi_align: self.align.abi.stable(tables),
+ size: self.size.stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_target::abi::call::FnAbi<'tcx, ty::Ty<'tcx>> {
+ type T = FnAbi;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ assert!(self.args.len() >= self.fixed_count as usize);
+ assert!(!self.c_variadic || matches!(self.conv, Conv::C));
+ FnAbi {
+ args: self.args.as_ref().stable(tables),
+ ret: self.ret.stable(tables),
+ fixed_count: self.fixed_count,
+ conv: self.conv.stable(tables),
+ c_variadic: self.c_variadic,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_target::abi::call::ArgAbi<'tcx, ty::Ty<'tcx>> {
+ type T = ArgAbi;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ ArgAbi {
+ ty: self.layout.ty.stable(tables),
+ layout: self.layout.layout.stable(tables),
+ mode: self.mode.stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_target::abi::call::Conv {
+ type T = CallConvention;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ Conv::C => CallConvention::C,
+ Conv::Rust => CallConvention::Rust,
+ Conv::Cold => CallConvention::Cold,
+ Conv::PreserveMost => CallConvention::PreserveMost,
+ Conv::PreserveAll => CallConvention::PreserveAll,
+ Conv::ArmAapcs => CallConvention::ArmAapcs,
+ Conv::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
+ Conv::Msp430Intr => CallConvention::Msp430Intr,
+ Conv::PtxKernel => CallConvention::PtxKernel,
+ Conv::X86Fastcall => CallConvention::X86Fastcall,
+ Conv::X86Intr => CallConvention::X86Intr,
+ Conv::X86Stdcall => CallConvention::X86Stdcall,
+ Conv::X86ThisCall => CallConvention::X86ThisCall,
+ Conv::X86VectorCall => CallConvention::X86VectorCall,
+ Conv::X86_64SysV => CallConvention::X86_64SysV,
+ Conv::X86_64Win64 => CallConvention::X86_64Win64,
+ Conv::AmdGpuKernel => CallConvention::AmdGpuKernel,
+ Conv::AvrInterrupt => CallConvention::AvrInterrupt,
+ Conv::AvrNonBlockingInterrupt => CallConvention::AvrNonBlockingInterrupt,
+ Conv::RiscvInterrupt { .. } => CallConvention::RiscvInterrupt,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_target::abi::call::PassMode {
+ type T = PassMode;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ rustc_target::abi::call::PassMode::Ignore => PassMode::Ignore,
+ rustc_target::abi::call::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
+ rustc_target::abi::call::PassMode::Pair(first, second) => {
+ PassMode::Pair(opaque(first), opaque(second))
+ }
+ rustc_target::abi::call::PassMode::Cast { pad_i32, cast } => {
+ PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
+ }
+ rustc_target::abi::call::PassMode::Indirect { attrs, meta_attrs, on_stack } => {
+ PassMode::Indirect {
+ attrs: opaque(attrs),
+ meta_attrs: opaque(meta_attrs),
+ on_stack: *on_stack,
+ }
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_target::abi::FieldIdx> {
+ type T = FieldsShape;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
+ rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
+ rustc_abi::FieldsShape::Array { stride, count } => {
+ FieldsShape::Array { stride: stride.stable(tables), count: *count }
+ }
+ rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
+ FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables) }
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx>
+ for rustc_abi::Variants<rustc_target::abi::FieldIdx, rustc_target::abi::VariantIdx>
+{
+ type T = VariantsShape;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ rustc_abi::Variants::Single { index } => {
+ VariantsShape::Single { index: index.stable(tables) }
+ }
+ rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
+ VariantsShape::Multiple {
+ tag: tag.stable(tables),
+ tag_encoding: tag_encoding.stable(tables),
+ tag_field: *tag_field,
+ variants: variants.iter().as_slice().stable(tables),
+ }
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_target::abi::VariantIdx> {
+ type T = TagEncoding;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
+ rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
+ TagEncoding::Niche {
+ untagged_variant: untagged_variant.stable(tables),
+ niche_variants: niche_variants.stable(tables),
+ niche_start: *niche_start,
+ }
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::Abi {
+ type T = ValueAbi;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match *self {
+ rustc_abi::Abi::Uninhabited => ValueAbi::Uninhabited,
+ rustc_abi::Abi::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)),
+ rustc_abi::Abi::ScalarPair(first, second) => {
+ ValueAbi::ScalarPair(first.stable(tables), second.stable(tables))
+ }
+ rustc_abi::Abi::Vector { element, count } => {
+ ValueAbi::Vector { element: element.stable(tables), count }
+ }
+ rustc_abi::Abi::Aggregate { sized } => ValueAbi::Aggregate { sized },
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::Size {
+ type T = Size;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ self.bytes_usize()
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::Align {
+ type T = Align;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ self.bytes()
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
+ type T = Opaque;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ opaque(self)
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/error.rs b/compiler/rustc_smir/src/rustc_smir/convert/error.rs
new file mode 100644
index 000000000..6c582b799
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/convert/error.rs
@@ -0,0 +1,22 @@
+//! Handle the conversion of different internal errors into a stable version.
+//!
+//! Currently we encode everything as [stable_mir::Error], which is represented as a string.
+use crate::rustc_smir::{Stable, Tables};
+use rustc_middle::mir::interpret::AllocError;
+use rustc_middle::ty::layout::LayoutError;
+
+impl<'tcx> Stable<'tcx> for LayoutError<'tcx> {
+ type T = stable_mir::Error;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::Error::new(format!("{self:?}"))
+ }
+}
+
+impl<'tcx> Stable<'tcx> for AllocError {
+ type T = stable_mir::Error;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::Error::new(format!("{self:?}"))
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
new file mode 100644
index 000000000..49bf2192f
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -0,0 +1,746 @@
+//! Conversion of internal Rust compiler `mir` items to stable ones.
+
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::alloc_range;
+use rustc_middle::mir::mono::MonoItem;
+use stable_mir::mir::alloc::GlobalAlloc;
+use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment};
+use stable_mir::ty::{Allocation, Const, ConstantKind};
+use stable_mir::{opaque, Error};
+
+use crate::rustc_smir::{alloc, Stable, Tables};
+
+impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
+ type T = stable_mir::mir::Body;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::mir::Body::new(
+ self.basic_blocks
+ .iter()
+ .map(|block| stable_mir::mir::BasicBlock {
+ terminator: block.terminator().stable(tables),
+ statements: block
+ .statements
+ .iter()
+ .map(|statement| statement.stable(tables))
+ .collect(),
+ })
+ .collect(),
+ self.local_decls
+ .iter()
+ .map(|decl| stable_mir::mir::LocalDecl {
+ ty: decl.ty.stable(tables),
+ span: decl.source_info.span.stable(tables),
+ mutability: decl.mutability.stable(tables),
+ })
+ .collect(),
+ self.arg_count,
+ self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
+ self.spread_arg.stable(tables),
+ self.span.stable(tables),
+ )
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
+ type T = stable_mir::mir::VarDebugInfo;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::mir::VarDebugInfo {
+ name: self.name.to_string(),
+ source_info: self.source_info.stable(tables),
+ composite: self.composite.as_ref().map(|composite| composite.stable(tables)),
+ value: self.value.stable(tables),
+ argument_index: self.argument_index,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
+ type T = stable_mir::mir::Statement;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::SourceInfo {
+ type T = stable_mir::mir::SourceInfo;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
+ type T = stable_mir::mir::VarDebugInfoFragment;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ VarDebugInfoFragment {
+ ty: self.ty.stable(tables),
+ projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
+ type T = stable_mir::mir::VarDebugInfoContents;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ mir::VarDebugInfoContents::Place(place) => {
+ stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
+ }
+ mir::VarDebugInfoContents::Const(const_operand) => {
+ let op = ConstOperand {
+ span: const_operand.span.stable(tables),
+ user_ty: const_operand.user_ty.map(|index| index.as_usize()),
+ const_: const_operand.const_.stable(tables),
+ };
+ stable_mir::mir::VarDebugInfoContents::Const(op)
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
+ type T = stable_mir::mir::StatementKind;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign(
+ assign.0.stable(tables),
+ assign.1.stable(tables),
+ ),
+ mir::StatementKind::FakeRead(fake_read_place) => {
+ stable_mir::mir::StatementKind::FakeRead(
+ fake_read_place.0.stable(tables),
+ fake_read_place.1.stable(tables),
+ )
+ }
+ mir::StatementKind::SetDiscriminant { place, variant_index } => {
+ stable_mir::mir::StatementKind::SetDiscriminant {
+ place: place.as_ref().stable(tables),
+ variant_index: variant_index.stable(tables),
+ }
+ }
+ mir::StatementKind::Deinit(place) => {
+ stable_mir::mir::StatementKind::Deinit(place.stable(tables))
+ }
+
+ mir::StatementKind::StorageLive(place) => {
+ stable_mir::mir::StatementKind::StorageLive(place.stable(tables))
+ }
+
+ mir::StatementKind::StorageDead(place) => {
+ stable_mir::mir::StatementKind::StorageDead(place.stable(tables))
+ }
+ mir::StatementKind::Retag(retag, place) => {
+ stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables))
+ }
+ mir::StatementKind::PlaceMention(place) => {
+ stable_mir::mir::StatementKind::PlaceMention(place.stable(tables))
+ }
+ mir::StatementKind::AscribeUserType(place_projection, variance) => {
+ stable_mir::mir::StatementKind::AscribeUserType {
+ place: place_projection.as_ref().0.stable(tables),
+ projections: place_projection.as_ref().1.stable(tables),
+ variance: variance.stable(tables),
+ }
+ }
+ mir::StatementKind::Coverage(coverage) => {
+ stable_mir::mir::StatementKind::Coverage(opaque(coverage))
+ }
+ mir::StatementKind::Intrinsic(intrinstic) => {
+ stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables))
+ }
+ mir::StatementKind::ConstEvalCounter => {
+ stable_mir::mir::StatementKind::ConstEvalCounter
+ }
+ mir::StatementKind::Nop => stable_mir::mir::StatementKind::Nop,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
+ type T = stable_mir::mir::Rvalue;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::Rvalue::*;
+ match self {
+ Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
+ Repeat(op, len) => {
+ let len = len.stable(tables);
+ stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
+ }
+ Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
+ region.stable(tables),
+ kind.stable(tables),
+ place.stable(tables),
+ ),
+ ThreadLocalRef(def_id) => {
+ stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
+ }
+ AddressOf(mutability, place) => {
+ stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
+ }
+ Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
+ Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
+ cast_kind.stable(tables),
+ op.stable(tables),
+ ty.stable(tables),
+ ),
+ BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
+ bin_op.stable(tables),
+ ops.0.stable(tables),
+ ops.1.stable(tables),
+ ),
+ CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp(
+ bin_op.stable(tables),
+ ops.0.stable(tables),
+ ops.1.stable(tables),
+ ),
+ NullaryOp(null_op, 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))
+ }
+ Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)),
+ Aggregate(agg_kind, operands) => {
+ let operands = operands.iter().map(|op| op.stable(tables)).collect();
+ stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
+ }
+ ShallowInitBox(op, ty) => {
+ stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
+ }
+ CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Mutability {
+ type T = stable_mir::mir::Mutability;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_hir::Mutability::*;
+ match *self {
+ Not => stable_mir::mir::Mutability::Not,
+ Mut => stable_mir::mir::Mutability::Mut,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::BorrowKind {
+ type T = stable_mir::mir::BorrowKind;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::BorrowKind::*;
+ match *self {
+ Shared => stable_mir::mir::BorrowKind::Shared,
+ Fake => stable_mir::mir::BorrowKind::Fake,
+ Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) },
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
+ type T = stable_mir::mir::MutBorrowKind;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::MutBorrowKind::*;
+ match *self {
+ Default => stable_mir::mir::MutBorrowKind::Default,
+ TwoPhaseBorrow => stable_mir::mir::MutBorrowKind::TwoPhaseBorrow,
+ ClosureCapture => stable_mir::mir::MutBorrowKind::ClosureCapture,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
+ type T = stable_mir::mir::NullOp;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::NullOp::*;
+ match self {
+ SizeOf => stable_mir::mir::NullOp::SizeOf,
+ AlignOf => stable_mir::mir::NullOp::AlignOf,
+ OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf(
+ indices.iter().map(|idx| idx.stable(tables)).collect(),
+ ),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::CastKind {
+ type T = stable_mir::mir::CastKind;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::CastKind::*;
+ match self {
+ PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress,
+ PointerFromExposedAddress => stable_mir::mir::CastKind::PointerFromExposedAddress,
+ PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
+ DynStar => stable_mir::mir::CastKind::DynStar,
+ IntToInt => stable_mir::mir::CastKind::IntToInt,
+ FloatToInt => stable_mir::mir::CastKind::FloatToInt,
+ FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
+ IntToFloat => stable_mir::mir::CastKind::IntToFloat,
+ PtrToPtr => stable_mir::mir::CastKind::PtrToPtr,
+ FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr,
+ Transmute => stable_mir::mir::CastKind::Transmute,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
+ type T = stable_mir::mir::FakeReadCause;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::FakeReadCause::*;
+ match self {
+ ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard,
+ ForMatchedPlace(local_def_id) => {
+ stable_mir::mir::FakeReadCause::ForMatchedPlace(opaque(local_def_id))
+ }
+ ForGuardBinding => stable_mir::mir::FakeReadCause::ForGuardBinding,
+ ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet(opaque(local_def_id)),
+ ForIndex => stable_mir::mir::FakeReadCause::ForIndex,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
+ type T = stable_mir::mir::Operand;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::Operand::*;
+ match self {
+ Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)),
+ Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)),
+ Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
+ type T = stable_mir::mir::Constant;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::mir::Constant {
+ span: self.span.stable(tables),
+ user_ty: self.user_ty.map(|u| u.as_usize()).or(None),
+ literal: self.const_.stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
+ type T = stable_mir::mir::Place;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::mir::Place {
+ local: self.local.as_usize(),
+ projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
+ type T = stable_mir::mir::ProjectionElem;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::ProjectionElem::*;
+ match self {
+ Deref => stable_mir::mir::ProjectionElem::Deref,
+ Field(idx, ty) => {
+ stable_mir::mir::ProjectionElem::Field(idx.stable(tables), ty.stable(tables))
+ }
+ Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables)),
+ ConstantIndex { offset, min_length, from_end } => {
+ stable_mir::mir::ProjectionElem::ConstantIndex {
+ offset: *offset,
+ min_length: *min_length,
+ from_end: *from_end,
+ }
+ }
+ Subslice { from, to, from_end } => stable_mir::mir::ProjectionElem::Subslice {
+ from: *from,
+ to: *to,
+ from_end: *from_end,
+ },
+ // MIR includes an `Option<Symbol>` argument for `Downcast` that is the name of the
+ // variant, used for printing MIR. However this information should also be accessible
+ // via a lookup using the `VariantIdx`. The `Option<Symbol>` argument is therefore
+ // dropped when converting to Stable MIR. A brief justification for this decision can be
+ // found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486
+ Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)),
+ OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)),
+ Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
+ type T = stable_mir::mir::UserTypeProjection;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Local {
+ type T = stable_mir::mir::Local;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ self.as_usize()
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::RetagKind {
+ type T = stable_mir::mir::RetagKind;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::RetagKind;
+ match self {
+ RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry,
+ RetagKind::TwoPhase => stable_mir::mir::RetagKind::TwoPhase,
+ RetagKind::Raw => stable_mir::mir::RetagKind::Raw,
+ RetagKind::Default => stable_mir::mir::RetagKind::Default,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::UnwindAction {
+ type T = stable_mir::mir::UnwindAction;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::UnwindAction;
+ match self {
+ UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue,
+ UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable,
+ UnwindAction::Terminate(_) => stable_mir::mir::UnwindAction::Terminate,
+ UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
+ type T = stable_mir::mir::NonDivergingIntrinsic;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::NonDivergingIntrinsic;
+ use stable_mir::mir::CopyNonOverlapping;
+ match self {
+ NonDivergingIntrinsic::Assume(op) => {
+ stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables))
+ }
+ NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => {
+ stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
+ src: copy_non_overlapping.src.stable(tables),
+ dst: copy_non_overlapping.dst.stable(tables),
+ count: copy_non_overlapping.count.stable(tables),
+ })
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
+ type T = stable_mir::mir::AssertMessage;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::AssertKind;
+ match self {
+ AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck {
+ len: len.stable(tables),
+ index: index.stable(tables),
+ },
+ AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow(
+ bin_op.stable(tables),
+ op1.stable(tables),
+ op2.stable(tables),
+ ),
+ AssertKind::OverflowNeg(op) => {
+ stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables))
+ }
+ AssertKind::DivisionByZero(op) => {
+ stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables))
+ }
+ AssertKind::RemainderByZero(op) => {
+ stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables))
+ }
+ AssertKind::ResumedAfterReturn(coroutine) => {
+ stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables))
+ }
+ AssertKind::ResumedAfterPanic(coroutine) => {
+ stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables))
+ }
+ AssertKind::MisalignedPointerDereference { required, found } => {
+ stable_mir::mir::AssertMessage::MisalignedPointerDereference {
+ required: required.stable(tables),
+ found: found.stable(tables),
+ }
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::BinOp {
+ type T = stable_mir::mir::BinOp;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::BinOp;
+ match self {
+ BinOp::Add => stable_mir::mir::BinOp::Add,
+ BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked,
+ BinOp::Sub => stable_mir::mir::BinOp::Sub,
+ BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked,
+ BinOp::Mul => stable_mir::mir::BinOp::Mul,
+ BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked,
+ BinOp::Div => stable_mir::mir::BinOp::Div,
+ BinOp::Rem => stable_mir::mir::BinOp::Rem,
+ BinOp::BitXor => stable_mir::mir::BinOp::BitXor,
+ BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd,
+ BinOp::BitOr => stable_mir::mir::BinOp::BitOr,
+ BinOp::Shl => stable_mir::mir::BinOp::Shl,
+ BinOp::ShlUnchecked => stable_mir::mir::BinOp::ShlUnchecked,
+ BinOp::Shr => stable_mir::mir::BinOp::Shr,
+ BinOp::ShrUnchecked => stable_mir::mir::BinOp::ShrUnchecked,
+ BinOp::Eq => stable_mir::mir::BinOp::Eq,
+ BinOp::Lt => stable_mir::mir::BinOp::Lt,
+ BinOp::Le => stable_mir::mir::BinOp::Le,
+ BinOp::Ne => stable_mir::mir::BinOp::Ne,
+ BinOp::Ge => stable_mir::mir::BinOp::Ge,
+ BinOp::Gt => stable_mir::mir::BinOp::Gt,
+ BinOp::Offset => stable_mir::mir::BinOp::Offset,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::UnOp {
+ type T = stable_mir::mir::UnOp;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::UnOp;
+ match self {
+ UnOp::Not => stable_mir::mir::UnOp::Not,
+ UnOp::Neg => stable_mir::mir::UnOp::Neg,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
+ type T = stable_mir::mir::AggregateKind;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ mir::AggregateKind::Array(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) => {
+ stable_mir::mir::AggregateKind::Adt(
+ tables.adt_def(*def_id),
+ var_idx.stable(tables),
+ generic_arg.stable(tables),
+ user_ty_index.map(|idx| idx.index()),
+ field_idx.map(|idx| idx.index()),
+ )
+ }
+ mir::AggregateKind::Closure(def_id, generic_arg) => {
+ stable_mir::mir::AggregateKind::Closure(
+ tables.closure_def(*def_id),
+ generic_arg.stable(tables),
+ )
+ }
+ mir::AggregateKind::Coroutine(def_id, generic_arg, movability) => {
+ stable_mir::mir::AggregateKind::Coroutine(
+ tables.coroutine_def(*def_id),
+ generic_arg.stable(tables),
+ movability.stable(tables),
+ )
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
+ type T = stable_mir::mir::InlineAsmOperand;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::mir::InlineAsmOperand;
+
+ let (in_value, out_place) = match self {
+ InlineAsmOperand::In { value, .. } => (Some(value.stable(tables)), None),
+ InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable(tables))),
+ InlineAsmOperand::InOut { in_value, out_place, .. } => {
+ (Some(in_value.stable(tables)), out_place.map(|place| place.stable(tables)))
+ }
+ InlineAsmOperand::Const { .. }
+ | InlineAsmOperand::SymFn { .. }
+ | InlineAsmOperand::SymStatic { .. } => (None, None),
+ };
+
+ stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{self:?}") }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
+ type T = stable_mir::mir::Terminator;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::mir::Terminator;
+ Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
+ type T = stable_mir::mir::TerminatorKind;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::mir::TerminatorKind;
+ match self {
+ mir::TerminatorKind::Goto { target } => {
+ TerminatorKind::Goto { target: target.as_usize() }
+ }
+ mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt {
+ discr: discr.stable(tables),
+ targets: {
+ let branches = targets.iter().map(|(val, target)| (val, target.as_usize()));
+ stable_mir::mir::SwitchTargets::new(
+ branches.collect(),
+ targets.otherwise().as_usize(),
+ )
+ },
+ },
+ mir::TerminatorKind::UnwindResume => TerminatorKind::Resume,
+ mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort,
+ mir::TerminatorKind::Return => TerminatorKind::Return,
+ mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable,
+ mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => {
+ TerminatorKind::Drop {
+ place: place.stable(tables),
+ target: target.as_usize(),
+ unwind: unwind.stable(tables),
+ }
+ }
+ mir::TerminatorKind::Call {
+ func,
+ args,
+ destination,
+ target,
+ unwind,
+ call_source: _,
+ fn_span: _,
+ } => TerminatorKind::Call {
+ func: func.stable(tables),
+ args: args.iter().map(|arg| arg.stable(tables)).collect(),
+ destination: destination.stable(tables),
+ target: target.map(|t| t.as_usize()),
+ unwind: unwind.stable(tables),
+ },
+ mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => {
+ TerminatorKind::Assert {
+ cond: cond.stable(tables),
+ expected: *expected,
+ msg: msg.stable(tables),
+ target: target.as_usize(),
+ unwind: unwind.stable(tables),
+ }
+ }
+ mir::TerminatorKind::InlineAsm {
+ template,
+ operands,
+ options,
+ line_spans,
+ destination,
+ unwind,
+ } => TerminatorKind::InlineAsm {
+ template: format!("{template:?}"),
+ operands: operands.iter().map(|operand| operand.stable(tables)).collect(),
+ options: format!("{options:?}"),
+ line_spans: format!("{line_spans:?}"),
+ destination: destination.map(|d| d.as_usize()),
+ unwind: unwind.stable(tables),
+ },
+ mir::TerminatorKind::Yield { .. }
+ | mir::TerminatorKind::CoroutineDrop
+ | mir::TerminatorKind::FalseEdge { .. }
+ | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
+ type T = Allocation;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ self.inner().stable(tables)
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
+ type T = stable_mir::ty::Allocation;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ alloc::allocation_filter(
+ self,
+ alloc_range(rustc_target::abi::Size::ZERO, self.size()),
+ tables,
+ )
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
+ type T = stable_mir::mir::alloc::AllocId;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables.create_alloc_id(*self)
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
+ type T = GlobalAlloc;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ mir::interpret::GlobalAlloc::Function(instance) => {
+ GlobalAlloc::Function(instance.stable(tables))
+ }
+ mir::interpret::GlobalAlloc::VTable(ty, trait_ref) => {
+ GlobalAlloc::VTable(ty.stable(tables), trait_ref.stable(tables))
+ }
+ mir::interpret::GlobalAlloc::Static(def) => {
+ GlobalAlloc::Static(tables.static_def(*def))
+ }
+ mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
+ type T = stable_mir::ty::Const;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ match *self {
+ mir::Const::Ty(c) => c.stable(tables),
+ 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()),
+ });
+ let ty = ty.stable(tables);
+ let id = tables.intern_const(*self);
+ Const::new(kind, ty, id)
+ }
+ mir::Const::Val(mir::ConstValue::ZeroSized, ty) => {
+ let ty = ty.stable(tables);
+ let id = tables.intern_const(*self);
+ Const::new(ConstantKind::ZeroSized, 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)
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
+ type T = Error;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ Error::new(format!("{self:?}"))
+ }
+}
+
+impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
+ type T = stable_mir::mir::mono::MonoItem;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::mir::mono::MonoItem as StableMonoItem;
+ match self {
+ MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)),
+ MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)),
+ MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)),
+ }
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
new file mode 100644
index 000000000..8b7b26f96
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
@@ -0,0 +1,74 @@
+//! Conversion of internal Rust compiler items to stable ones.
+
+use rustc_target::abi::FieldIdx;
+
+use crate::rustc_smir::{Stable, Tables};
+
+mod abi;
+mod error;
+mod mir;
+mod ty;
+
+impl<'tcx> Stable<'tcx> for rustc_hir::Unsafety {
+ type T = stable_mir::mir::Safety;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ rustc_hir::Unsafety::Unsafe => stable_mir::mir::Safety::Unsafe,
+ rustc_hir::Unsafety::Normal => stable_mir::mir::Safety::Normal,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for FieldIdx {
+ type T = usize;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ self.as_usize()
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
+ type T = stable_mir::mir::CoroutineSource;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_hir::CoroutineSource;
+ match self {
+ CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block,
+ CoroutineSource::Closure => stable_mir::mir::CoroutineSource::Closure,
+ CoroutineSource::Fn => stable_mir::mir::CoroutineSource::Fn,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
+ type T = stable_mir::mir::CoroutineKind;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_hir::CoroutineKind;
+ match self {
+ CoroutineKind::Async(source) => {
+ stable_mir::mir::CoroutineKind::Async(source.stable(tables))
+ }
+ CoroutineKind::Gen(source) => {
+ stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
+ }
+ CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
+ CoroutineKind::AsyncGen(source) => {
+ stable_mir::mir::CoroutineKind::AsyncGen(source.stable(tables))
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_span::Symbol {
+ type T = stable_mir::Symbol;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ self.to_string()
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_span::Span {
+ type T = stable_mir::ty::Span;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ tables.create_span(*self)
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
new file mode 100644
index 000000000..cbdddc300
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -0,0 +1,829 @@
+//! Conversion of internal Rust compiler `ty` items to stable ones.
+
+use rustc_middle::ty::Ty;
+use rustc_middle::{mir, ty};
+use stable_mir::ty::{
+ AdtKind, Const, ConstantKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy,
+ TyKind, UintTy,
+};
+
+use crate::rustc_smir::{alloc, Stable, Tables};
+
+impl<'tcx> Stable<'tcx> for ty::AliasKind {
+ type T = stable_mir::ty::AliasKind;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::AliasKind::*;
+ match self {
+ Projection => stable_mir::ty::AliasKind::Projection,
+ Inherent => stable_mir::ty::AliasKind::Inherent,
+ Opaque => stable_mir::ty::AliasKind::Opaque,
+ Weak => stable_mir::ty::AliasKind::Weak,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> {
+ type T = stable_mir::ty::AliasTy;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::AliasTy { args, def_id, .. } = self;
+ stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::DynKind {
+ type T = stable_mir::ty::DynKind;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::DynKind;
+ match self {
+ DynKind::Dyn => stable_mir::ty::DynKind::Dyn,
+ DynKind::DynStar => stable_mir::ty::DynKind::DynStar,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> {
+ type T = stable_mir::ty::ExistentialPredicate;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::ExistentialPredicate::*;
+ match self {
+ ty::ExistentialPredicate::Trait(existential_trait_ref) => {
+ Trait(existential_trait_ref.stable(tables))
+ }
+ ty::ExistentialPredicate::Projection(existential_projection) => {
+ Projection(existential_projection.stable(tables))
+ }
+ ty::ExistentialPredicate::AutoTrait(def_id) => AutoTrait(tables.trait_def(*def_id)),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
+ type T = stable_mir::ty::ExistentialTraitRef;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::ExistentialTraitRef { def_id, args } = self;
+ stable_mir::ty::ExistentialTraitRef {
+ def_id: tables.trait_def(*def_id),
+ generic_args: args.stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
+ type T = stable_mir::ty::TermKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::TermKind;
+ match self {
+ ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)),
+ ty::TermKind::Const(cnst) => {
+ let cnst = cnst.stable(tables);
+ TermKind::Const(cnst)
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> {
+ type T = stable_mir::ty::ExistentialProjection;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::ExistentialProjection { def_id, args, term } = self;
+ stable_mir::ty::ExistentialProjection {
+ def_id: tables.trait_def(*def_id),
+ generic_args: args.stable(tables),
+ term: term.unpack().stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
+ type T = stable_mir::mir::PointerCoercion;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::adjustment::PointerCoercion;
+ match self {
+ PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer,
+ PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer,
+ PointerCoercion::ClosureFnPointer(unsafety) => {
+ stable_mir::mir::PointerCoercion::ClosureFnPointer(unsafety.stable(tables))
+ }
+ PointerCoercion::MutToConstPointer => {
+ stable_mir::mir::PointerCoercion::MutToConstPointer
+ }
+ PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
+ PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
+ type T = usize;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ self.as_usize()
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::AdtKind {
+ type T = AdtKind;
+
+ fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ty::AdtKind::Struct => AdtKind::Struct,
+ ty::AdtKind::Union => AdtKind::Union,
+ ty::AdtKind::Enum => AdtKind::Enum,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::FieldDef {
+ type T = stable_mir::ty::FieldDef;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::ty::FieldDef {
+ def: tables.create_def_id(self.did),
+ name: self.name.stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
+ type T = stable_mir::ty::GenericArgs;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect())
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
+ type T = stable_mir::ty::GenericArgKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::GenericArgKind;
+ match self {
+ ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)),
+ ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)),
+ ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)),
+ }
+ }
+}
+
+impl<'tcx, S, V> Stable<'tcx> for ty::Binder<'tcx, S>
+where
+ S: Stable<'tcx, T = V>,
+{
+ type T = stable_mir::ty::Binder<V>;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::Binder;
+
+ Binder {
+ value: self.as_ref().skip_binder().stable(tables),
+ bound_vars: self
+ .bound_vars()
+ .iter()
+ .map(|bound_var| bound_var.stable(tables))
+ .collect(),
+ }
+ }
+}
+
+impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder<S>
+where
+ S: Stable<'tcx, T = V>,
+{
+ type T = stable_mir::ty::EarlyBinder<V>;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::EarlyBinder;
+
+ EarlyBinder { value: self.as_ref().skip_binder().stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
+ type T = stable_mir::ty::FnSig;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_target::spec::abi;
+ use stable_mir::ty::{Abi, FnSig};
+
+ FnSig {
+ 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 {
+ abi::Abi::Rust => Abi::Rust,
+ abi::Abi::C { unwind } => Abi::C { unwind },
+ abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind },
+ abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind },
+ abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind },
+ abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind },
+ abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind },
+ abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind },
+ abi::Abi::Win64 { unwind } => Abi::Win64 { unwind },
+ abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind },
+ abi::Abi::PtxKernel => Abi::PtxKernel,
+ abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt,
+ abi::Abi::X86Interrupt => Abi::X86Interrupt,
+ abi::Abi::AmdGpuKernel => Abi::AmdGpuKernel,
+ abi::Abi::EfiApi => Abi::EfiApi,
+ abi::Abi::AvrInterrupt => Abi::AvrInterrupt,
+ abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt,
+ abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
+ abi::Abi::Wasm => Abi::Wasm,
+ abi::Abi::System { unwind } => Abi::System { unwind },
+ abi::Abi::RustIntrinsic => Abi::RustIntrinsic,
+ abi::Abi::RustCall => Abi::RustCall,
+ abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic,
+ abi::Abi::Unadjusted => Abi::Unadjusted,
+ abi::Abi::RustCold => Abi::RustCold,
+ abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM,
+ abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS,
+ },
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
+ type T = stable_mir::ty::BoundTyKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::BoundTyKind;
+
+ match self {
+ ty::BoundTyKind::Anon => BoundTyKind::Anon,
+ ty::BoundTyKind::Param(def_id, symbol) => {
+ BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string())
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
+ type T = stable_mir::ty::BoundRegionKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::BoundRegionKind;
+
+ match self {
+ ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon,
+ ty::BoundRegionKind::BrNamed(def_id, symbol) => {
+ BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string())
+ }
+ ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::BoundVariableKind {
+ type T = stable_mir::ty::BoundVariableKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::BoundVariableKind;
+
+ match self {
+ ty::BoundVariableKind::Ty(bound_ty_kind) => {
+ BoundVariableKind::Ty(bound_ty_kind.stable(tables))
+ }
+ ty::BoundVariableKind::Region(bound_region_kind) => {
+ BoundVariableKind::Region(bound_region_kind.stable(tables))
+ }
+ ty::BoundVariableKind::Const => BoundVariableKind::Const,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::IntTy {
+ type T = IntTy;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ty::IntTy::Isize => IntTy::Isize,
+ ty::IntTy::I8 => IntTy::I8,
+ ty::IntTy::I16 => IntTy::I16,
+ ty::IntTy::I32 => IntTy::I32,
+ ty::IntTy::I64 => IntTy::I64,
+ ty::IntTy::I128 => IntTy::I128,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::UintTy {
+ type T = UintTy;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ty::UintTy::Usize => UintTy::Usize,
+ ty::UintTy::U8 => UintTy::U8,
+ ty::UintTy::U16 => UintTy::U16,
+ ty::UintTy::U32 => UintTy::U32,
+ ty::UintTy::U64 => UintTy::U64,
+ ty::UintTy::U128 => UintTy::U128,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::FloatTy {
+ type T = FloatTy;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ty::FloatTy::F32 => FloatTy::F32,
+ ty::FloatTy::F64 => FloatTy::F64,
+ }
+ }
+}
+
+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 {
+ ty::Bool => TyKind::RigidTy(RigidTy::Bool),
+ ty::Char => TyKind::RigidTy(RigidTy::Char),
+ ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))),
+ ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))),
+ ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))),
+ ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt(
+ tables.adt_def(adt_def.did()),
+ generic_args.stable(tables),
+ )),
+ 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(ty.stable(tables), constant.stable(tables)))
+ }
+ ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))),
+ ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => {
+ TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables)))
+ }
+ ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
+ region.stable(tables),
+ ty.stable(tables),
+ mutbl.stable(tables),
+ )),
+ ty::FnDef(def_id, generic_args) => {
+ TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables)))
+ }
+ ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))),
+ ty::Dynamic(existential_predicates, region, dyn_kind) => {
+ TyKind::RigidTy(RigidTy::Dynamic(
+ existential_predicates
+ .iter()
+ .map(|existential_predicate| existential_predicate.stable(tables))
+ .collect(),
+ region.stable(tables),
+ dyn_kind.stable(tables),
+ ))
+ }
+ ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure(
+ tables.closure_def(*def_id),
+ generic_args.stable(tables),
+ )),
+ ty::Coroutine(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Coroutine(
+ tables.coroutine_def(*def_id),
+ generic_args.stable(tables),
+ movability.stable(tables),
+ )),
+ ty::Never => TyKind::RigidTy(RigidTy::Never),
+ 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))
+ }
+ ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables)),
+ ty::Bound(debruijn_idx, bound_ty) => {
+ TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables))
+ }
+ ty::CoroutineWitness(def_id, args) => TyKind::RigidTy(RigidTy::CoroutineWitness(
+ tables.coroutine_witness_def(*def_id),
+ args.stable(tables),
+ )),
+ ty::Placeholder(..) | ty::Infer(_) | ty::Error(_) => {
+ unreachable!();
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
+ type T = stable_mir::ty::Const;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let kind = match self.kind() {
+ ty::Value(val) => {
+ let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
+ if matches!(const_val, mir::ConstValue::ZeroSized) {
+ ConstantKind::ZeroSized
+ } else {
+ 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)
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ParamConst {
+ type T = stable_mir::ty::ParamConst;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::ParamConst;
+ ParamConst { index: self.index, name: self.name.to_string() }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ParamTy {
+ type T = stable_mir::ty::ParamTy;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::ParamTy;
+ ParamTy { index: self.index, name: self.name.to_string() }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::BoundTy {
+ type T = stable_mir::ty::BoundTy;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::BoundTy;
+ BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
+ type T = stable_mir::ty::TraitSpecializationKind;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::TraitSpecializationKind;
+
+ match self {
+ ty::trait_def::TraitSpecializationKind::None => TraitSpecializationKind::None,
+ ty::trait_def::TraitSpecializationKind::Marker => TraitSpecializationKind::Marker,
+ ty::trait_def::TraitSpecializationKind::AlwaysApplicable => {
+ TraitSpecializationKind::AlwaysApplicable
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::TraitDef {
+ type T = stable_mir::ty::TraitDecl;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::opaque;
+ use stable_mir::ty::TraitDecl;
+
+ TraitDecl {
+ def_id: tables.trait_def(self.def_id),
+ unsafety: self.unsafety.stable(tables),
+ paren_sugar: self.paren_sugar,
+ has_auto_impl: self.has_auto_impl,
+ is_marker: self.is_marker,
+ is_coinductive: self.is_coinductive,
+ skip_array_during_method_dispatch: self.skip_array_during_method_dispatch,
+ specialization_kind: self.specialization_kind.stable(tables),
+ must_implement_one_of: self
+ .must_implement_one_of
+ .as_ref()
+ .map(|idents| idents.iter().map(|ident| opaque(ident)).collect()),
+ implement_via_object: self.implement_via_object,
+ deny_explicit_impl: self.deny_explicit_impl,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
+ type T = stable_mir::ty::TraitRef;
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::TraitRef;
+
+ TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap()
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::Generics {
+ type T = stable_mir::ty::Generics;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::Generics;
+
+ let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect();
+ let param_def_id_to_index =
+ params.iter().map(|param| (param.def_id, param.index)).collect();
+
+ Generics {
+ parent: self.parent.map(|did| tables.generic_def(did)),
+ parent_count: self.parent_count,
+ params,
+ param_def_id_to_index,
+ has_self: self.has_self,
+ has_late_bound_regions: self
+ .has_late_bound_regions
+ .as_ref()
+ .map(|late_bound_regions| late_bound_regions.stable(tables)),
+ host_effect_index: self.host_effect_index,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
+ type T = stable_mir::ty::GenericParamDefKind;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::GenericParamDefKind;
+ match self {
+ ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
+ ty::GenericParamDefKind::Type { has_default, synthetic } => {
+ GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
+ }
+ ty::GenericParamDefKind::Const { has_default, is_host_effect: _ } => {
+ GenericParamDefKind::Const { has_default: *has_default }
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
+ type T = stable_mir::ty::GenericParamDef;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ GenericParamDef {
+ name: self.name.to_string(),
+ def_id: tables.generic_def(self.def_id),
+ index: self.index,
+ pure_wrt_drop: self.pure_wrt_drop,
+ kind: self.kind.stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
+ type T = stable_mir::ty::PredicateKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::PredicateKind;
+ match self {
+ PredicateKind::Clause(clause_kind) => {
+ stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables))
+ }
+ PredicateKind::ObjectSafe(did) => {
+ stable_mir::ty::PredicateKind::ObjectSafe(tables.trait_def(*did))
+ }
+ PredicateKind::Subtype(subtype_predicate) => {
+ stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables))
+ }
+ PredicateKind::Coerce(coerce_predicate) => {
+ stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables))
+ }
+ PredicateKind::ConstEquate(a, b) => {
+ stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables))
+ }
+ PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous,
+ PredicateKind::NormalizesTo(_pred) => unimplemented!(),
+ PredicateKind::AliasRelate(a, b, alias_relation_direction) => {
+ stable_mir::ty::PredicateKind::AliasRelate(
+ a.unpack().stable(tables),
+ b.unpack().stable(tables),
+ alias_relation_direction.stable(tables),
+ )
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
+ type T = stable_mir::ty::ClauseKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::ClauseKind;
+ match *self {
+ ClauseKind::Trait(trait_object) => {
+ stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables))
+ }
+ ClauseKind::RegionOutlives(region_outlives) => {
+ stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables))
+ }
+ ClauseKind::TypeOutlives(type_outlives) => {
+ let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
+ stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
+ a.stable(tables),
+ b.stable(tables),
+ ))
+ }
+ ClauseKind::Projection(projection_predicate) => {
+ stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables))
+ }
+ ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
+ const_.stable(tables),
+ ty.stable(tables),
+ ),
+ ClauseKind::WellFormed(generic_arg) => {
+ stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables))
+ }
+ ClauseKind::ConstEvaluatable(const_) => {
+ stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
+ }
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ClosureKind {
+ type T = stable_mir::ty::ClosureKind;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::ClosureKind::*;
+ match self {
+ Fn => stable_mir::ty::ClosureKind::Fn,
+ FnMut => stable_mir::ty::ClosureKind::FnMut,
+ FnOnce => stable_mir::ty::ClosureKind::FnOnce,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
+ type T = stable_mir::ty::SubtypePredicate;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
+ stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
+ type T = stable_mir::ty::CoercePredicate;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::CoercePredicate { a, b } = self;
+ stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection {
+ type T = stable_mir::ty::AliasRelationDirection;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::AliasRelationDirection::*;
+ match self {
+ Equate => stable_mir::ty::AliasRelationDirection::Equate,
+ Subtype => stable_mir::ty::AliasRelationDirection::Subtype,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> {
+ type T = stable_mir::ty::TraitPredicate;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::TraitPredicate { trait_ref, polarity } = self;
+ stable_mir::ty::TraitPredicate {
+ trait_ref: trait_ref.stable(tables),
+ polarity: polarity.stable(tables),
+ }
+ }
+}
+
+impl<'tcx, A, B, U, V> Stable<'tcx> for ty::OutlivesPredicate<A, B>
+where
+ A: Stable<'tcx, T = U>,
+ B: Stable<'tcx, T = V>,
+{
+ type T = stable_mir::ty::OutlivesPredicate<U, V>;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::OutlivesPredicate(a, b) = self;
+ stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables))
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
+ type T = stable_mir::ty::ProjectionPredicate;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::ProjectionPredicate { projection_ty, term } = self;
+ stable_mir::ty::ProjectionPredicate {
+ projection_ty: projection_ty.stable(tables),
+ term: term.unpack().stable(tables),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
+ type T = stable_mir::ty::ImplPolarity;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ use rustc_middle::ty::ImplPolarity::*;
+ match self {
+ Positive => stable_mir::ty::ImplPolarity::Positive,
+ Negative => stable_mir::ty::ImplPolarity::Negative,
+ Reservation => stable_mir::ty::ImplPolarity::Reservation,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
+ type T = stable_mir::ty::Region;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ Region { kind: self.kind().stable(tables) }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
+ type T = stable_mir::ty::RegionKind;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind};
+ match self {
+ ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion {
+ def_id: tables.region_def(early_reg.def_id),
+ index: early_reg.index,
+ name: early_reg.name.to_string(),
+ }),
+ ty::ReBound(db_index, bound_reg) => RegionKind::ReBound(
+ db_index.as_u32(),
+ BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
+ ),
+ ty::ReStatic => RegionKind::ReStatic,
+ ty::RePlaceholder(place_holder) => {
+ RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
+ universe: place_holder.universe.as_u32(),
+ bound: BoundRegion {
+ var: place_holder.bound.var.as_u32(),
+ kind: place_holder.bound.kind.stable(tables),
+ },
+ })
+ }
+ ty::ReErased => RegionKind::ReErased,
+ _ => unreachable!("{self:?}"),
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
+ type T = stable_mir::mir::mono::Instance;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let def = tables.instance_def(*self);
+ let kind = match self.def {
+ ty::InstanceDef::Item(..) => stable_mir::mir::mono::InstanceKind::Item,
+ ty::InstanceDef::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic,
+ ty::InstanceDef::Virtual(_def_id, idx) => {
+ stable_mir::mir::mono::InstanceKind::Virtual { idx }
+ }
+ ty::InstanceDef::VTableShim(..)
+ | ty::InstanceDef::ReifyShim(..)
+ | ty::InstanceDef::FnPtrAddrShim(..)
+ | ty::InstanceDef::ClosureOnceShim { .. }
+ | ty::InstanceDef::ThreadLocalShim(..)
+ | ty::InstanceDef::DropGlue(..)
+ | ty::InstanceDef::CloneShim(..)
+ | ty::InstanceDef::FnPtrShim(..) => stable_mir::mir::mono::InstanceKind::Shim,
+ };
+ stable_mir::mir::mono::Instance { def, kind }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::Variance {
+ type T = stable_mir::mir::Variance;
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ty::Variance::Bivariant => stable_mir::mir::Variance::Bivariant,
+ ty::Variance::Contravariant => stable_mir::mir::Variance::Contravariant,
+ ty::Variance::Covariant => stable_mir::mir::Variance::Covariant,
+ ty::Variance::Invariant => stable_mir::mir::Variance::Invariant,
+ }
+ }
+}
+
+impl<'tcx> Stable<'tcx> for ty::Movability {
+ type T = stable_mir::ty::Movability;
+
+ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ match self {
+ ty::Movability::Static => stable_mir::ty::Movability::Static,
+ ty::Movability::Movable => stable_mir::ty::Movability::Movable,
+ }
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 27596c08f..e1ee40c0b 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,280 +7,100 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
-use crate::rustc_internal::{IndexMap, RustcInternal};
-use crate::rustc_smir::hir::def::DefKind;
-use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
-use rustc_hir as hir;
+use rustc_hir::def::DefKind;
use rustc_middle::mir;
-use rustc_middle::mir::interpret::{alloc_range, AllocId};
-use rustc_middle::mir::mono::MonoItem;
-use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt, Variance};
+use rustc_middle::mir::interpret::AllocId;
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc_target::abi::FieldIdx;
+use stable_mir::abi::Layout;
use stable_mir::mir::mono::InstanceDef;
-use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
-use stable_mir::ty::{
- Const, ConstId, ConstantKind, FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy,
- Span, TyKind, UintTy,
-};
-use stable_mir::{self, opaque, Context, Filename};
-use std::cell::RefCell;
+use stable_mir::ty::{ConstId, Span};
+use stable_mir::{CtorKind, ItemKind};
+use std::ops::RangeInclusive;
use tracing::debug;
+use crate::rustc_internal::IndexMap;
+
mod alloc;
mod builder;
-
-impl<'tcx> Context for TablesWrapper<'tcx> {
- fn local_crate(&self) -> stable_mir::Crate {
- let tables = self.0.borrow();
- smir_crate(tables.tcx, LOCAL_CRATE)
- }
-
- fn external_crates(&self) -> Vec<stable_mir::Crate> {
- let tables = self.0.borrow();
- tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
- }
-
- fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
- let tables = self.0.borrow();
- let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
- .iter()
- .chain(tables.tcx.crates(()).iter())
- .map(|crate_num| {
- let crate_name = tables.tcx.crate_name(*crate_num).to_string();
- (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
- })
- .into_iter()
- .filter_map(|c| c)
- .collect();
- crates
- }
-
- fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
- let tables = self.0.borrow();
- tables.tcx.def_path_str(tables[def_id])
- }
-
- fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
- let tables = self.0.borrow();
- tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
- }
-
- fn get_filename(&self, span: &Span) -> Filename {
- let tables = self.0.borrow();
- opaque(
- &tables
- .tcx
- .sess
- .source_map()
- .span_to_filename(tables[*span])
- .display(rustc_span::FileNameDisplayPreference::Local)
- .to_string(),
- )
- }
-
- fn get_lines(&self, span: &Span) -> LineInfo {
- let tables = self.0.borrow();
- let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]);
- LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
- }
-
- fn def_kind(&self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
- let mut tables = self.0.borrow_mut();
- tables.tcx.def_kind(tables[def_id]).stable(&mut *tables)
- }
-
- fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
- let mut tables = self.0.borrow_mut();
- tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
- }
-
- fn all_local_items(&self) -> stable_mir::CrateItems {
- let mut tables = self.0.borrow_mut();
- tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect()
- }
-
- fn entry_fn(&self) -> Option<stable_mir::CrateItem> {
- let mut tables = self.0.borrow_mut();
- let tcx = tables.tcx;
- Some(tables.crate_item(tcx.entry_fn(())?.0))
- }
-
- fn all_trait_decls(&self) -> stable_mir::TraitDecls {
- let mut tables = self.0.borrow_mut();
- tables
- .tcx
- .traits(LOCAL_CRATE)
- .iter()
- .map(|trait_def_id| tables.trait_def(*trait_def_id))
- .collect()
- }
-
- fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
- let mut tables = self.0.borrow_mut();
- let def_id = tables[trait_def.0];
- let trait_def = tables.tcx.trait_def(def_id);
- trait_def.stable(&mut *tables)
- }
-
- fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls {
- let mut tables = self.0.borrow_mut();
- tables
- .tcx
- .trait_impls_in_crate(LOCAL_CRATE)
- .iter()
- .map(|impl_def_id| tables.impl_def(*impl_def_id))
- .collect()
- }
-
- fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
- let mut tables = self.0.borrow_mut();
- let def_id = tables[impl_def.0];
- let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap();
- impl_trait.stable(&mut *tables)
- }
-
- fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body {
- let mut tables = self.0.borrow_mut();
- let def_id = tables[item];
- tables.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(&mut tables)
- }
-
- fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
- let mut tables = self.0.borrow_mut();
- tables.types[ty].kind().stable(&mut *tables)
- }
-
- fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
- let mut tables = self.0.borrow_mut();
- let def_id = tables[def_id];
- let generics = tables.tcx.generics_of(def_id);
- generics.stable(&mut *tables)
- }
-
- fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
- let mut tables = self.0.borrow_mut();
- let def_id = tables[def_id];
- let ty::GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id);
- stable_mir::ty::GenericPredicates {
- parent: parent.map(|did| tables.trait_def(did)),
- predicates: predicates
- .iter()
- .map(|(clause, span)| {
- (
- clause.as_predicate().kind().skip_binder().stable(&mut *tables),
- span.stable(&mut *tables),
- )
- })
- .collect(),
- }
- }
-
- fn explicit_predicates_of(
- &self,
- def_id: stable_mir::DefId,
- ) -> stable_mir::ty::GenericPredicates {
- let mut tables = self.0.borrow_mut();
- let def_id = tables[def_id];
- let ty::GenericPredicates { parent, predicates } =
- tables.tcx.explicit_predicates_of(def_id);
- stable_mir::ty::GenericPredicates {
- parent: parent.map(|did| tables.trait_def(did)),
- predicates: predicates
- .iter()
- .map(|(clause, span)| {
- (
- clause.as_predicate().kind().skip_binder().stable(&mut *tables),
- span.stable(&mut *tables),
- )
- })
- .collect(),
- }
- }
-
- fn instance_body(&self, def: InstanceDef) -> Body {
- let mut tables = self.0.borrow_mut();
- let instance = tables.instances[def];
- builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)
- }
-
- fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
- let mut tables = self.0.borrow_mut();
- let instance = tables.instances[def];
- instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables)
- }
-
- fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
- let mut tables = self.0.borrow_mut();
- let def_id = tables.instances[def].def_id();
- tables.create_def_id(def_id)
- }
-
- fn instance_mangled_name(&self, def: InstanceDef) -> String {
- let tables = self.0.borrow_mut();
- let instance = tables.instances[def];
- tables.tcx.symbol_name(instance).name.to_string()
- }
-
- fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
- let mut tables = self.0.borrow_mut();
- let def_id = tables[item.0];
- Instance::mono(tables.tcx, def_id).stable(&mut *tables)
- }
-
- fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
- let tables = self.0.borrow();
- let def_id = tables[def_id];
- let generics = tables.tcx.generics_of(def_id);
- let result = generics.requires_monomorphization(tables.tcx);
- result
- }
-
- fn resolve_instance(
- &self,
- def: stable_mir::ty::FnDef,
- args: &stable_mir::ty::GenericArgs,
- ) -> Option<stable_mir::mir::mono::Instance> {
- let mut tables = self.0.borrow_mut();
- let def_id = def.0.internal(&mut *tables);
- let args_ref = args.internal(&mut *tables);
- match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
- Ok(Some(instance)) => Some(instance.stable(&mut *tables)),
- Ok(None) | Err(_) => None,
- }
- }
-}
-
-pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
+pub(crate) mod context;
+mod convert;
pub struct Tables<'tcx> {
pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
- pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
+ pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::mir::alloc::AllocId>,
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
pub(crate) types: IndexMap<Ty<'tcx>, stable_mir::ty::Ty>,
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
pub(crate) constants: IndexMap<mir::Const<'tcx>, ConstId>,
+ pub(crate) layouts: IndexMap<rustc_target::abi::Layout<'tcx>, Layout>,
}
impl<'tcx> Tables<'tcx> {
- fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
+ pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
self.types.create_or_fetch(ty)
}
- fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
+ pub(crate) fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
self.constants.create_or_fetch(constant)
}
+
+ pub(crate) fn has_body(&self, instance: Instance<'tcx>) -> bool {
+ let def_id = instance.def_id();
+ self.tcx.is_mir_available(def_id)
+ || !matches!(
+ instance.def,
+ ty::InstanceDef::Virtual(..)
+ | ty::InstanceDef::Intrinsic(..)
+ | ty::InstanceDef::Item(..)
+ )
+ }
}
/// Build a stable mir crate from a given crate number.
-fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
+pub(crate) fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
let crate_name = tcx.crate_name(crate_num).to_string();
let is_local = crate_num == LOCAL_CRATE;
debug!(?crate_name, ?crate_num, "smir_crate");
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
}
+pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind {
+ match kind {
+ DefKind::Mod
+ | DefKind::Struct
+ | DefKind::Union
+ | DefKind::Enum
+ | DefKind::Variant
+ | DefKind::Trait
+ | DefKind::TyAlias
+ | DefKind::ForeignTy
+ | DefKind::TraitAlias
+ | DefKind::AssocTy
+ | DefKind::TyParam
+ | DefKind::ConstParam
+ | DefKind::Macro(_)
+ | DefKind::ExternCrate
+ | DefKind::Use
+ | DefKind::ForeignMod
+ | DefKind::OpaqueTy
+ | DefKind::Field
+ | DefKind::LifetimeParam
+ | DefKind::Impl { .. }
+ | DefKind::GlobalAsm => {
+ unreachable!("Not a valid item kind: {kind:?}");
+ }
+ DefKind::Closure | DefKind::AssocFn | DefKind::Fn => ItemKind::Fn,
+ DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
+ ItemKind::Const
+ }
+ DefKind::Static(_) => ItemKind::Static,
+ DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const),
+ DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn),
+ }
+}
+
/// Trait used to convert between an internal MIR type to a Stable MIR type.
pub trait Stable<'tcx> {
/// The stable representation of the type implementing Stable.
@@ -289,1481 +109,70 @@ pub trait Stable<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T;
}
-impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
- type T = stable_mir::mir::Body;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- stable_mir::mir::Body::new(
- self.basic_blocks
- .iter()
- .map(|block| stable_mir::mir::BasicBlock {
- terminator: block.terminator().stable(tables),
- statements: block
- .statements
- .iter()
- .map(|statement| statement.stable(tables))
- .collect(),
- })
- .collect(),
- self.local_decls
- .iter()
- .map(|decl| stable_mir::mir::LocalDecl {
- ty: decl.ty.stable(tables),
- span: decl.source_info.span.stable(tables),
- })
- .collect(),
- self.arg_count,
- )
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
- type T = stable_mir::mir::Statement;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
- type T = stable_mir::mir::StatementKind;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- match self {
- mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign(
- assign.0.stable(tables),
- assign.1.stable(tables),
- ),
- mir::StatementKind::FakeRead(fake_read_place) => {
- stable_mir::mir::StatementKind::FakeRead(
- fake_read_place.0.stable(tables),
- fake_read_place.1.stable(tables),
- )
- }
- mir::StatementKind::SetDiscriminant { place, variant_index } => {
- stable_mir::mir::StatementKind::SetDiscriminant {
- place: place.as_ref().stable(tables),
- variant_index: variant_index.stable(tables),
- }
- }
- mir::StatementKind::Deinit(place) => {
- stable_mir::mir::StatementKind::Deinit(place.stable(tables))
- }
-
- mir::StatementKind::StorageLive(place) => {
- stable_mir::mir::StatementKind::StorageLive(place.stable(tables))
- }
-
- mir::StatementKind::StorageDead(place) => {
- stable_mir::mir::StatementKind::StorageDead(place.stable(tables))
- }
- mir::StatementKind::Retag(retag, place) => {
- stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables))
- }
- mir::StatementKind::PlaceMention(place) => {
- stable_mir::mir::StatementKind::PlaceMention(place.stable(tables))
- }
- mir::StatementKind::AscribeUserType(place_projection, variance) => {
- stable_mir::mir::StatementKind::AscribeUserType {
- place: place_projection.as_ref().0.stable(tables),
- projections: place_projection.as_ref().1.stable(tables),
- variance: variance.stable(tables),
- }
- }
- mir::StatementKind::Coverage(coverage) => {
- stable_mir::mir::StatementKind::Coverage(opaque(coverage))
- }
- mir::StatementKind::Intrinsic(intrinstic) => {
- stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables))
- }
- mir::StatementKind::ConstEvalCounter => {
- stable_mir::mir::StatementKind::ConstEvalCounter
- }
- mir::StatementKind::Nop => stable_mir::mir::StatementKind::Nop,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
- type T = stable_mir::mir::Rvalue;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use mir::Rvalue::*;
- match self {
- Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
- Repeat(op, len) => {
- let len = len.stable(tables);
- stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
- }
- Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
- region.stable(tables),
- kind.stable(tables),
- place.stable(tables),
- ),
- ThreadLocalRef(def_id) => {
- stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
- }
- AddressOf(mutability, place) => {
- stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
- }
- Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
- Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
- cast_kind.stable(tables),
- op.stable(tables),
- ty.stable(tables),
- ),
- BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
- bin_op.stable(tables),
- ops.0.stable(tables),
- ops.1.stable(tables),
- ),
- CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp(
- bin_op.stable(tables),
- ops.0.stable(tables),
- ops.1.stable(tables),
- ),
- NullaryOp(null_op, 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))
- }
- Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)),
- Aggregate(agg_kind, operands) => {
- let operands = operands.iter().map(|op| op.stable(tables)).collect();
- stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
- }
- ShallowInitBox(op, ty) => {
- stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
- }
- CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::Mutability {
- type T = stable_mir::mir::Mutability;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use mir::Mutability::*;
- match *self {
- Not => stable_mir::mir::Mutability::Not,
- Mut => stable_mir::mir::Mutability::Mut,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::BorrowKind {
- type T = stable_mir::mir::BorrowKind;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use mir::BorrowKind::*;
- match *self {
- Shared => stable_mir::mir::BorrowKind::Shared,
- Fake => stable_mir::mir::BorrowKind::Fake,
- Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) },
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
- type T = stable_mir::mir::MutBorrowKind;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use mir::MutBorrowKind::*;
- match *self {
- Default => stable_mir::mir::MutBorrowKind::Default,
- TwoPhaseBorrow => stable_mir::mir::MutBorrowKind::TwoPhaseBorrow,
- ClosureCapture => stable_mir::mir::MutBorrowKind::ClosureCapture,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
- type T = stable_mir::mir::NullOp;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use mir::NullOp::*;
- match self {
- SizeOf => stable_mir::mir::NullOp::SizeOf,
- AlignOf => stable_mir::mir::NullOp::AlignOf,
- OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf(
- indices.iter().map(|idx| idx.stable(tables)).collect(),
- ),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::CastKind {
- type T = stable_mir::mir::CastKind;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use mir::CastKind::*;
- match self {
- PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress,
- PointerFromExposedAddress => stable_mir::mir::CastKind::PointerFromExposedAddress,
- PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
- DynStar => stable_mir::mir::CastKind::DynStar,
- IntToInt => stable_mir::mir::CastKind::IntToInt,
- FloatToInt => stable_mir::mir::CastKind::FloatToInt,
- FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
- IntToFloat => stable_mir::mir::CastKind::IntToFloat,
- PtrToPtr => stable_mir::mir::CastKind::PtrToPtr,
- FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr,
- Transmute => stable_mir::mir::CastKind::Transmute,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::AliasKind {
- type T = stable_mir::ty::AliasKind;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use ty::AliasKind::*;
- match self {
- Projection => stable_mir::ty::AliasKind::Projection,
- Inherent => stable_mir::ty::AliasKind::Inherent,
- Opaque => stable_mir::ty::AliasKind::Opaque,
- Weak => stable_mir::ty::AliasKind::Weak,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> {
- type T = stable_mir::ty::AliasTy;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::AliasTy { args, def_id, .. } = self;
- stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::DynKind {
- type T = stable_mir::ty::DynKind;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use ty::DynKind;
- match self {
- DynKind::Dyn => stable_mir::ty::DynKind::Dyn,
- DynKind::DynStar => stable_mir::ty::DynKind::DynStar,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> {
- type T = stable_mir::ty::ExistentialPredicate;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::ExistentialPredicate::*;
- match self {
- ty::ExistentialPredicate::Trait(existential_trait_ref) => {
- Trait(existential_trait_ref.stable(tables))
- }
- ty::ExistentialPredicate::Projection(existential_projection) => {
- Projection(existential_projection.stable(tables))
- }
- ty::ExistentialPredicate::AutoTrait(def_id) => AutoTrait(tables.trait_def(*def_id)),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
- type T = stable_mir::ty::ExistentialTraitRef;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::ExistentialTraitRef { def_id, args } = self;
- stable_mir::ty::ExistentialTraitRef {
- def_id: tables.trait_def(*def_id),
- generic_args: args.stable(tables),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
- type T = stable_mir::ty::TermKind;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::TermKind;
- match self {
- ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)),
- ty::TermKind::Const(cnst) => {
- let cnst = cnst.stable(tables);
- TermKind::Const(cnst)
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> {
- type T = stable_mir::ty::ExistentialProjection;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::ExistentialProjection { def_id, args, term } = self;
- stable_mir::ty::ExistentialProjection {
- def_id: tables.trait_def(*def_id),
- generic_args: args.stable(tables),
- term: term.unpack().stable(tables),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
- type T = stable_mir::mir::PointerCoercion;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use ty::adjustment::PointerCoercion;
- match self {
- PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer,
- PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer,
- PointerCoercion::ClosureFnPointer(unsafety) => {
- stable_mir::mir::PointerCoercion::ClosureFnPointer(unsafety.stable(tables))
- }
- PointerCoercion::MutToConstPointer => {
- stable_mir::mir::PointerCoercion::MutToConstPointer
- }
- PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
- PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for rustc_hir::Unsafety {
- type T = stable_mir::mir::Safety;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- match self {
- rustc_hir::Unsafety::Unsafe => stable_mir::mir::Safety::Unsafe,
- rustc_hir::Unsafety::Normal => stable_mir::mir::Safety::Normal,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
- type T = stable_mir::mir::FakeReadCause;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use mir::FakeReadCause::*;
- match self {
- ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard,
- ForMatchedPlace(local_def_id) => {
- stable_mir::mir::FakeReadCause::ForMatchedPlace(opaque(local_def_id))
- }
- ForGuardBinding => stable_mir::mir::FakeReadCause::ForGuardBinding,
- ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet(opaque(local_def_id)),
- ForIndex => stable_mir::mir::FakeReadCause::ForIndex,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for FieldIdx {
- type T = usize;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- self.as_usize()
- }
-}
-
-impl<'tcx> Stable<'tcx> for (rustc_target::abi::VariantIdx, FieldIdx) {
- type T = (usize, usize);
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- (self.0.as_usize(), self.1.as_usize())
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
- type T = stable_mir::mir::Operand;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use mir::Operand::*;
- match self {
- Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)),
- Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)),
- Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
- type T = stable_mir::mir::Constant;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- stable_mir::mir::Constant {
- span: self.span.stable(tables),
- user_ty: self.user_ty.map(|u| u.as_usize()).or(None),
- literal: self.const_.stable(tables),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
- type T = stable_mir::mir::Place;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- stable_mir::mir::Place {
- local: self.local.as_usize(),
- projection: format!("{:?}", self.projection),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
- type T = stable_mir::mir::UserTypeProjection;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- UserTypeProjection { base: self.base.as_usize(), projection: format!("{:?}", self.projs) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::Local {
- type T = stable_mir::mir::Local;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- self.as_usize()
- }
-}
-
-impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx {
- type T = VariantIdx;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- self.as_usize()
- }
-}
-
-impl<'tcx> Stable<'tcx> for Variance {
- type T = stable_mir::mir::Variance;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- match self {
- Variance::Bivariant => stable_mir::mir::Variance::Bivariant,
- Variance::Contravariant => stable_mir::mir::Variance::Contravariant,
- Variance::Covariant => stable_mir::mir::Variance::Covariant,
- Variance::Invariant => stable_mir::mir::Variance::Invariant,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::RetagKind {
- type T = stable_mir::mir::RetagKind;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use rustc_middle::mir::RetagKind;
- match self {
- RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry,
- RetagKind::TwoPhase => stable_mir::mir::RetagKind::TwoPhase,
- RetagKind::Raw => stable_mir::mir::RetagKind::Raw,
- RetagKind::Default => stable_mir::mir::RetagKind::Default,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
- type T = usize;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- self.as_usize()
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::UnwindAction {
- type T = stable_mir::mir::UnwindAction;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use rustc_middle::mir::UnwindAction;
- match self {
- UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue,
- UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable,
- UnwindAction::Terminate(_) => stable_mir::mir::UnwindAction::Terminate,
- UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
- type T = stable_mir::mir::NonDivergingIntrinsic;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use rustc_middle::mir::NonDivergingIntrinsic;
- match self {
- NonDivergingIntrinsic::Assume(op) => {
- stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables))
- }
- NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => {
- stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
- src: copy_non_overlapping.src.stable(tables),
- dst: copy_non_overlapping.dst.stable(tables),
- count: copy_non_overlapping.count.stable(tables),
- })
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
- type T = stable_mir::mir::AssertMessage;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use rustc_middle::mir::AssertKind;
- match self {
- AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck {
- len: len.stable(tables),
- index: index.stable(tables),
- },
- AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow(
- bin_op.stable(tables),
- op1.stable(tables),
- op2.stable(tables),
- ),
- AssertKind::OverflowNeg(op) => {
- stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables))
- }
- AssertKind::DivisionByZero(op) => {
- stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables))
- }
- AssertKind::RemainderByZero(op) => {
- stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables))
- }
- AssertKind::ResumedAfterReturn(coroutine) => {
- stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables))
- }
- AssertKind::ResumedAfterPanic(coroutine) => {
- stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables))
- }
- AssertKind::MisalignedPointerDereference { required, found } => {
- stable_mir::mir::AssertMessage::MisalignedPointerDereference {
- required: required.stable(tables),
- found: found.stable(tables),
- }
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::BinOp {
- type T = stable_mir::mir::BinOp;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use mir::BinOp;
- match self {
- BinOp::Add => stable_mir::mir::BinOp::Add,
- BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked,
- BinOp::Sub => stable_mir::mir::BinOp::Sub,
- BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked,
- BinOp::Mul => stable_mir::mir::BinOp::Mul,
- BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked,
- BinOp::Div => stable_mir::mir::BinOp::Div,
- BinOp::Rem => stable_mir::mir::BinOp::Rem,
- BinOp::BitXor => stable_mir::mir::BinOp::BitXor,
- BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd,
- BinOp::BitOr => stable_mir::mir::BinOp::BitOr,
- BinOp::Shl => stable_mir::mir::BinOp::Shl,
- BinOp::ShlUnchecked => stable_mir::mir::BinOp::ShlUnchecked,
- BinOp::Shr => stable_mir::mir::BinOp::Shr,
- BinOp::ShrUnchecked => stable_mir::mir::BinOp::ShrUnchecked,
- BinOp::Eq => stable_mir::mir::BinOp::Eq,
- BinOp::Lt => stable_mir::mir::BinOp::Lt,
- BinOp::Le => stable_mir::mir::BinOp::Le,
- BinOp::Ne => stable_mir::mir::BinOp::Ne,
- BinOp::Ge => stable_mir::mir::BinOp::Ge,
- BinOp::Gt => stable_mir::mir::BinOp::Gt,
- BinOp::Offset => stable_mir::mir::BinOp::Offset,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::UnOp {
- type T = stable_mir::mir::UnOp;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use mir::UnOp;
- match self {
- UnOp::Not => stable_mir::mir::UnOp::Not,
- UnOp::Neg => stable_mir::mir::UnOp::Neg,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
- type T = stable_mir::mir::AggregateKind;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- match self {
- mir::AggregateKind::Array(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) => {
- stable_mir::mir::AggregateKind::Adt(
- tables.adt_def(*def_id),
- var_idx.index(),
- generic_arg.stable(tables),
- user_ty_index.map(|idx| idx.index()),
- field_idx.map(|idx| idx.index()),
- )
- }
- mir::AggregateKind::Closure(def_id, generic_arg) => {
- stable_mir::mir::AggregateKind::Closure(
- tables.closure_def(*def_id),
- generic_arg.stable(tables),
- )
- }
- mir::AggregateKind::Coroutine(def_id, generic_arg, movability) => {
- stable_mir::mir::AggregateKind::Coroutine(
- tables.coroutine_def(*def_id),
- generic_arg.stable(tables),
- movability.stable(tables),
- )
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
- type T = stable_mir::mir::CoroutineSource;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use rustc_hir::CoroutineSource;
- match self {
- CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block,
- CoroutineSource::Closure => stable_mir::mir::CoroutineSource::Closure,
- CoroutineSource::Fn => stable_mir::mir::CoroutineSource::Fn,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
- type T = stable_mir::mir::CoroutineKind;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use rustc_hir::CoroutineKind;
- match self {
- CoroutineKind::Async(source) => {
- stable_mir::mir::CoroutineKind::Async(source.stable(tables))
- }
- CoroutineKind::Gen(source) => {
- stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
- }
- CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
- type T = stable_mir::mir::InlineAsmOperand;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use rustc_middle::mir::InlineAsmOperand;
-
- let (in_value, out_place) = match self {
- InlineAsmOperand::In { value, .. } => (Some(value.stable(tables)), None),
- InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable(tables))),
- InlineAsmOperand::InOut { in_value, out_place, .. } => {
- (Some(in_value.stable(tables)), out_place.map(|place| place.stable(tables)))
- }
- InlineAsmOperand::Const { .. }
- | InlineAsmOperand::SymFn { .. }
- | InlineAsmOperand::SymStatic { .. } => (None, None),
- };
-
- stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{self:?}") }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
- type T = stable_mir::mir::Terminator;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::mir::Terminator;
- Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
- type T = stable_mir::mir::TerminatorKind;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::mir::TerminatorKind;
- match self {
- mir::TerminatorKind::Goto { target } => {
- TerminatorKind::Goto { target: target.as_usize() }
- }
- mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt {
- discr: discr.stable(tables),
- targets: targets
- .iter()
- .map(|(value, target)| stable_mir::mir::SwitchTarget {
- value,
- target: target.as_usize(),
- })
- .collect(),
- otherwise: targets.otherwise().as_usize(),
- },
- mir::TerminatorKind::UnwindResume => TerminatorKind::Resume,
- mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort,
- mir::TerminatorKind::Return => TerminatorKind::Return,
- mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable,
- mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => {
- TerminatorKind::Drop {
- place: place.stable(tables),
- target: target.as_usize(),
- unwind: unwind.stable(tables),
- }
- }
- mir::TerminatorKind::Call {
- func,
- args,
- destination,
- target,
- unwind,
- call_source: _,
- fn_span: _,
- } => TerminatorKind::Call {
- func: func.stable(tables),
- args: args.iter().map(|arg| arg.stable(tables)).collect(),
- destination: destination.stable(tables),
- target: target.map(|t| t.as_usize()),
- unwind: unwind.stable(tables),
- },
- mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => {
- TerminatorKind::Assert {
- cond: cond.stable(tables),
- expected: *expected,
- msg: msg.stable(tables),
- target: target.as_usize(),
- unwind: unwind.stable(tables),
- }
- }
- mir::TerminatorKind::InlineAsm {
- template,
- operands,
- options,
- line_spans,
- destination,
- unwind,
- } => TerminatorKind::InlineAsm {
- template: format!("{template:?}"),
- operands: operands.iter().map(|operand| operand.stable(tables)).collect(),
- options: format!("{options:?}"),
- line_spans: format!("{line_spans:?}"),
- destination: destination.map(|d| d.as_usize()),
- unwind: unwind.stable(tables),
- },
- mir::TerminatorKind::Yield { .. }
- | mir::TerminatorKind::CoroutineDrop
- | mir::TerminatorKind::FalseEdge { .. }
- | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
- type T = stable_mir::ty::GenericArgs;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::GenericArgs;
-
- GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect())
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
- type T = stable_mir::ty::GenericArgKind;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::GenericArgKind;
- match self {
- ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)),
- ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)),
- ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)),
- }
- }
-}
-
-impl<'tcx, S, V> Stable<'tcx> for ty::Binder<'tcx, S>
+impl<'tcx, T> Stable<'tcx> for &T
where
- S: Stable<'tcx, T = V>,
+ T: Stable<'tcx>,
{
- type T = stable_mir::ty::Binder<V>;
+ type T = T::T;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::Binder;
-
- Binder {
- value: self.as_ref().skip_binder().stable(tables),
- bound_vars: self
- .bound_vars()
- .iter()
- .map(|bound_var| bound_var.stable(tables))
- .collect(),
- }
+ (*self).stable(tables)
}
}
-impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder<S>
+impl<'tcx, T> Stable<'tcx> for Option<T>
where
- S: Stable<'tcx, T = V>,
+ T: Stable<'tcx>,
{
- type T = stable_mir::ty::EarlyBinder<V>;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::EarlyBinder;
-
- EarlyBinder { value: self.as_ref().skip_binder().stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
- type T = stable_mir::ty::FnSig;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use rustc_target::spec::abi;
- use stable_mir::ty::{Abi, FnSig};
-
- FnSig {
- 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 {
- abi::Abi::Rust => Abi::Rust,
- abi::Abi::C { unwind } => Abi::C { unwind },
- abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind },
- abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind },
- abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind },
- abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind },
- abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind },
- abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind },
- abi::Abi::Win64 { unwind } => Abi::Win64 { unwind },
- abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind },
- abi::Abi::PtxKernel => Abi::PtxKernel,
- abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt,
- abi::Abi::X86Interrupt => Abi::X86Interrupt,
- abi::Abi::AmdGpuKernel => Abi::AmdGpuKernel,
- abi::Abi::EfiApi => Abi::EfiApi,
- abi::Abi::AvrInterrupt => Abi::AvrInterrupt,
- abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt,
- abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
- abi::Abi::Wasm => Abi::Wasm,
- abi::Abi::System { unwind } => Abi::System { unwind },
- abi::Abi::RustIntrinsic => Abi::RustIntrinsic,
- abi::Abi::RustCall => Abi::RustCall,
- abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic,
- abi::Abi::Unadjusted => Abi::Unadjusted,
- abi::Abi::RustCold => Abi::RustCold,
- abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM,
- abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS,
- },
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
- type T = stable_mir::ty::BoundTyKind;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::BoundTyKind;
-
- match self {
- ty::BoundTyKind::Anon => BoundTyKind::Anon,
- ty::BoundTyKind::Param(def_id, symbol) => {
- BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string())
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
- type T = stable_mir::ty::BoundRegionKind;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::BoundRegionKind;
-
- match self {
- ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon,
- ty::BoundRegionKind::BrNamed(def_id, symbol) => {
- BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string())
- }
- ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::BoundVariableKind {
- type T = stable_mir::ty::BoundVariableKind;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::BoundVariableKind;
-
- match self {
- ty::BoundVariableKind::Ty(bound_ty_kind) => {
- BoundVariableKind::Ty(bound_ty_kind.stable(tables))
- }
- ty::BoundVariableKind::Region(bound_region_kind) => {
- BoundVariableKind::Region(bound_region_kind.stable(tables))
- }
- ty::BoundVariableKind::Const => BoundVariableKind::Const,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::IntTy {
- type T = IntTy;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- match self {
- ty::IntTy::Isize => IntTy::Isize,
- ty::IntTy::I8 => IntTy::I8,
- ty::IntTy::I16 => IntTy::I16,
- ty::IntTy::I32 => IntTy::I32,
- ty::IntTy::I64 => IntTy::I64,
- ty::IntTy::I128 => IntTy::I128,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::UintTy {
- type T = UintTy;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- match self {
- ty::UintTy::Usize => UintTy::Usize,
- ty::UintTy::U8 => UintTy::U8,
- ty::UintTy::U16 => UintTy::U16,
- ty::UintTy::U32 => UintTy::U32,
- ty::UintTy::U64 => UintTy::U64,
- ty::UintTy::U128 => UintTy::U128,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::FloatTy {
- type T = FloatTy;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- match self {
- ty::FloatTy::F32 => FloatTy::F32,
- ty::FloatTy::F64 => FloatTy::F64,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for hir::Movability {
- type T = Movability;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- match self {
- hir::Movability::Static => Movability::Static,
- hir::Movability::Movable => Movability::Movable,
- }
- }
-}
-
-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 {
- ty::Bool => TyKind::RigidTy(RigidTy::Bool),
- ty::Char => TyKind::RigidTy(RigidTy::Char),
- ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))),
- ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))),
- ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))),
- ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt(
- tables.adt_def(adt_def.did()),
- generic_args.stable(tables),
- )),
- 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(ty.stable(tables), constant.stable(tables)))
- }
- ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))),
- ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => {
- TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables)))
- }
- ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
- region.stable(tables),
- ty.stable(tables),
- mutbl.stable(tables),
- )),
- ty::FnDef(def_id, generic_args) => {
- TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables)))
- }
- ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))),
- ty::Dynamic(existential_predicates, region, dyn_kind) => {
- TyKind::RigidTy(RigidTy::Dynamic(
- existential_predicates
- .iter()
- .map(|existential_predicate| existential_predicate.stable(tables))
- .collect(),
- region.stable(tables),
- dyn_kind.stable(tables),
- ))
- }
- ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure(
- tables.closure_def(*def_id),
- generic_args.stable(tables),
- )),
- ty::Coroutine(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Coroutine(
- tables.coroutine_def(*def_id),
- generic_args.stable(tables),
- movability.stable(tables),
- )),
- ty::Never => TyKind::RigidTy(RigidTy::Never),
- 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))
- }
- ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables)),
- ty::Bound(debruijn_idx, bound_ty) => {
- TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables))
- }
- ty::Placeholder(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => {
- unreachable!();
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
- type T = stable_mir::ty::Const;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let kind = match self.kind() {
- ty::Value(val) => {
- let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
- if matches!(const_val, mir::ConstValue::ZeroSized) {
- ConstantKind::ZeroSized
- } else {
- 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)
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ParamConst {
- type T = stable_mir::ty::ParamConst;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::ParamConst;
- ParamConst { index: self.index, name: self.name.to_string() }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ParamTy {
- type T = stable_mir::ty::ParamTy;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::ParamTy;
- ParamTy { index: self.index, name: self.name.to_string() }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::BoundTy {
- type T = stable_mir::ty::BoundTy;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::BoundTy;
- BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
- type T = stable_mir::ty::Allocation;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- alloc::allocation_filter(
- self,
- alloc_range(rustc_target::abi::Size::ZERO, self.size()),
- tables,
- )
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
- type T = stable_mir::ty::TraitSpecializationKind;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::TraitSpecializationKind;
-
- match self {
- ty::trait_def::TraitSpecializationKind::None => TraitSpecializationKind::None,
- ty::trait_def::TraitSpecializationKind::Marker => TraitSpecializationKind::Marker,
- ty::trait_def::TraitSpecializationKind::AlwaysApplicable => {
- TraitSpecializationKind::AlwaysApplicable
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::TraitDef {
- type T = stable_mir::ty::TraitDecl;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::TraitDecl;
-
- TraitDecl {
- def_id: tables.trait_def(self.def_id),
- unsafety: self.unsafety.stable(tables),
- paren_sugar: self.paren_sugar,
- has_auto_impl: self.has_auto_impl,
- is_marker: self.is_marker,
- is_coinductive: self.is_coinductive,
- skip_array_during_method_dispatch: self.skip_array_during_method_dispatch,
- specialization_kind: self.specialization_kind.stable(tables),
- must_implement_one_of: self
- .must_implement_one_of
- .as_ref()
- .map(|idents| idents.iter().map(|ident| opaque(ident)).collect()),
- implement_via_object: self.implement_via_object,
- deny_explicit_impl: self.deny_explicit_impl,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
- type T = stable_mir::ty::Const;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- match *self {
- mir::Const::Ty(c) => c.stable(tables),
- 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()),
- });
- let ty = ty.stable(tables);
- let id = tables.intern_const(*self);
- Const::new(kind, ty, id)
- }
- mir::Const::Val(val, ty) if matches!(val, mir::ConstValue::ZeroSized) => {
- let ty = ty.stable(tables);
- let id = tables.intern_const(*self);
- Const::new(ConstantKind::ZeroSized, 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)
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
- type T = stable_mir::ty::TraitRef;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::TraitRef;
-
- TraitRef { def_id: tables.trait_def(self.def_id), args: self.args.stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::Generics {
- type T = stable_mir::ty::Generics;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::Generics;
-
- let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect();
- let param_def_id_to_index =
- params.iter().map(|param| (param.def_id, param.index)).collect();
-
- Generics {
- parent: self.parent.map(|did| tables.generic_def(did)),
- parent_count: self.parent_count,
- params,
- param_def_id_to_index,
- has_self: self.has_self,
- has_late_bound_regions: self
- .has_late_bound_regions
- .as_ref()
- .map(|late_bound_regions| late_bound_regions.stable(tables)),
- host_effect_index: self.host_effect_index,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
- type T = stable_mir::ty::GenericParamDefKind;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::GenericParamDefKind;
- match self {
- ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
- ty::GenericParamDefKind::Type { has_default, synthetic } => {
- GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
- }
- ty::GenericParamDefKind::Const { has_default, is_host_effect: _ } => {
- GenericParamDefKind::Const { has_default: *has_default }
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
- type T = stable_mir::ty::GenericParamDef;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- GenericParamDef {
- name: self.name.to_string(),
- def_id: tables.generic_def(self.def_id),
- index: self.index,
- pure_wrt_drop: self.pure_wrt_drop,
- kind: self.kind.stable(tables),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
- type T = stable_mir::ty::PredicateKind;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use ty::PredicateKind;
- match self {
- PredicateKind::Clause(clause_kind) => {
- stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables))
- }
- PredicateKind::ObjectSafe(did) => {
- stable_mir::ty::PredicateKind::ObjectSafe(tables.trait_def(*did))
- }
- PredicateKind::ClosureKind(did, generic_args, closure_kind) => {
- stable_mir::ty::PredicateKind::ClosureKind(
- tables.closure_def(*did),
- generic_args.stable(tables),
- closure_kind.stable(tables),
- )
- }
- PredicateKind::Subtype(subtype_predicate) => {
- stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables))
- }
- PredicateKind::Coerce(coerce_predicate) => {
- stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables))
- }
- PredicateKind::ConstEquate(a, b) => {
- stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables))
- }
- PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous,
- PredicateKind::AliasRelate(a, b, alias_relation_direction) => {
- stable_mir::ty::PredicateKind::AliasRelate(
- a.unpack().stable(tables),
- b.unpack().stable(tables),
- alias_relation_direction.stable(tables),
- )
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
- type T = stable_mir::ty::ClauseKind;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use ty::ClauseKind;
- match *self {
- ClauseKind::Trait(trait_object) => {
- stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables))
- }
- ClauseKind::RegionOutlives(region_outlives) => {
- stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables))
- }
- ClauseKind::TypeOutlives(type_outlives) => {
- let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
- stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
- a.stable(tables),
- b.stable(tables),
- ))
- }
- ClauseKind::Projection(projection_predicate) => {
- stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables))
- }
- ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
- const_.stable(tables),
- ty.stable(tables),
- ),
- ClauseKind::WellFormed(generic_arg) => {
- stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables))
- }
- ClauseKind::ConstEvaluatable(const_) => {
- stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
- }
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ClosureKind {
- type T = stable_mir::ty::ClosureKind;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use ty::ClosureKind::*;
- match self {
- Fn => stable_mir::ty::ClosureKind::Fn,
- FnMut => stable_mir::ty::ClosureKind::FnMut,
- FnOnce => stable_mir::ty::ClosureKind::FnOnce,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
- type T = stable_mir::ty::SubtypePredicate;
+ type T = Option<T::T>;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
- stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) }
+ self.as_ref().map(|value| value.stable(tables))
}
}
-impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
- type T = stable_mir::ty::CoercePredicate;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::CoercePredicate { a, b } = self;
- stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection {
- type T = stable_mir::ty::AliasRelationDirection;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use ty::AliasRelationDirection::*;
- match self {
- Equate => stable_mir::ty::AliasRelationDirection::Equate,
- Subtype => stable_mir::ty::AliasRelationDirection::Subtype,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> {
- type T = stable_mir::ty::TraitPredicate;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::TraitPredicate { trait_ref, polarity } = self;
- stable_mir::ty::TraitPredicate {
- trait_ref: trait_ref.stable(tables),
- polarity: polarity.stable(tables),
- }
- }
-}
-
-impl<'tcx, A, B, U, V> Stable<'tcx> for ty::OutlivesPredicate<A, B>
+impl<'tcx, T, E> Stable<'tcx> for Result<T, E>
where
- A: Stable<'tcx, T = U>,
- B: Stable<'tcx, T = V>,
+ T: Stable<'tcx>,
+ E: Stable<'tcx>,
{
- type T = stable_mir::ty::OutlivesPredicate<U, V>;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::OutlivesPredicate(a, b) = self;
- stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables))
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
- type T = stable_mir::ty::ProjectionPredicate;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let ty::ProjectionPredicate { projection_ty, term } = self;
- stable_mir::ty::ProjectionPredicate {
- projection_ty: projection_ty.stable(tables),
- term: term.unpack().stable(tables),
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
- type T = stable_mir::ty::ImplPolarity;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use ty::ImplPolarity::*;
- match self {
- Positive => stable_mir::ty::ImplPolarity::Positive,
- Negative => stable_mir::ty::ImplPolarity::Negative,
- Reservation => stable_mir::ty::ImplPolarity::Reservation,
- }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
- type T = stable_mir::ty::Region;
-
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- Region { kind: self.kind().stable(tables) }
- }
-}
-
-impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
- type T = stable_mir::ty::RegionKind;
+ type T = Result<T::T, E::T>;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::ty::RegionKind;
match self {
- ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion {
- def_id: tables.region_def(early_reg.def_id),
- index: early_reg.index,
- name: early_reg.name.to_string(),
- }),
- ty::ReLateBound(db_index, bound_reg) => RegionKind::ReLateBound(
- db_index.as_u32(),
- BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
- ),
- ty::ReStatic => RegionKind::ReStatic,
- ty::RePlaceholder(place_holder) => {
- RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
- universe: place_holder.universe.as_u32(),
- bound: BoundRegion {
- var: place_holder.bound.var.as_u32(),
- kind: place_holder.bound.kind.stable(tables),
- },
- })
- }
- ty::ReErased => RegionKind::ReErased,
- _ => unreachable!("{self:?}"),
+ Ok(val) => Ok(val.stable(tables)),
+ Err(error) => Err(error.stable(tables)),
}
}
}
-impl<'tcx> Stable<'tcx> for rustc_span::Span {
- type T = stable_mir::ty::Span;
-
+impl<'tcx, T> Stable<'tcx> for &[T]
+where
+ T: Stable<'tcx>,
+{
+ type T = Vec<T::T>;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- tables.create_span(*self)
- }
-}
-
-impl<'tcx> Stable<'tcx> for DefKind {
- type T = stable_mir::DefKind;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- // FIXME: add a real implementation of stable DefKind
- opaque(self)
+ self.iter().map(|e| e.stable(tables)).collect()
}
}
-impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
- type T = stable_mir::mir::mono::Instance;
-
+impl<'tcx, T, U> Stable<'tcx> for (T, U)
+where
+ T: Stable<'tcx>,
+ U: Stable<'tcx>,
+{
+ type T = (T::T, U::T);
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- let def = tables.instance_def(*self);
- let kind = match self.def {
- ty::InstanceDef::Item(..) => stable_mir::mir::mono::InstanceKind::Item,
- ty::InstanceDef::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic,
- ty::InstanceDef::Virtual(..) => stable_mir::mir::mono::InstanceKind::Virtual,
- ty::InstanceDef::VTableShim(..)
- | ty::InstanceDef::ReifyShim(..)
- | ty::InstanceDef::FnPtrAddrShim(..)
- | ty::InstanceDef::ClosureOnceShim { .. }
- | ty::InstanceDef::ThreadLocalShim(..)
- | ty::InstanceDef::DropGlue(..)
- | ty::InstanceDef::CloneShim(..)
- | ty::InstanceDef::FnPtrShim(..) => stable_mir::mir::mono::InstanceKind::Shim,
- };
- stable_mir::mir::mono::Instance { def, kind }
+ (self.0.stable(tables), self.1.stable(tables))
}
}
-impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
- type T = stable_mir::mir::mono::MonoItem;
-
+impl<'tcx, T> Stable<'tcx> for RangeInclusive<T>
+where
+ T: Stable<'tcx>,
+{
+ type T = RangeInclusive<T::T>;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use stable_mir::mir::mono::MonoItem as StableMonoItem;
- match self {
- MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)),
- MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)),
- MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)),
- }
+ RangeInclusive::new(self.start().stable(tables), self.end().stable(tables))
}
}