diff options
Diffstat (limited to 'compiler/rustc_smir')
| -rw-r--r-- | compiler/rustc_smir/Cargo.toml | 6 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/lib.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_internal/internal.rs | 61 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_internal/mod.rs | 232 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_smir/builder.rs | 55 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_smir/mod.rs | 228 |
6 files changed, 437 insertions, 152 deletions
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 4c29f743708..41c7d3a8594 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,14 +4,12 @@ version = "0.0.0" edition = "2021" [dependencies] +rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } rustc_middle = { path = "../rustc_middle" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -rustc_driver = { path = "../rustc_driver" } -rustc_interface = { path = "../rustc_interface" } -rustc_session = {path = "../rustc_session" } -tracing = "0.1" stable_mir = {path = "../stable_mir" } +tracing = "0.1" [features] diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index b6c36678db5..c24b9efe865 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -10,10 +10,9 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] -#![feature(rustc_private)] -#![feature(ptr_metadata)] -#![feature(type_alias_impl_trait)] // Used to define opaque types. -#![feature(intra_doc_pointers)] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] pub mod rustc_internal; diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs new file mode 100644 index 00000000000..f42a9739320 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -0,0 +1,61 @@ +//! Module containing the translation from stable mir constructs to the rustc counterpart. +//! +//! This module will only include a few constructs to allow users to invoke internal rustc APIs +//! due to incomplete stable coverage. + +// Prefer importing stable_mir over internal rustc constructs to make this file more readable. +use crate::rustc_smir::{MaybeStable, Tables}; +use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy}; +use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty}; +use stable_mir::DefId; + +use super::RustcInternal; + +impl<'tcx> RustcInternal<'tcx> for DefId { + type T = rustc_span::def_id::DefId; + fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T { + tables.def_ids[*self] + } +} + +impl<'tcx> RustcInternal<'tcx> for GenericArgs { + type T = rustc_ty::GenericArgsRef<'tcx>; + fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T { + tables.tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables))) + } +} + +impl<'tcx> RustcInternal<'tcx> for GenericArgKind { + type T = rustc_ty::GenericArg<'tcx>; + fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + GenericArgKind::Lifetime(reg) => reg.internal(tables).into(), + GenericArgKind::Type(ty) => ty.internal(tables).into(), + GenericArgKind::Const(cnst) => cnst.internal(tables).into(), + } + } +} + +impl<'tcx> RustcInternal<'tcx> for Region { + type T = rustc_ty::Region<'tcx>; + fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T { + todo!() + } +} + +impl<'tcx> RustcInternal<'tcx> for Ty { + type T = InternalTy<'tcx>; + fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T { + match tables.types[self.0] { + MaybeStable::Stable(_) => todo!(), + MaybeStable::Rustc(ty) => ty, + } + } +} + +impl<'tcx> RustcInternal<'tcx> for Const { + type T = rustc_ty::Const<'tcx>; + fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T { + todo!() + } +} diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 1a9dea99f64..f7e519570fa 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,24 +3,27 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use std::ops::{ControlFlow, Index}; - -use crate::rustc_internal; use crate::rustc_smir::Tables; -use rustc_driver::{Callbacks, Compilation, RunCompiler}; -use rustc_interface::{interface, Queries}; +use rustc_data_structures::fx; +use rustc_data_structures::fx::FxIndexMap; use rustc_middle::mir::interpret::AllocId; +use rustc_middle::ty; use rustc_middle::ty::TyCtxt; -pub use rustc_span::def_id::{CrateNum, DefId}; +use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Span; -use stable_mir::CompilerError; +use stable_mir::ty::IndexedVal; +use std::fmt::Debug; +use std::hash::Hash; +use std::ops::Index; + +mod internal; impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> { type Output = DefId; #[inline(always)] fn index(&self, index: stable_mir::DefId) -> &Self::Output { - &self.def_ids[index.0] + &self.def_ids[index] } } @@ -29,7 +32,7 @@ impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> { #[inline(always)] fn index(&self, index: stable_mir::ty::Span) -> &Self::Output { - &self.spans[index.0] + &self.spans[index] } } @@ -54,8 +57,8 @@ impl<'tcx> Tables<'tcx> { stable_mir::ty::ClosureDef(self.create_def_id(did)) } - pub fn generator_def(&mut self, did: DefId) -> stable_mir::ty::GeneratorDef { - stable_mir::ty::GeneratorDef(self.create_def_id(did)) + pub fn coroutine_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineDef { + stable_mir::ty::CoroutineDef(self.create_def_id(did)) } pub fn alias_def(&mut self, did: DefId) -> stable_mir::ty::AliasDef { @@ -94,37 +97,27 @@ impl<'tcx> Tables<'tcx> { 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 stable_mir::DefId(i); - } - } - let id = self.def_ids.len(); - self.def_ids.push(did); - stable_mir::DefId(id) + pub(crate) fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId { + self.def_ids.create_or_fetch(did) } 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) + self.alloc_ids.create_or_fetch(aid) } 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) + self.spans.create_or_fetch(span) + } + + pub(crate) fn instance_def( + &mut self, + instance: ty::Instance<'tcx>, + ) -> stable_mir::mir::mono::InstanceDef { + self.instances.create_or_fetch(instance) + } + + pub(crate) fn static_def(&mut self, did: DefId) -> stable_mir::mir::mono::StaticDef { + stable_mir::mir::mono::StaticDef(self.create_def_id(did)) } } @@ -134,66 +127,131 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { stable_mir::run( - Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] }, + Tables { + tcx, + def_ids: IndexMap::default(), + alloc_ids: IndexMap::default(), + spans: IndexMap::default(), + types: vec![], + instances: IndexMap::default(), + }, 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>>, -} +#[macro_export] +macro_rules! run { + ($args:expr, $callback:expr) => { + run!($args, tcx, $callback) + }; + ($args:expr, $tcx:ident, $callback:expr) => {{ + use rustc_driver::{Callbacks, Compilation, RunCompiler}; + use rustc_interface::{interface, Queries}; + use stable_mir::CompilerError; + use std::ops::ControlFlow; -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), + 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), + } + } + } + + 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 + } + }) + } + } + + StableMir::new($args, |$tcx| $callback).run() + }}; +} + +/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra +/// safety features added. +pub struct IndexMap<K, V> { + index_map: fx::FxIndexMap<K, V>, +} + +impl<K, V> Default for IndexMap<K, V> { + fn default() -> Self { + Self { index_map: FxIndexMap::default() } } } -impl<B, C> Callbacks for StableMir<B, C> -where - B: Send, - C: Send, +impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> IndexMap<K, V> { + pub fn create_or_fetch(&mut self, key: K) -> V { + let len = self.index_map.len(); + let v = self.index_map.entry(key).or_insert(V::to_val(len)); + *v + } +} + +impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V> + for IndexMap<K, V> { - /// 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 - } - }) + type Output = K; + + fn index(&self, index: V) -> &Self::Output { + let (k, v) = self.index_map.get_index(index.to_index()).unwrap(); + assert_eq!(*v, index, "Provided value doesn't match with indexed value"); + k } } + +/// Trait used to translate a stable construct to its rustc counterpart. +/// +/// This is basically a mirror of [crate::rustc_smir::Stable]. +pub(crate) trait RustcInternal<'tcx> { + type T; + fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T; +} diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs new file mode 100644 index 00000000000..8ff3958da7b --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -0,0 +1,55 @@ +//! Logic required to produce a monomorphic stable body. +//! +//! We first retrieve and monomorphize the rustc body representation, i.e., we generate a +//! monomorphic body using internal representation. +//! After that, we convert the internal representation into a stable one. +use crate::rustc_smir::{Stable, Tables}; +use rustc_middle::mir; +use rustc_middle::mir::visit::MutVisitor; +use rustc_middle::ty::{self, Ty, TyCtxt}; + +/// Builds a monomorphic body for a given instance. +pub struct BodyBuilder<'tcx> { + tcx: TyCtxt<'tcx>, + instance: ty::Instance<'tcx>, +} + +impl<'tcx> BodyBuilder<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self { + BodyBuilder { tcx, instance } + } + + 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) { + self.visit_body(&mut body); + } + body.stable(tables) + } + + fn monomorphize<T>(&self, value: T) -> T + where + T: ty::TypeFoldable<TyCtxt<'tcx>>, + { + self.instance.instantiate_mir_and_normalize_erasing_regions( + self.tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value), + ) + } +} + +impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> { + fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, _location: mir::Location) { + *ct = self.monomorphize(*ct); + } + + fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: mir::visit::TyContext) { + *ty = self.monomorphize(*ty); + } + + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 7d1122c2fd2..d5379797f1c 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,20 +7,26 @@ //! //! 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_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; -use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; +use rustc_middle::mir::mono::MonoItem; +use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; -use stable_mir::mir::{CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx}; -use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy}; -use stable_mir::{self, opaque, Context}; +use stable_mir::mir::mono::InstanceDef; +use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx}; +use stable_mir::ty::{ + FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy, +}; +use stable_mir::{self, opaque, Context, Filename}; use tracing::debug; mod alloc; +mod builder; impl<'tcx> Context for Tables<'tcx> { fn local_crate(&self) -> stable_mir::Crate { @@ -31,21 +37,45 @@ impl<'tcx> Context for Tables<'tcx> { self.tcx.crates(()).iter().map(|crate_num| smir_crate(self.tcx, *crate_num)).collect() } - fn find_crate(&self, name: &str) -> Option<stable_mir::Crate> { - [LOCAL_CRATE].iter().chain(self.tcx.crates(()).iter()).find_map(|crate_num| { - let crate_name = self.tcx.crate_name(*crate_num).to_string(); - (name == crate_name).then(|| smir_crate(self.tcx, *crate_num)) - }) + fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> { + let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE] + .iter() + .chain(self.tcx.crates(()).iter()) + .map(|crate_num| { + let crate_name = self.tcx.crate_name(*crate_num).to_string(); + (name == crate_name).then(|| smir_crate(self.tcx, *crate_num)) + }) + .into_iter() + .filter_map(|c| c) + .collect(); + crates } 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 { + fn span_to_string(&self, span: stable_mir::ty::Span) -> String { self.tcx.sess.source_map().span_to_diagnostic_string(self[span]) } + fn get_filename(&self, span: &Span) -> Filename { + opaque( + &self + .tcx + .sess + .source_map() + .span_to_filename(self[*span]) + .display(rustc_span::FileNameDisplayPreference::Local) + .to_string(), + ) + } + + fn get_lines(&self, span: &Span) -> LineInfo { + let lines = &self.tcx.sess.source_map().span_to_location_info(self[*span]); + LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 } + } + fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind { self.tcx.def_kind(self[def_id]).stable(self) } @@ -92,29 +122,7 @@ impl<'tcx> Context for Tables<'tcx> { 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 - .iter() - .map(|block| stable_mir::mir::BasicBlock { - terminator: block.terminator().stable(self), - statements: block - .statements - .iter() - .map(|statement| statement.stable(self)) - .collect(), - }) - .collect(), - locals: mir - .local_decls - .iter() - .map(|decl| stable_mir::mir::LocalDecl { - ty: self.intern_ty(decl.ty), - span: decl.source_info.span.stable(self), - }) - .collect(), - } + self.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(self) } fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind { @@ -163,6 +171,47 @@ impl<'tcx> Context for Tables<'tcx> { .collect(), } } + + fn instance_body(&mut self, def: InstanceDef) -> Body { + let instance = self.instances[def]; + builder::BodyBuilder::new(self.tcx, instance).build(self) + } + + fn instance_ty(&mut self, def: InstanceDef) -> stable_mir::ty::Ty { + let instance = self.instances[def]; + let ty = instance.ty(self.tcx, ParamEnv::empty()); + self.intern_ty(ty) + } + + fn instance_def_id(&mut self, def: InstanceDef) -> stable_mir::DefId { + let def_id = self.instances[def].def_id(); + self.create_def_id(def_id) + } + + fn mono_instance(&mut self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance { + let def_id = self[item.0]; + Instance::mono(self.tcx, def_id).stable(self) + } + + fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool { + let def_id = self[def_id]; + let generics = self.tcx.generics_of(def_id); + let result = generics.requires_monomorphization(self.tcx); + result + } + + fn resolve_instance( + &mut self, + def: stable_mir::ty::FnDef, + args: &stable_mir::ty::GenericArgs, + ) -> Option<stable_mir::mir::mono::Instance> { + let def_id = def.0.internal(self); + let args_ref = args.internal(self); + match Instance::resolve(self.tcx, ParamEnv::reveal_all(), def_id, args_ref) { + Ok(Some(instance)) => Some(instance.stable(self)), + Ok(None) | Err(_) => None, + } + } } #[derive(Clone)] @@ -194,10 +243,11 @@ impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> { pub struct Tables<'tcx> { pub tcx: TyCtxt<'tcx>, - pub def_ids: Vec<DefId>, - pub alloc_ids: Vec<AllocId>, - pub spans: Vec<rustc_span::Span>, - pub types: Vec<MaybeStable<stable_mir::ty::TyKind, Ty<'tcx>>>, + pub def_ids: IndexMap<DefId, stable_mir::DefId>, + pub alloc_ids: IndexMap<AllocId, stable_mir::AllocId>, + pub spans: IndexMap<rustc_span::Span, Span>, + pub types: Vec<MaybeStable<TyKind, Ty<'tcx>>>, + pub instances: IndexMap<ty::Instance<'tcx>, InstanceDef>, } impl<'tcx> Tables<'tcx> { @@ -227,6 +277,35 @@ pub(crate) 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 { + blocks: 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(), + locals: self + .local_decls + .iter() + .map(|decl| stable_mir::mir::LocalDecl { + ty: tables.intern_ty(decl.ty), + span: decl.source_info.span.stable(tables), + }) + .collect(), + } + } +} + impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { type T = stable_mir::mir::Statement; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { @@ -703,11 +782,11 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { AssertKind::RemainderByZero(op) => { stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables)) } - AssertKind::ResumedAfterReturn(generator) => { - stable_mir::mir::AssertMessage::ResumedAfterReturn(generator.stable(tables)) + AssertKind::ResumedAfterReturn(coroutine) => { + stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables)) } - AssertKind::ResumedAfterPanic(generator) => { - stable_mir::mir::AssertMessage::ResumedAfterPanic(generator.stable(tables)) + AssertKind::ResumedAfterPanic(coroutine) => { + stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables)) } AssertKind::MisalignedPointerDereference { required, found } => { stable_mir::mir::AssertMessage::MisalignedPointerDereference { @@ -784,9 +863,9 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { generic_arg.stable(tables), ) } - mir::AggregateKind::Generator(def_id, generic_arg, movability) => { - stable_mir::mir::AggregateKind::Generator( - tables.generator_def(*def_id), + 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), ) @@ -795,20 +874,20 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { } } -impl<'tcx> Stable<'tcx> for rustc_hir::GeneratorKind { - type T = stable_mir::mir::GeneratorKind; +impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { + type T = stable_mir::mir::CoroutineKind; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; + use rustc_hir::{AsyncCoroutineKind, CoroutineKind}; match self { - GeneratorKind::Async(async_gen) => { + CoroutineKind::Async(async_gen) => { let async_gen = match async_gen { - AsyncGeneratorKind::Block => stable_mir::mir::AsyncGeneratorKind::Block, - AsyncGeneratorKind::Closure => stable_mir::mir::AsyncGeneratorKind::Closure, - AsyncGeneratorKind::Fn => stable_mir::mir::AsyncGeneratorKind::Fn, + AsyncCoroutineKind::Block => stable_mir::mir::AsyncCoroutineKind::Block, + AsyncCoroutineKind::Closure => stable_mir::mir::AsyncCoroutineKind::Closure, + AsyncCoroutineKind::Fn => stable_mir::mir::AsyncCoroutineKind::Fn, }; - stable_mir::mir::GeneratorKind::Async(async_gen) + stable_mir::mir::CoroutineKind::Async(async_gen) } - GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen, + CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine, } } } @@ -911,7 +990,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { unwind: unwind.stable(tables), }, mir::TerminatorKind::Yield { .. } - | mir::TerminatorKind::GeneratorDrop + | mir::TerminatorKind::CoroutineDrop | mir::TerminatorKind::FalseEdge { .. } | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(), } @@ -1166,8 +1245,8 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { tables.closure_def(*def_id), generic_args.stable(tables), )), - ty::Generator(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Generator( - tables.generator_def(*def_id), + ty::Coroutine(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Coroutine( + tables.coroutine_def(*def_id), generic_args.stable(tables), movability.stable(tables), )), @@ -1182,7 +1261,7 @@ 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::Infer(_) | ty::Error(_) => { + ty::Placeholder(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => { unreachable!(); } } @@ -1610,3 +1689,38 @@ impl<'tcx> Stable<'tcx> for DefKind { opaque(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(..) => 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 } + } +} + +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)), + } + } +} |
