summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_smir/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_smir/src')
-rw-r--r--compiler/rustc_smir/src/lib.rs16
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs190
-rw-r--r--compiler/rustc_smir/src/rustc_smir/alloc.rs123
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs644
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir.rs3
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs478
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs153
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs463
8 files changed, 736 insertions, 1334 deletions
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 8cb533c8d..b6c36678d 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -10,26 +10,12 @@
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
-#![cfg_attr(not(feature = "default"), feature(rustc_private))]
+#![feature(rustc_private)]
#![feature(ptr_metadata)]
#![feature(type_alias_impl_trait)] // Used to define opaque types.
#![feature(intra_doc_pointers)]
-// Declare extern rustc_* crates to enable building this crate separately from the compiler.
-#[cfg(not(feature = "default"))]
-extern crate rustc_hir;
-#[cfg(not(feature = "default"))]
-extern crate rustc_middle;
-#[cfg(not(feature = "default"))]
-extern crate rustc_span;
-#[cfg(not(feature = "default"))]
-extern crate rustc_target;
-
pub mod rustc_internal;
-pub mod stable_mir;
// Make this module private for now since external users should not call these directly.
mod rustc_smir;
-
-#[macro_use]
-extern crate scoped_tls;
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 078ff6744..1a9dea99f 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -3,83 +3,37 @@
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.
-use std::fmt::Debug;
-use std::string::ToString;
+use std::ops::{ControlFlow, Index};
-use crate::{
- rustc_smir::Tables,
- stable_mir::{self, with},
-};
+use crate::rustc_internal;
+use crate::rustc_smir::Tables;
+use rustc_driver::{Callbacks, Compilation, RunCompiler};
+use rustc_interface::{interface, Queries};
+use rustc_middle::mir::interpret::AllocId;
use rustc_middle::ty::TyCtxt;
pub use rustc_span::def_id::{CrateNum, DefId};
+use rustc_span::Span;
+use stable_mir::CompilerError;
-fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
- let mut ret = None;
- with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t))));
- ret.unwrap()
-}
-
-pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
- with_tables(|t| t.item_def_id(item))
-}
-
-pub fn crate_item(did: DefId) -> stable_mir::CrateItem {
- with_tables(|t| t.crate_item(did))
-}
-
-pub fn adt_def(did: DefId) -> stable_mir::ty::AdtDef {
- with_tables(|t| t.adt_def(did))
-}
-
-pub fn foreign_def(did: DefId) -> stable_mir::ty::ForeignDef {
- with_tables(|t| t.foreign_def(did))
-}
-
-pub fn fn_def(did: DefId) -> stable_mir::ty::FnDef {
- with_tables(|t| t.fn_def(did))
-}
-
-pub fn closure_def(did: DefId) -> stable_mir::ty::ClosureDef {
- with_tables(|t| t.closure_def(did))
-}
-
-pub fn generator_def(did: DefId) -> stable_mir::ty::GeneratorDef {
- with_tables(|t| t.generator_def(did))
-}
-
-pub fn alias_def(did: DefId) -> stable_mir::ty::AliasDef {
- with_tables(|t| t.alias_def(did))
-}
-
-pub fn param_def(did: DefId) -> stable_mir::ty::ParamDef {
- with_tables(|t| t.param_def(did))
-}
+impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
+ type Output = DefId;
-pub fn br_named_def(did: DefId) -> stable_mir::ty::BrNamedDef {
- with_tables(|t| t.br_named_def(did))
+ #[inline(always)]
+ fn index(&self, index: stable_mir::DefId) -> &Self::Output {
+ &self.def_ids[index.0]
+ }
}
-pub fn trait_def(did: DefId) -> stable_mir::ty::TraitDef {
- with_tables(|t| t.trait_def(did))
-}
+impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
+ type Output = Span;
-pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef {
- with_tables(|t| t.impl_def(did))
+ #[inline(always)]
+ fn index(&self, index: stable_mir::ty::Span) -> &Self::Output {
+ &self.spans[index.0]
+ }
}
impl<'tcx> Tables<'tcx> {
- pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId {
- self.def_ids[item.0]
- }
-
- pub fn trait_def_id(&self, trait_def: &stable_mir::ty::TraitDef) -> DefId {
- self.def_ids[trait_def.0]
- }
-
- pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId {
- self.def_ids[impl_def.0]
- }
-
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
stable_mir::CrateItem(self.create_def_id(did))
}
@@ -120,6 +74,10 @@ impl<'tcx> Tables<'tcx> {
stable_mir::ty::TraitDef(self.create_def_id(did))
}
+ pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef {
+ stable_mir::ty::GenericDef(self.create_def_id(did))
+ }
+
pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
stable_mir::ty::ConstDef(self.create_def_id(did))
}
@@ -128,16 +86,45 @@ impl<'tcx> Tables<'tcx> {
stable_mir::ty::ImplDef(self.create_def_id(did))
}
+ pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef {
+ stable_mir::ty::RegionDef(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))
+ }
+
fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
// FIXME: this becomes inefficient when we have too many ids
for (i, &d) in self.def_ids.iter().enumerate() {
if d == did {
- return i;
+ return stable_mir::DefId(i);
}
}
let id = self.def_ids.len();
self.def_ids.push(did);
- id
+ stable_mir::DefId(id)
+ }
+
+ fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId {
+ // FIXME: this becomes inefficient when we have too many ids
+ if let Some(i) = self.alloc_ids.iter().position(|a| *a == aid) {
+ return stable_mir::AllocId(i);
+ };
+ let id = self.def_ids.len();
+ self.alloc_ids.push(aid);
+ stable_mir::AllocId(id)
+ }
+
+ pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
+ for (i, &sp) in self.spans.iter().enumerate() {
+ if sp == span {
+ return stable_mir::ty::Span(i);
+ }
+ }
+ let id = self.spans.len();
+ self.spans.push(span);
+ stable_mir::ty::Span(id)
}
}
@@ -146,12 +133,67 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
}
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
- crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f);
+ stable_mir::run(
+ Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] },
+ f,
+ );
+}
+
+pub struct StableMir<B = (), C = ()>
+where
+ B: Send,
+ C: Send,
+{
+ args: Vec<String>,
+ callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>,
+ result: Option<ControlFlow<B, C>>,
+}
+
+impl<B, C> StableMir<B, C>
+where
+ B: Send,
+ C: Send,
+{
+ /// Creates a new `StableMir` instance, with given test_function and arguments.
+ pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>) -> Self {
+ StableMir { args, callback, result: None }
+ }
+
+ /// Runs the compiler against given target and tests it with `test_function`
+ pub fn run(&mut self) -> Result<C, CompilerError<B>> {
+ let compiler_result =
+ rustc_driver::catch_fatal_errors(|| RunCompiler::new(&self.args.clone(), self).run());
+ match (compiler_result, self.result.take()) {
+ (Ok(Ok(())), Some(ControlFlow::Continue(value))) => Ok(value),
+ (Ok(Ok(())), Some(ControlFlow::Break(value))) => Err(CompilerError::Interrupted(value)),
+ (Ok(Ok(_)), None) => Err(CompilerError::Skipped),
+ (Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
+ (Err(_), _) => Err(CompilerError::ICE),
+ }
+ }
}
-/// A type that provides internal information but that can still be used for debug purpose.
-pub type Opaque = impl Debug + ToString + Clone;
-
-pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
- format!("{value:?}")
+impl<B, C> Callbacks for StableMir<B, C>
+where
+ B: Send,
+ C: Send,
+{
+ /// Called after analysis. Return value instructs the compiler whether to
+ /// continue the compilation afterwards (defaults to `Compilation::Continue`)
+ fn after_analysis<'tcx>(
+ &mut self,
+ _compiler: &interface::Compiler,
+ queries: &'tcx Queries<'tcx>,
+ ) -> Compilation {
+ queries.global_ctxt().unwrap().enter(|tcx| {
+ rustc_internal::run(tcx, || {
+ self.result = Some((self.callback)(tcx));
+ });
+ if self.result.as_ref().is_some_and(|val| val.is_continue()) {
+ Compilation::Continue
+ } else {
+ Compilation::Stop
+ }
+ })
+ }
}
diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs
new file mode 100644
index 000000000..63a2a1450
--- /dev/null
+++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs
@@ -0,0 +1,123 @@
+use rustc_middle::mir::{
+ interpret::{alloc_range, AllocRange, Pointer},
+ ConstValue,
+};
+
+use crate::rustc_smir::{Stable, Tables};
+use stable_mir::mir::Mutability;
+use stable_mir::ty::{Allocation, ProvenanceMap};
+
+/// Creates new empty `Allocation` from given `Align`.
+fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
+ Allocation {
+ bytes: Vec::new(),
+ provenance: ProvenanceMap { ptrs: Vec::new() },
+ align: align.bytes(),
+ mutability: Mutability::Not,
+ }
+}
+
+// We need this method instead of a Stable implementation
+// because we need to get `Ty` of the const we are trying to create, to do that
+// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
+#[allow(rustc::usage_of_qualified_ty)]
+pub fn new_allocation<'tcx>(
+ ty: rustc_middle::ty::Ty<'tcx>,
+ const_value: ConstValue<'tcx>,
+ tables: &mut Tables<'tcx>,
+) -> Allocation {
+ 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()
+ .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();
+ allocation.stable(tables)
+ }
+ ConstValue::ZeroSized => {
+ let align =
+ tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().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 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 mut allocation =
+ rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
+ allocation
+ .write_scalar(
+ &tables.tcx,
+ alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
+ scalar_ptr,
+ )
+ .unwrap();
+ allocation
+ .write_scalar(
+ &tables.tcx,
+ alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()),
+ scalar_meta,
+ )
+ .unwrap();
+ allocation.stable(tables)
+ }
+ ConstValue::Indirect { alloc_id, offset } => {
+ let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory();
+ let ty_size = tables
+ .tcx
+ .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty))
+ .unwrap()
+ .size;
+ allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
+ }
+ }
+}
+
+/// Creates an `Allocation` only from information within the `AllocRange`.
+pub(super) fn allocation_filter<'tcx>(
+ alloc: &rustc_middle::mir::interpret::Allocation,
+ alloc_range: AllocRange,
+ tables: &mut Tables<'tcx>,
+) -> Allocation {
+ let mut bytes: Vec<Option<u8>> = alloc
+ .inspect_with_uninit_and_ptr_outside_interpreter(
+ alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(),
+ )
+ .iter()
+ .copied()
+ .map(Some)
+ .collect();
+ for (i, b) in bytes.iter_mut().enumerate() {
+ if !alloc
+ .init_mask()
+ .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize()))
+ {
+ *b = None;
+ }
+ }
+ let mut ptrs = Vec::new();
+ for (offset, prov) in alloc
+ .provenance()
+ .ptrs()
+ .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)));
+ }
+ Allocation {
+ bytes: bytes,
+ provenance: ProvenanceMap { ptrs },
+ align: alloc.align.bytes(),
+ mutability: alloc.mutability.stable(tables),
+ }
+}
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 06b37008e..6e83b9601 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -1,5 +1,5 @@
//! Module that implements what will become the rustc side of Stable MIR.
-//!
+
//! This module is responsible for building Stable MIR components from internal components.
//!
//! This module is not intended to be invoked directly by users. It will eventually
@@ -7,21 +7,21 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
-use crate::rustc_internal::{self, opaque};
-use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
-use crate::stable_mir::ty::{
- allocation_filter, new_allocation, Const, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
-};
-use crate::stable_mir::{self, Context};
+use crate::rustc_smir::hir::def::DefKind;
+use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
use rustc_hir as hir;
-use rustc_middle::mir::coverage::CodeRegion;
-use rustc_middle::mir::interpret::alloc_range;
-use rustc_middle::mir::{self, ConstantKind};
+use rustc_middle::mir;
+use rustc_middle::mir::interpret::{alloc_range, AllocId};
use rustc_middle::ty::{self, Ty, TyCtxt, Variance};
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_target::abi::FieldIdx;
+use stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
+use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy};
+use stable_mir::{self, opaque, Context};
use tracing::debug;
+mod alloc;
+
impl<'tcx> Context for Tables<'tcx> {
fn local_crate(&self) -> stable_mir::Crate {
smir_crate(self.tcx, LOCAL_CRATE)
@@ -38,9 +38,26 @@ impl<'tcx> Context for Tables<'tcx> {
})
}
+ fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
+ self.tcx.def_path_str(self[def_id])
+ }
+
+ fn print_span(&self, span: stable_mir::ty::Span) -> String {
+ self.tcx.sess.source_map().span_to_diagnostic_string(self[span])
+ }
+
+ fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
+ self.tcx.def_kind(self[def_id]).stable(self)
+ }
+
+ fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span {
+ self.tcx.def_span(self[def_id]).stable(self)
+ }
+
fn all_local_items(&mut self) -> stable_mir::CrateItems {
self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect()
}
+
fn entry_fn(&mut self) -> Option<stable_mir::CrateItem> {
Some(self.crate_item(self.tcx.entry_fn(())?.0))
}
@@ -54,7 +71,7 @@ impl<'tcx> Context for Tables<'tcx> {
}
fn trait_decl(&mut self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
- let def_id = self.trait_def_id(trait_def);
+ let def_id = self[trait_def.0];
let trait_def = self.tcx.trait_def(def_id);
trait_def.stable(self)
}
@@ -68,14 +85,14 @@ impl<'tcx> Context for Tables<'tcx> {
}
fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
- let def_id = self.impl_trait_def_id(impl_def);
+ let def_id = self[impl_def.0];
let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap();
impl_trait.stable(self)
}
- fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
- let def_id = self.item_def_id(item);
- let mir = self.tcx.optimized_mir(def_id);
+ fn mir_body(&mut self, item: stable_mir::DefId) -> stable_mir::mir::Body {
+ let def_id = self[item];
+ let mir = self.tcx.instance_mir(ty::InstanceDef::Item(def_id));
stable_mir::mir::Body {
blocks: mir
.basic_blocks
@@ -93,29 +110,96 @@ impl<'tcx> Context for Tables<'tcx> {
}
}
- fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) {
- f(self)
+ fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind {
+ self.types[ty.0].clone().stable(self)
+ }
+
+ fn mk_ty(&mut self, kind: TyKind) -> stable_mir::ty::Ty {
+ let n = self.types.len();
+ self.types.push(MaybeStable::Stable(kind));
+ stable_mir::ty::Ty(n)
+ }
+
+ fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
+ let def_id = self[def_id];
+ let generics = self.tcx.generics_of(def_id);
+ generics.stable(self)
+ }
+
+ fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
+ let def_id = self[def_id];
+ let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
+ stable_mir::ty::GenericPredicates {
+ parent: parent.map(|did| self.trait_def(did)),
+ predicates: predicates
+ .iter()
+ .map(|(clause, span)| {
+ (clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
+ })
+ .collect(),
+ }
+ }
+
+ fn explicit_predicates_of(
+ &mut self,
+ def_id: stable_mir::DefId,
+ ) -> stable_mir::ty::GenericPredicates {
+ let def_id = self[def_id];
+ let ty::GenericPredicates { parent, predicates } = self.tcx.explicit_predicates_of(def_id);
+ stable_mir::ty::GenericPredicates {
+ parent: parent.map(|did| self.trait_def(did)),
+ predicates: predicates
+ .iter()
+ .map(|(clause, span)| {
+ (clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
+ })
+ .collect(),
+ }
+ }
+}
+
+#[derive(Clone)]
+pub enum MaybeStable<S, R> {
+ Stable(S),
+ Rustc(R),
+}
+
+impl<'tcx, S, R> MaybeStable<S, R> {
+ fn stable(self, tables: &mut Tables<'tcx>) -> S
+ where
+ R: Stable<'tcx, T = S>,
+ {
+ match self {
+ MaybeStable::Stable(s) => s,
+ MaybeStable::Rustc(r) => r.stable(tables),
+ }
}
+}
- fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind {
- let ty = self.types[ty.0];
- ty.stable(self)
+impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {
+ fn eq(&self, other: &R) -> bool {
+ match self {
+ MaybeStable::Stable(_) => false,
+ MaybeStable::Rustc(r) => r == other,
+ }
}
}
pub struct Tables<'tcx> {
pub tcx: TyCtxt<'tcx>,
pub def_ids: Vec<DefId>,
- pub types: Vec<Ty<'tcx>>,
+ pub alloc_ids: Vec<AllocId>,
+ pub spans: Vec<rustc_span::Span>,
+ pub types: Vec<MaybeStable<stable_mir::ty::TyKind, Ty<'tcx>>>,
}
impl<'tcx> Tables<'tcx> {
fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
- if let Some(id) = self.types.iter().position(|&t| t == ty) {
+ if let Some(id) = self.types.iter().position(|t| *t == ty) {
return stable_mir::ty::Ty(id);
}
let id = self.types.len();
- self.types.push(ty);
+ self.types.push(MaybeStable::Rustc(ty));
stable_mir::ty::Ty(id)
}
}
@@ -168,10 +252,7 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
variance: variance.stable(tables),
}
}
- Coverage(coverage) => stable_mir::mir::Statement::Coverage(stable_mir::mir::Coverage {
- kind: coverage.kind.stable(tables),
- code_region: coverage.code_region.as_ref().map(|reg| reg.stable(tables)),
- }),
+ Coverage(coverage) => stable_mir::mir::Statement::Coverage(opaque(coverage)),
Intrinsic(intrinstic) => {
stable_mir::mir::Statement::Intrinsic(intrinstic.stable(tables))
}
@@ -188,17 +269,16 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
match self {
Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
Repeat(op, len) => {
- let cnst = ConstantKind::from_const(*len, tables.tcx);
- let len = Const { literal: cnst.stable(tables) };
+ let len = len.stable(tables);
stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
}
Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
- opaque(region),
+ region.stable(tables),
kind.stable(tables),
place.stable(tables),
),
ThreadLocalRef(def_id) => {
- stable_mir::mir::Rvalue::ThreadLocalRef(rustc_internal::crate_item(*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))
@@ -255,7 +335,7 @@ impl<'tcx> Stable<'tcx> for mir::BorrowKind {
use mir::BorrowKind::*;
match *self {
Shared => stable_mir::mir::BorrowKind::Shared,
- Shallow => stable_mir::mir::BorrowKind::Shallow,
+ Fake => stable_mir::mir::BorrowKind::Fake,
Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) },
}
}
@@ -377,8 +457,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
match self {
ty::TermKind::Ty(ty) => TermKind::Type(tables.intern_ty(*ty)),
ty::TermKind::Const(cnst) => {
- let cnst = ConstantKind::from_const(*cnst, tables.tcx);
- let cnst = Const { literal: cnst.stable(tables) };
+ let cnst = cnst.stable(tables);
TermKind::Const(cnst)
}
}
@@ -457,7 +536,19 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
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.to_string()),
+ 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),
}
}
}
@@ -472,30 +563,6 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
}
}
-impl<'tcx> Stable<'tcx> for mir::coverage::CoverageKind {
- type T = stable_mir::mir::CoverageKind;
- fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- use rustc_middle::mir::coverage::CoverageKind;
- match self {
- CoverageKind::Counter { function_source_hash, id } => {
- stable_mir::mir::CoverageKind::Counter {
- function_source_hash: *function_source_hash as usize,
- id: opaque(id),
- }
- }
- CoverageKind::Expression { id, lhs, op, rhs } => {
- stable_mir::mir::CoverageKind::Expression {
- id: opaque(id),
- lhs: opaque(lhs),
- op: op.stable(tables),
- rhs: opaque(rhs),
- }
- }
- CoverageKind::Unreachable => stable_mir::mir::CoverageKind::Unreachable,
- }
- }
-}
-
impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
type T = stable_mir::mir::UserTypeProjection;
@@ -504,18 +571,6 @@ impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
}
}
-impl<'tcx> Stable<'tcx> for mir::coverage::Op {
- type T = stable_mir::mir::Op;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- use rustc_middle::mir::coverage::Op::*;
- match self {
- Subtract => stable_mir::mir::Op::Subtract,
- Add => stable_mir::mir::Op::Add,
- }
- }
-}
-
impl<'tcx> Stable<'tcx> for mir::Local {
type T = stable_mir::mir::Local;
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -562,20 +617,6 @@ impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
}
}
-impl<'tcx> Stable<'tcx> for CodeRegion {
- type T = stable_mir::mir::CodeRegion;
-
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
- stable_mir::mir::CodeRegion {
- file_name: self.file_name.as_str().to_string(),
- start_line: self.start_line as usize,
- start_col: self.start_col as usize,
- end_line: self.end_line as usize,
- end_col: self.end_col as usize,
- }
- }
-}
-
impl<'tcx> Stable<'tcx> for mir::UnwindAction {
type T = stable_mir::mir::UnwindAction;
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -583,7 +624,7 @@ impl<'tcx> Stable<'tcx> for 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::Terminate(_) => stable_mir::mir::UnwindAction::Terminate,
UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()),
}
}
@@ -700,7 +741,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
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(
- rustc_internal::adt_def(*def_id),
+ tables.adt_def(*def_id),
var_idx.index(),
generic_arg.stable(tables),
user_ty_index.map(|idx| idx.index()),
@@ -709,13 +750,13 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
}
mir::AggregateKind::Closure(def_id, generic_arg) => {
stable_mir::mir::AggregateKind::Closure(
- rustc_internal::closure_def(*def_id),
+ tables.closure_def(*def_id),
generic_arg.stable(tables),
)
}
mir::AggregateKind::Generator(def_id, generic_arg, movability) => {
stable_mir::mir::AggregateKind::Generator(
- rustc_internal::generator_def(*def_id),
+ tables.generator_def(*def_id),
generic_arg.stable(tables),
movability.stable(tables),
)
@@ -780,8 +821,8 @@ impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
.collect(),
otherwise: targets.otherwise().as_usize(),
},
- Resume => Terminator::Resume,
- Terminate => Terminator::Abort,
+ UnwindResume => Terminator::Resume,
+ UnwindTerminate(_) => Terminator::Abort,
Return => Terminator::Return,
Unreachable => Terminator::Unreachable,
Drop { place, target, unwind, replace: _ } => Terminator::Drop {
@@ -835,12 +876,9 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::GenericArgKind;
match self {
- ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(opaque(region)),
+ ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)),
ty::GenericArgKind::Type(ty) => GenericArgKind::Type(tables.intern_ty(*ty)),
- ty::GenericArgKind::Const(cnst) => {
- let cnst = ConstantKind::from_const(*cnst, tables.tcx);
- GenericArgKind::Const(stable_mir::ty::Const { literal: cnst.stable(tables) })
- }
+ ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)),
}
}
}
@@ -928,13 +966,13 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
type T = stable_mir::ty::BoundTyKind;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ 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(rustc_internal::param_def(*def_id), symbol.to_string())
+ BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string())
}
}
}
@@ -943,15 +981,13 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
type T = stable_mir::ty::BoundRegionKind;
- fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::BoundRegionKind;
match self {
- ty::BoundRegionKind::BrAnon(option_span) => {
- BoundRegionKind::BrAnon(option_span.map(|span| opaque(&span)))
- }
+ ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon,
ty::BoundRegionKind::BrNamed(def_id, symbol) => {
- BoundRegionKind::BrNamed(rustc_internal::br_named_def(*def_id), symbol.to_string())
+ BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string())
}
ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv,
}
@@ -1038,31 +1074,26 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
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(
- rustc_internal::adt_def(adt_def.did()),
+ tables.adt_def(adt_def.did()),
generic_args.stable(tables),
)),
- ty::Foreign(def_id) => {
- TyKind::RigidTy(RigidTy::Foreign(rustc_internal::foreign_def(*def_id)))
- }
+ ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))),
ty::Str => TyKind::RigidTy(RigidTy::Str),
ty::Array(ty, constant) => {
- let cnst = ConstantKind::from_const(*constant, tables.tcx);
- let cnst = stable_mir::ty::Const { literal: cnst.stable(tables) };
- TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), cnst))
+ TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables)))
}
ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(tables.intern_ty(*ty))),
ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => {
TyKind::RigidTy(RigidTy::RawPtr(tables.intern_ty(*ty), mutbl.stable(tables)))
}
ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
- opaque(region),
+ region.stable(tables),
tables.intern_ty(*ty),
mutbl.stable(tables),
)),
- ty::FnDef(def_id, generic_args) => TyKind::RigidTy(RigidTy::FnDef(
- rustc_internal::fn_def(*def_id),
- generic_args.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(
@@ -1070,16 +1101,16 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
.iter()
.map(|existential_predicate| existential_predicate.stable(tables))
.collect(),
- opaque(region),
+ region.stable(tables),
dyn_kind.stable(tables),
))
}
ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure(
- rustc_internal::closure_def(*def_id),
+ tables.closure_def(*def_id),
generic_args.stable(tables),
)),
ty::Generator(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Generator(
- rustc_internal::generator_def(*def_id),
+ tables.generator_def(*def_id),
generic_args.stable(tables),
movability.stable(tables),
)),
@@ -1094,17 +1125,54 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
ty::Bound(debruijn_idx, bound_ty) => {
TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables))
}
- ty::Placeholder(..)
- | ty::GeneratorWitness(_)
- | ty::GeneratorWitnessMIR(_, _)
- | ty::Infer(_)
- | ty::Error(_) => {
+ ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) | ty::Error(_) => {
unreachable!();
}
}
}
}
+impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
+ type T = stable_mir::ty::Const;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ stable_mir::ty::Const {
+ literal: match self.kind() {
+ ty::Value(val) => {
+ let const_val = tables.tcx.valtree_to_const_val((self.ty(), val));
+ stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
+ self.ty(),
+ const_val,
+ tables,
+ ))
+ }
+ ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
+ ty::ErrorCt(_) => unreachable!(),
+ ty::InferCt(_) => unreachable!(),
+ ty::BoundCt(_, _) => unimplemented!(),
+ ty::PlaceholderCt(_) => unimplemented!(),
+ ty::Unevaluated(uv) => {
+ stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
+ def: tables.const_def(uv.def),
+ args: uv.args.stable(tables),
+ promoted: None,
+ })
+ }
+ ty::ExprCt(_) => unimplemented!(),
+ },
+ ty: tables.intern_ty(self.ty()),
+ }
+ }
+}
+
+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 {
@@ -1125,7 +1193,11 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
type T = stable_mir::ty::Allocation;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
- allocation_filter(self, alloc_range(rustc_target::abi::Size::ZERO, self.size()), tables)
+ alloc::allocation_filter(
+ self,
+ alloc_range(rustc_target::abi::Size::ZERO, self.size()),
+ tables,
+ )
}
}
@@ -1150,7 +1222,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
use stable_mir::ty::TraitDecl;
TraitDecl {
- def_id: rustc_internal::trait_def(self.def_id),
+ 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,
@@ -1168,31 +1240,28 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
}
}
-impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> {
- type T = stable_mir::ty::ConstantKind;
+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 {
- ConstantKind::Ty(c) => match c.kind() {
- ty::Value(val) => {
- let const_val = tables.tcx.valtree_to_const_val((c.ty(), val));
- stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables))
- }
- ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(&param)),
- ty::ErrorCt(_) => unreachable!(),
- _ => unimplemented!(),
+ match *self {
+ mir::Const::Ty(c) => c.stable(tables),
+ mir::Const::Unevaluated(unev_const, ty) => stable_mir::ty::Const {
+ literal: stable_mir::ty::ConstantKind::Unevaluated(
+ stable_mir::ty::UnevaluatedConst {
+ def: tables.const_def(unev_const.def),
+ args: unev_const.args.stable(tables),
+ promoted: unev_const.promoted.map(|u| u.as_u32()),
+ },
+ ),
+ ty: tables.intern_ty(ty),
+ },
+ mir::Const::Val(val, ty) => stable_mir::ty::Const {
+ literal: stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
+ ty, val, tables,
+ )),
+ ty: tables.intern_ty(ty),
},
- ConstantKind::Unevaluated(unev_const, ty) => {
- stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
- ty: tables.intern_ty(*ty),
- def: tables.const_def(unev_const.def),
- args: unev_const.args.stable(tables),
- promoted: unev_const.promoted.map(|u| u.as_u32()),
- })
- }
- ConstantKind::Val(val, _) => {
- stable_mir::ty::ConstantKind::Allocated(new_allocation(self, *val, tables))
- }
}
}
}
@@ -1202,6 +1271,285 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::TraitRef;
- TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
+ 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 {
+ Trait(trait_object) => stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables)),
+ RegionOutlives(region_outlives) => {
+ stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables))
+ }
+ TypeOutlives(type_outlives) => {
+ let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
+ stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
+ tables.intern_ty(a),
+ b.stable(tables),
+ ))
+ }
+ Projection(projection_predicate) => {
+ stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables))
+ }
+ ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
+ const_.stable(tables),
+ tables.intern_ty(ty),
+ ),
+ WellFormed(generic_arg) => {
+ stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables))
+ }
+ 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;
+
+ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+ let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
+ stable_mir::ty::SubtypePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) }
+ }
+}
+
+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: tables.intern_ty(*a), b: tables.intern_ty(*b) }
+ }
+}
+
+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>
+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 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::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:?}"),
+ }
+ }
+}
+
+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)
+ }
+}
+
+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)
}
}
diff --git a/compiler/rustc_smir/src/stable_mir/mir.rs b/compiler/rustc_smir/src/stable_mir/mir.rs
deleted file mode 100644
index a9dbc3463..000000000
--- a/compiler/rustc_smir/src/stable_mir/mir.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod body;
-
-pub use body::*;
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
deleted file mode 100644
index c16bd6cbd..000000000
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ /dev/null
@@ -1,478 +0,0 @@
-use crate::rustc_internal::Opaque;
-use crate::stable_mir::ty::{
- AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region,
-};
-use crate::stable_mir::{self, ty::Ty};
-
-#[derive(Clone, Debug)]
-pub struct Body {
- pub blocks: Vec<BasicBlock>,
- pub locals: Vec<Ty>,
-}
-
-#[derive(Clone, Debug)]
-pub struct BasicBlock {
- pub statements: Vec<Statement>,
- pub terminator: Terminator,
-}
-
-#[derive(Clone, Debug)]
-pub enum Terminator {
- Goto {
- target: usize,
- },
- SwitchInt {
- discr: Operand,
- targets: Vec<SwitchTarget>,
- otherwise: usize,
- },
- Resume,
- Abort,
- Return,
- Unreachable,
- Drop {
- place: Place,
- target: usize,
- unwind: UnwindAction,
- },
- Call {
- func: Operand,
- args: Vec<Operand>,
- destination: Place,
- target: Option<usize>,
- unwind: UnwindAction,
- },
- Assert {
- cond: Operand,
- expected: bool,
- msg: AssertMessage,
- target: usize,
- unwind: UnwindAction,
- },
- GeneratorDrop,
- InlineAsm {
- template: String,
- operands: Vec<InlineAsmOperand>,
- options: String,
- line_spans: String,
- destination: Option<usize>,
- unwind: UnwindAction,
- },
-}
-
-#[derive(Clone, Debug)]
-pub struct InlineAsmOperand {
- pub in_value: Option<Operand>,
- pub out_place: Option<Place>,
- // This field has a raw debug representation of MIR's InlineAsmOperand.
- // For now we care about place/operand + the rest in a debug format.
- pub raw_rpr: String,
-}
-
-#[derive(Clone, Debug)]
-pub enum UnwindAction {
- Continue,
- Unreachable,
- Terminate,
- Cleanup(usize),
-}
-
-#[derive(Clone, Debug)]
-pub enum AssertMessage {
- BoundsCheck { len: Operand, index: Operand },
- Overflow(BinOp, Operand, Operand),
- OverflowNeg(Operand),
- DivisionByZero(Operand),
- RemainderByZero(Operand),
- ResumedAfterReturn(GeneratorKind),
- ResumedAfterPanic(GeneratorKind),
- MisalignedPointerDereference { required: Operand, found: Operand },
-}
-
-#[derive(Clone, Debug)]
-pub enum BinOp {
- Add,
- AddUnchecked,
- Sub,
- SubUnchecked,
- Mul,
- MulUnchecked,
- Div,
- Rem,
- BitXor,
- BitAnd,
- BitOr,
- Shl,
- ShlUnchecked,
- Shr,
- ShrUnchecked,
- Eq,
- Lt,
- Le,
- Ne,
- Ge,
- Gt,
- Offset,
-}
-
-#[derive(Clone, Debug)]
-pub enum UnOp {
- Not,
- Neg,
-}
-
-#[derive(Clone, Debug)]
-pub enum GeneratorKind {
- Async(AsyncGeneratorKind),
- Gen,
-}
-
-#[derive(Clone, Debug)]
-pub enum AsyncGeneratorKind {
- Block,
- Closure,
- Fn,
-}
-
-pub(crate) type LocalDefId = Opaque;
-pub(crate) type CounterValueReference = Opaque;
-pub(crate) type InjectedExpressionId = Opaque;
-pub(crate) type ExpressionOperandId = Opaque;
-
-/// The FakeReadCause describes the type of pattern why a FakeRead statement exists.
-#[derive(Clone, Debug)]
-pub enum FakeReadCause {
- ForMatchGuard,
- ForMatchedPlace(LocalDefId),
- ForGuardBinding,
- ForLet(LocalDefId),
- ForIndex,
-}
-
-/// Describes what kind of retag is to be performed
-#[derive(Clone, Debug)]
-pub enum RetagKind {
- FnEntry,
- TwoPhase,
- Raw,
- Default,
-}
-
-#[derive(Clone, Debug)]
-pub enum Variance {
- Covariant,
- Invariant,
- Contravariant,
- Bivariant,
-}
-
-#[derive(Clone, Debug)]
-pub enum Op {
- Subtract,
- Add,
-}
-
-#[derive(Clone, Debug)]
-pub enum CoverageKind {
- Counter {
- function_source_hash: usize,
- id: CounterValueReference,
- },
- Expression {
- id: InjectedExpressionId,
- lhs: ExpressionOperandId,
- op: Op,
- rhs: ExpressionOperandId,
- },
- Unreachable,
-}
-
-#[derive(Clone, Debug)]
-pub struct CodeRegion {
- pub file_name: String,
- pub start_line: usize,
- pub start_col: usize,
- pub end_line: usize,
- pub end_col: usize,
-}
-
-#[derive(Clone, Debug)]
-pub struct Coverage {
- pub kind: CoverageKind,
- pub code_region: Option<CodeRegion>,
-}
-
-#[derive(Clone, Debug)]
-pub struct CopyNonOverlapping {
- pub src: Operand,
- pub dst: Operand,
- pub count: Operand,
-}
-
-#[derive(Clone, Debug)]
-pub enum NonDivergingIntrinsic {
- Assume(Operand),
- CopyNonOverlapping(CopyNonOverlapping),
-}
-
-#[derive(Clone, Debug)]
-pub enum Statement {
- Assign(Place, Rvalue),
- FakeRead(FakeReadCause, Place),
- SetDiscriminant { place: Place, variant_index: VariantIdx },
- Deinit(Place),
- StorageLive(Local),
- StorageDead(Local),
- Retag(RetagKind, Place),
- PlaceMention(Place),
- AscribeUserType { place: Place, projections: UserTypeProjection, variance: Variance },
- Coverage(Coverage),
- Intrinsic(NonDivergingIntrinsic),
- ConstEvalCounter,
- Nop,
-}
-
-#[derive(Clone, Debug)]
-pub enum Rvalue {
- /// Creates a pointer with the indicated mutability to the place.
- ///
- /// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
- /// `&raw v` or `addr_of!(v)`.
- AddressOf(Mutability, Place),
-
- /// Creates an aggregate value, like a tuple or struct.
- ///
- /// This is needed because dataflow analysis needs to distinguish
- /// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
- /// has a destructor.
- ///
- /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
- /// generator lowering, `Generator` aggregate kinds are disallowed too.
- Aggregate(AggregateKind, Vec<Operand>),
-
- /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
- /// parameter may be a `usize` as well.
- /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
- /// raw pointers, or function pointers and return a `bool`. The types of the operands must be
- /// matching, up to the usual caveat of the lifetimes in function pointers.
- /// * Left and right shift operations accept signed or unsigned integers not necessarily of the
- /// same type and return a value of the same type as their LHS. Like in Rust, the RHS is
- /// truncated as needed.
- /// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
- /// types and return a value of that type.
- /// * The remaining operations accept signed integers, unsigned integers, or floats with
- /// matching types and return a value of that type.
- BinaryOp(BinOp, Operand, Operand),
-
- /// Performs essentially all of the casts that can be performed via `as`.
- ///
- /// This allows for casts from/to a variety of types.
- Cast(CastKind, Operand, Ty),
-
- /// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
- ///
- /// For addition, subtraction, and multiplication on integers the error condition is set when
- /// the infinite precision result would not be equal to the actual result.
- CheckedBinaryOp(BinOp, Operand, Operand),
-
- /// A CopyForDeref is equivalent to a read from a place.
- /// When such a read happens, it is guaranteed that the only use of the returned value is a
- /// deref operation, immediately followed by one or more projections.
- CopyForDeref(Place),
-
- /// Computes the discriminant of the place, returning it as an integer of type
- /// [`discriminant_ty`]. Returns zero for types without discriminant.
- ///
- /// The validity requirements for the underlying value are undecided for this rvalue, see
- /// [#91095]. Note too that the value of the discriminant is not the same thing as the
- /// variant index; use [`discriminant_for_variant`] to convert.
- ///
- /// [`discriminant_ty`]: rustc_middle::ty::Ty::discriminant_ty
- /// [#91095]: https://github.com/rust-lang/rust/issues/91095
- /// [`discriminant_for_variant`]: rustc_middle::ty::Ty::discriminant_for_variant
- Discriminant(Place),
-
- /// Yields the length of the place, as a `usize`.
- ///
- /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
- /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
- /// ill-formed for places of other types.
- Len(Place),
-
- /// Creates a reference to the place.
- Ref(Region, BorrowKind, Place),
-
- /// Creates an array where each element is the value of the operand.
- ///
- /// This is the cause of a bug in the case where the repetition count is zero because the value
- /// is not dropped, see [#74836].
- ///
- /// Corresponds to source code like `[x; 32]`.
- ///
- /// [#74836]: https://github.com/rust-lang/rust/issues/74836
- Repeat(Operand, Const),
-
- /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
- ///
- /// This is different from a normal transmute because dataflow analysis will treat the box as
- /// initialized but its content as uninitialized. Like other pointer casts, this in general
- /// affects alias analysis.
- ShallowInitBox(Operand, Ty),
-
- /// Creates a pointer/reference to the given thread local.
- ///
- /// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a
- /// `*const T`, and if neither of those apply a `&T`.
- ///
- /// **Note:** This is a runtime operation that actually executes code and is in this sense more
- /// like a function call. Also, eliminating dead stores of this rvalue causes `fn main() {}` to
- /// SIGILL for some reason that I (JakobDegen) never got a chance to look into.
- ///
- /// **Needs clarification**: Are there weird additional semantics here related to the runtime
- /// nature of this operation?
- ThreadLocalRef(stable_mir::CrateItem),
-
- /// Computes a value as described by the operation.
- NullaryOp(NullOp, Ty),
-
- /// Exactly like `BinaryOp`, but less operands.
- ///
- /// Also does two's-complement arithmetic. Negation requires a signed integer or a float;
- /// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds
- /// return a value with the same type as their operand.
- UnaryOp(UnOp, Operand),
-
- /// Yields the operand unchanged
- Use(Operand),
-}
-
-#[derive(Clone, Debug)]
-pub enum AggregateKind {
- Array(Ty),
- Tuple,
- Adt(AdtDef, VariantIdx, GenericArgs, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
- Closure(ClosureDef, GenericArgs),
- Generator(GeneratorDef, GenericArgs, Movability),
-}
-
-#[derive(Clone, Debug)]
-pub enum Operand {
- Copy(Place),
- Move(Place),
- Constant(String),
-}
-
-#[derive(Clone, Debug)]
-pub struct Place {
- pub local: Local,
- pub projection: String,
-}
-
-#[derive(Clone, Debug)]
-pub struct UserTypeProjection {
- pub base: UserTypeAnnotationIndex,
- pub projection: String,
-}
-
-pub type Local = usize;
-
-type FieldIdx = usize;
-
-/// The source-order index of a variant in a type.
-pub type VariantIdx = usize;
-
-type UserTypeAnnotationIndex = usize;
-
-#[derive(Clone, Debug)]
-pub struct SwitchTarget {
- pub value: u128,
- pub target: usize,
-}
-
-#[derive(Clone, Debug)]
-pub enum BorrowKind {
- /// Data must be immutable and is aliasable.
- Shared,
-
- /// The immediately borrowed place must be immutable, but projections from
- /// it don't need to be. For example, a shallow borrow of `a.b` doesn't
- /// conflict with a mutable borrow of `a.b.c`.
- Shallow,
-
- /// Data is mutable and not aliasable.
- Mut {
- /// `true` if this borrow arose from method-call auto-ref
- kind: MutBorrowKind,
- },
-}
-
-#[derive(Clone, Debug)]
-pub enum MutBorrowKind {
- Default,
- TwoPhaseBorrow,
- ClosureCapture,
-}
-
-#[derive(Clone, Debug)]
-pub enum Mutability {
- Not,
- Mut,
-}
-
-#[derive(Clone, Debug)]
-pub enum Safety {
- Unsafe,
- Normal,
-}
-
-#[derive(Clone, Debug)]
-pub enum PointerCoercion {
- /// Go from a fn-item type to a fn-pointer type.
- ReifyFnPointer,
-
- /// Go from a safe fn pointer to an unsafe fn pointer.
- UnsafeFnPointer,
-
- /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
- /// It cannot convert a closure that requires unsafe.
- ClosureFnPointer(Safety),
-
- /// Go from a mut raw pointer to a const raw pointer.
- MutToConstPointer,
-
- /// Go from `*const [T; N]` to `*const T`
- ArrayToPointer,
-
- /// Unsize a pointer/reference value, e.g., `&[T; n]` to
- /// `&[T]`. Note that the source could be a thin or fat pointer.
- /// This will do things like convert thin pointers to fat
- /// pointers, or convert structs containing thin pointers to
- /// structs containing fat pointers, or convert between fat
- /// pointers.
- Unsize,
-}
-
-#[derive(Clone, Debug)]
-pub enum CastKind {
- PointerExposeAddress,
- PointerFromExposedAddress,
- PointerCoercion(PointerCoercion),
- DynStar,
- IntToInt,
- FloatToInt,
- FloatToFloat,
- IntToFloat,
- PtrToPtr,
- FnPtrToPtr,
- Transmute,
-}
-
-#[derive(Clone, Debug)]
-pub enum NullOp {
- /// Returns the size of a value of that type.
- SizeOf,
- /// Returns the minimum alignment of a type.
- AlignOf,
- /// Returns the offset of a field.
- OffsetOf(Vec<FieldIdx>),
-}
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
deleted file mode 100644
index 19061742b..000000000
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-//! Module that implements the public interface to the Stable MIR.
-//!
-//! This module shall contain all type definitions and APIs that we expect 3P tools to invoke to
-//! interact with the compiler.
-//!
-//! The goal is to eventually move this module to its own crate which shall be published on
-//! [crates.io](https://crates.io).
-//!
-//! ## Note:
-//!
-//! There shouldn't be any direct references to internal compiler constructs in this module.
-//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`.
-
-use std::cell::Cell;
-
-use crate::rustc_smir::Tables;
-
-use self::ty::{ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
-
-pub mod mir;
-pub mod ty;
-
-/// Use String for now but we should replace it.
-pub type Symbol = String;
-
-/// The number that identifies a crate.
-pub type CrateNum = usize;
-
-/// A unique identification number for each item accessible for the current compilation unit.
-pub type DefId = usize;
-
-/// A list of crate items.
-pub type CrateItems = Vec<CrateItem>;
-
-/// A list of trait decls.
-pub type TraitDecls = Vec<TraitDef>;
-
-/// A list of impl trait decls.
-pub type ImplTraitDecls = Vec<ImplDef>;
-
-/// Holds information about a crate.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct Crate {
- pub(crate) id: CrateNum,
- pub name: Symbol,
- pub is_local: bool,
-}
-
-/// Holds information about an item in the crate.
-/// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to
-/// use this item.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct CrateItem(pub(crate) DefId);
-
-impl CrateItem {
- pub fn body(&self) -> mir::Body {
- with(|cx| cx.mir_body(self))
- }
-}
-
-/// Return the function where execution starts if the current
-/// crate defines that. This is usually `main`, but could be
-/// `start` if the crate is a no-std crate.
-pub fn entry_fn() -> Option<CrateItem> {
- with(|cx| cx.entry_fn())
-}
-
-/// Access to the local crate.
-pub fn local_crate() -> Crate {
- with(|cx| cx.local_crate())
-}
-
-/// Try to find a crate with the given name.
-pub fn find_crate(name: &str) -> Option<Crate> {
- with(|cx| cx.find_crate(name))
-}
-
-/// Try to find a crate with the given name.
-pub fn external_crates() -> Vec<Crate> {
- with(|cx| cx.external_crates())
-}
-
-/// Retrieve all items in the local crate that have a MIR associated with them.
-pub fn all_local_items() -> CrateItems {
- with(|cx| cx.all_local_items())
-}
-
-pub fn all_trait_decls() -> TraitDecls {
- with(|cx| cx.all_trait_decls())
-}
-
-pub fn trait_decl(trait_def: &TraitDef) -> TraitDecl {
- with(|cx| cx.trait_decl(trait_def))
-}
-
-pub fn all_trait_impls() -> ImplTraitDecls {
- with(|cx| cx.all_trait_impls())
-}
-
-pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
- with(|cx| cx.trait_impl(trait_impl))
-}
-
-pub trait Context {
- fn entry_fn(&mut self) -> Option<CrateItem>;
- /// Retrieve all items of the local crate that have a MIR associated with them.
- fn all_local_items(&mut self) -> CrateItems;
- fn mir_body(&mut self, item: &CrateItem) -> mir::Body;
- fn all_trait_decls(&mut self) -> TraitDecls;
- fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
- fn all_trait_impls(&mut self) -> ImplTraitDecls;
- fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
- /// Get information about the local crate.
- fn local_crate(&self) -> Crate;
- /// Retrieve a list of all external crates.
- fn external_crates(&self) -> Vec<Crate>;
-
- /// Find a crate with the given name.
- fn find_crate(&self, name: &str) -> Option<Crate>;
-
- /// Obtain the representation of a type.
- fn ty_kind(&mut self, ty: Ty) -> TyKind;
-
- /// HACK: Until we have fully stable consumers, we need an escape hatch
- /// to get `DefId`s out of `CrateItem`s.
- fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>));
-}
-
-// A thread local variable that stores a pointer to the tables mapping between TyCtxt
-// datastructures and stable MIR datastructures
-scoped_thread_local! (static TLV: Cell<*mut ()>);
-
-pub fn run(mut context: impl Context, f: impl FnOnce()) {
- assert!(!TLV.is_set());
- fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) {
- let ptr: *mut () = &mut context as *mut &mut _ as _;
- TLV.set(&Cell::new(ptr), || {
- f();
- });
- }
- g(&mut context, f);
-}
-
-/// Loads the current context and calls a function with it.
-/// Do not nest these, as that will ICE.
-pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
- assert!(TLV.is_set());
- TLV.with(|tlv| {
- let ptr = tlv.get();
- assert!(!ptr.is_null());
- f(unsafe { *(ptr as *mut &mut dyn Context) })
- })
-}
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
deleted file mode 100644
index 7a6601f09..000000000
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ /dev/null
@@ -1,463 +0,0 @@
-use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer};
-
-use super::{mir::Mutability, mir::Safety, with, DefId};
-use crate::{
- rustc_internal::{opaque, Opaque},
- rustc_smir::{Stable, Tables},
-};
-
-#[derive(Copy, Clone, Debug)]
-pub struct Ty(pub usize);
-
-impl Ty {
- pub fn kind(&self) -> TyKind {
- with(|context| context.ty_kind(*self))
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct Const {
- pub literal: ConstantKind,
-}
-
-type Ident = Opaque;
-pub(crate) type Region = Opaque;
-type Span = Opaque;
-
-#[derive(Clone, Debug)]
-pub enum TyKind {
- RigidTy(RigidTy),
- Alias(AliasKind, AliasTy),
- Param(ParamTy),
- Bound(usize, BoundTy),
-}
-
-#[derive(Clone, Debug)]
-pub enum RigidTy {
- Bool,
- Char,
- Int(IntTy),
- Uint(UintTy),
- Float(FloatTy),
- Adt(AdtDef, GenericArgs),
- Foreign(ForeignDef),
- Str,
- Array(Ty, Const),
- Slice(Ty),
- RawPtr(Ty, Mutability),
- Ref(Region, Ty, Mutability),
- FnDef(FnDef, GenericArgs),
- FnPtr(PolyFnSig),
- Closure(ClosureDef, GenericArgs),
- Generator(GeneratorDef, GenericArgs, Movability),
- Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
- Never,
- Tuple(Vec<Ty>),
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum IntTy {
- Isize,
- I8,
- I16,
- I32,
- I64,
- I128,
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum UintTy {
- Usize,
- U8,
- U16,
- U32,
- U64,
- U128,
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum FloatTy {
- F32,
- F64,
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum Movability {
- Static,
- Movable,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ForeignDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct FnDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ClosureDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct GeneratorDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ParamDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct BrNamedDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct AdtDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct AliasDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct TraitDef(pub(crate) DefId);
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ConstDef(pub(crate) DefId);
-
-impl TraitDef {
- pub fn trait_decl(&self) -> TraitDecl {
- with(|cx| cx.trait_decl(self))
- }
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ImplDef(pub(crate) DefId);
-
-impl ImplDef {
- pub fn trait_impl(&self) -> ImplTrait {
- with(|cx| cx.trait_impl(self))
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct GenericArgs(pub Vec<GenericArgKind>);
-
-#[derive(Clone, Debug)]
-pub enum GenericArgKind {
- Lifetime(Region),
- Type(Ty),
- Const(Const),
-}
-
-#[derive(Clone, Debug)]
-pub enum TermKind {
- Type(Ty),
- Const(Const),
-}
-
-#[derive(Clone, Debug)]
-pub enum AliasKind {
- Projection,
- Inherent,
- Opaque,
- Weak,
-}
-
-#[derive(Clone, Debug)]
-pub struct AliasTy {
- pub def_id: AliasDef,
- pub args: GenericArgs,
-}
-
-pub type PolyFnSig = Binder<FnSig>;
-
-#[derive(Clone, Debug)]
-pub struct FnSig {
- pub inputs_and_output: Vec<Ty>,
- pub c_variadic: bool,
- pub unsafety: Safety,
- pub abi: Abi,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub enum Abi {
- Rust,
- C { unwind: bool },
- Cdecl { unwind: bool },
- Stdcall { unwind: bool },
- Fastcall { unwind: bool },
- Vectorcall { unwind: bool },
- Thiscall { unwind: bool },
- Aapcs { unwind: bool },
- Win64 { unwind: bool },
- SysV64 { unwind: bool },
- PtxKernel,
- Msp430Interrupt,
- X86Interrupt,
- AmdGpuKernel,
- EfiApi,
- AvrInterrupt,
- AvrNonBlockingInterrupt,
- CCmseNonSecureCall,
- Wasm,
- System { unwind: bool },
- RustIntrinsic,
- RustCall,
- PlatformIntrinsic,
- Unadjusted,
- RustCold,
- RiscvInterruptM,
- RiscvInterruptS,
-}
-
-#[derive(Clone, Debug)]
-pub struct Binder<T> {
- pub value: T,
- pub bound_vars: Vec<BoundVariableKind>,
-}
-
-#[derive(Clone, Debug)]
-pub struct EarlyBinder<T> {
- pub value: T,
-}
-
-#[derive(Clone, Debug)]
-pub enum BoundVariableKind {
- Ty(BoundTyKind),
- Region(BoundRegionKind),
- Const,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub enum BoundTyKind {
- Anon,
- Param(ParamDef, String),
-}
-
-#[derive(Clone, Debug)]
-pub enum BoundRegionKind {
- BrAnon(Option<Span>),
- BrNamed(BrNamedDef, String),
- BrEnv,
-}
-
-#[derive(Clone, Debug)]
-pub enum DynKind {
- Dyn,
- DynStar,
-}
-
-#[derive(Clone, Debug)]
-pub enum ExistentialPredicate {
- Trait(ExistentialTraitRef),
- Projection(ExistentialProjection),
- AutoTrait(TraitDef),
-}
-
-#[derive(Clone, Debug)]
-pub struct ExistentialTraitRef {
- pub def_id: TraitDef,
- pub generic_args: GenericArgs,
-}
-
-#[derive(Clone, Debug)]
-pub struct ExistentialProjection {
- pub def_id: TraitDef,
- pub generic_args: GenericArgs,
- pub term: TermKind,
-}
-
-#[derive(Clone, Debug)]
-pub struct ParamTy {
- pub index: u32,
- pub name: String,
-}
-
-#[derive(Clone, Debug)]
-pub struct BoundTy {
- pub var: usize,
- pub kind: BoundTyKind,
-}
-
-pub type Bytes = Vec<Option<u8>>;
-pub type Size = usize;
-pub type Prov = Opaque;
-pub type Align = u64;
-pub type Promoted = u32;
-pub type InitMaskMaterialized = Vec<u64>;
-
-/// Stores the provenance information of pointers stored in memory.
-#[derive(Clone, Debug)]
-pub struct ProvenanceMap {
- /// Provenance in this map applies from the given offset for an entire pointer-size worth of
- /// bytes. Two entries in this map are always at least a pointer size apart.
- pub ptrs: Vec<(Size, Prov)>,
-}
-
-#[derive(Clone, Debug)]
-pub struct Allocation {
- pub bytes: Bytes,
- pub provenance: ProvenanceMap,
- pub align: Align,
- pub mutability: Mutability,
-}
-
-impl Allocation {
- /// Creates new empty `Allocation` from given `Align`.
- fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
- Allocation {
- bytes: Vec::new(),
- provenance: ProvenanceMap { ptrs: Vec::new() },
- align: align.bytes(),
- mutability: Mutability::Not,
- }
- }
-}
-
-// We need this method instead of a Stable implementation
-// because we need to get `Ty` of the const we are trying to create, to do that
-// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
-pub fn new_allocation<'tcx>(
- const_kind: &rustc_middle::mir::ConstantKind<'tcx>,
- const_value: ConstValue<'tcx>,
- tables: &mut Tables<'tcx>,
-) -> Allocation {
- match const_value {
- ConstValue::Scalar(scalar) => {
- let size = scalar.size();
- let align = tables
- .tcx
- .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
- .unwrap()
- .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();
- allocation.stable(tables)
- }
- ConstValue::ZeroSized => {
- let align = tables
- .tcx
- .layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty()))
- .unwrap()
- .align;
- Allocation::new_empty_allocation(align.abi)
- }
- ConstValue::Slice { data, start, end } => {
- let alloc_id = tables.tcx.create_memory_alloc(data);
- let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start));
- let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
- let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize(
- (end - start) as u64,
- &tables.tcx,
- );
- let layout = tables
- .tcx
- .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
- .unwrap();
- let mut allocation =
- rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
- allocation
- .write_scalar(
- &tables.tcx,
- alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
- scalar_ptr,
- )
- .unwrap();
- allocation
- .write_scalar(
- &tables.tcx,
- alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()),
- scalar_len,
- )
- .unwrap();
- allocation.stable(tables)
- }
- ConstValue::ByRef { alloc, offset } => {
- let ty_size = tables
- .tcx
- .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
- .unwrap()
- .size;
- allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
- }
- }
-}
-
-/// Creates an `Allocation` only from information within the `AllocRange`.
-pub fn allocation_filter<'tcx>(
- alloc: &rustc_middle::mir::interpret::Allocation,
- alloc_range: AllocRange,
- tables: &mut Tables<'tcx>,
-) -> Allocation {
- let mut bytes: Vec<Option<u8>> = alloc
- .inspect_with_uninit_and_ptr_outside_interpreter(
- alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(),
- )
- .iter()
- .copied()
- .map(Some)
- .collect();
- for (i, b) in bytes.iter_mut().enumerate() {
- if !alloc
- .init_mask()
- .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize()))
- {
- *b = None;
- }
- }
- let mut ptrs = Vec::new();
- for (offset, prov) in alloc
- .provenance()
- .ptrs()
- .iter()
- .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end())
- {
- ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov)));
- }
- Allocation {
- bytes: bytes,
- provenance: ProvenanceMap { ptrs },
- align: alloc.align.bytes(),
- mutability: alloc.mutability.stable(tables),
- }
-}
-
-#[derive(Clone, Debug)]
-pub enum ConstantKind {
- Allocated(Allocation),
- Unevaluated(UnevaluatedConst),
- ParamCt(Opaque),
-}
-
-#[derive(Clone, Debug)]
-pub struct UnevaluatedConst {
- pub ty: Ty,
- pub def: ConstDef,
- pub args: GenericArgs,
- pub promoted: Option<Promoted>,
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum TraitSpecializationKind {
- None,
- Marker,
- AlwaysApplicable,
-}
-
-#[derive(Clone, Debug)]
-pub struct TraitDecl {
- pub def_id: TraitDef,
- pub unsafety: Safety,
- pub paren_sugar: bool,
- pub has_auto_impl: bool,
- pub is_marker: bool,
- pub is_coinductive: bool,
- pub skip_array_during_method_dispatch: bool,
- pub specialization_kind: TraitSpecializationKind,
- pub must_implement_one_of: Option<Vec<Ident>>,
- pub implement_via_object: bool,
- pub deny_explicit_impl: bool,
-}
-
-pub type ImplTrait = EarlyBinder<TraitRef>;
-
-#[derive(Clone, Debug)]
-pub struct TraitRef {
- pub def_id: TraitDef,
- pub args: GenericArgs,
-}