diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index e643ad28c03..609a04d263c 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -47,5 +47,5 @@ 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![] }, f); + crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f); } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 81ecce415d5..6af43f5d3f3 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,8 +7,8 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::stable_mir::{self, Context}; -use rustc_middle::ty::TyCtxt; +use crate::stable_mir::{self, ty::TyKind, Context}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use tracing::debug; @@ -34,7 +34,7 @@ impl<'tcx> Context for Tables<'tcx> { fn entry_fn(&mut self) -> Option { Some(self.crate_item(self.tcx.entry_fn(())?.0)) } - fn mir_body(&self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body { + 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); stable_mir::mir::Body { @@ -46,17 +46,68 @@ impl<'tcx> Context for Tables<'tcx> { statements: block.statements.iter().map(rustc_statement_to_statement).collect(), }) .collect(), + locals: mir.local_decls.iter().map(|decl| self.intern_ty(decl.ty)).collect(), } } fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) { f(self) } + + fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind { + self.rustc_ty_to_ty(self.types[ty.0]) + } } pub struct Tables<'tcx> { pub tcx: TyCtxt<'tcx>, pub def_ids: Vec, + pub types: Vec>, +} + +impl<'tcx> Tables<'tcx> { + fn rustc_ty_to_ty(&mut self, ty: Ty<'tcx>) -> TyKind { + match ty.kind() { + ty::Bool => TyKind::Bool, + ty::Char => todo!(), + ty::Int(_) => todo!(), + ty::Uint(_) => todo!(), + ty::Float(_) => todo!(), + ty::Adt(_, _) => todo!(), + ty::Foreign(_) => todo!(), + ty::Str => todo!(), + ty::Array(_, _) => todo!(), + ty::Slice(_) => todo!(), + ty::RawPtr(_) => todo!(), + ty::Ref(_, _, _) => todo!(), + ty::FnDef(_, _) => todo!(), + ty::FnPtr(_) => todo!(), + ty::Placeholder(..) => todo!(), + ty::Dynamic(_, _, _) => todo!(), + ty::Closure(_, _) => todo!(), + ty::Generator(_, _, _) => todo!(), + ty::GeneratorWitness(_) => todo!(), + ty::GeneratorWitnessMIR(_, _) => todo!(), + ty::Never => todo!(), + ty::Tuple(fields) => { + TyKind::Tuple(fields.iter().map(|ty| self.intern_ty(ty)).collect()) + } + ty::Alias(_, _) => todo!(), + ty::Param(_) => todo!(), + ty::Bound(_, _) => todo!(), + ty::Infer(_) => todo!(), + ty::Error(_) => todo!(), + } + } + + fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::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); + stable_mir::ty::Ty(id) + } } /// Build a stable mir crate from a given crate number. diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 4baf3f1f75e..6328c35aa59 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -1,6 +1,9 @@ +use crate::stable_mir::ty::Ty; + #[derive(Clone, Debug)] pub struct Body { pub blocks: Vec, + pub locals: Vec, } #[derive(Clone, Debug)] diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs new file mode 100644 index 00000000000..f27801b0f6c --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -0,0 +1,15 @@ +use super::with; + +#[derive(Copy, Clone, Debug)] +pub struct Ty(pub usize); + +impl Ty { + pub fn kind(&self) -> TyKind { + with(|context| context.ty_kind(*self)) + } +} + +pub enum TyKind { + Bool, + Tuple(Vec), +} diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index b0fcc36b0a8..a3db2e9ef24 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -40,6 +40,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap(); let body = bar.body(); + assert_eq!(body.locals.len(), 2); assert_eq!(body.blocks.len(), 1); let block = &body.blocks[0]; assert_eq!(block.statements.len(), 1); @@ -54,6 +55,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap(); let body = foo_bar.body(); + assert_eq!(body.locals.len(), 7); assert_eq!(body.blocks.len(), 4); let block = &body.blocks[0]; match &block.terminator {