diff options
Diffstat (limited to 'compiler/rustc_smir/src')
-rw-r--r-- | compiler/rustc_smir/src/lib.rs | 6 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_internal/internal.rs | 444 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_internal/mod.rs | 39 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_internal/pretty.rs | 20 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/alloc.rs | 44 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/builder.rs | 29 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/context.rs | 555 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/convert/abi.rs | 242 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/convert/error.rs | 22 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/convert/mir.rs | 746 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/convert/mod.rs | 74 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 829 | ||||
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/mod.rs | 1781 |
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)) } } |