diff options
Diffstat (limited to 'compiler/rustc_smir/src/rustc_smir/mod.rs')
-rw-r--r-- | compiler/rustc_smir/src/rustc_smir/mod.rs | 420 |
1 files changed, 241 insertions, 179 deletions
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 5572108f4..85d5bb00c 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,7 +7,9 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::stable_mir::{self, ty::TyKind, Context}; +use crate::stable_mir::ty::{FloatTy, IntTy, RigidTy, TyKind, UintTy}; +use crate::stable_mir::{self, Context}; +use rustc_middle::mir; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use tracing::debug; @@ -42,8 +44,8 @@ impl<'tcx> Context for Tables<'tcx> { .basic_blocks .iter() .map(|block| stable_mir::mir::BasicBlock { - terminator: rustc_terminator_to_terminator(block.terminator()), - statements: block.statements.iter().map(rustc_statement_to_statement).collect(), + terminator: block.terminator().stable(), + statements: block.statements.iter().map(mir::Statement::stable).collect(), }) .collect(), locals: mir.local_decls.iter().map(|decl| self.intern_ty(decl.ty)).collect(), @@ -68,11 +70,28 @@ pub struct Tables<'tcx> { 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::Bool => TyKind::RigidTy(RigidTy::Bool), + ty::Char => TyKind::RigidTy(RigidTy::Char), + ty::Int(int_ty) => match int_ty { + ty::IntTy::Isize => TyKind::RigidTy(RigidTy::Int(IntTy::Isize)), + ty::IntTy::I8 => TyKind::RigidTy(RigidTy::Int(IntTy::I8)), + ty::IntTy::I16 => TyKind::RigidTy(RigidTy::Int(IntTy::I16)), + ty::IntTy::I32 => TyKind::RigidTy(RigidTy::Int(IntTy::I32)), + ty::IntTy::I64 => TyKind::RigidTy(RigidTy::Int(IntTy::I64)), + ty::IntTy::I128 => TyKind::RigidTy(RigidTy::Int(IntTy::I128)), + }, + ty::Uint(uint_ty) => match uint_ty { + ty::UintTy::Usize => TyKind::RigidTy(RigidTy::Uint(UintTy::Usize)), + ty::UintTy::U8 => TyKind::RigidTy(RigidTy::Uint(UintTy::U8)), + ty::UintTy::U16 => TyKind::RigidTy(RigidTy::Uint(UintTy::U16)), + ty::UintTy::U32 => TyKind::RigidTy(RigidTy::Uint(UintTy::U32)), + ty::UintTy::U64 => TyKind::RigidTy(RigidTy::Uint(UintTy::U64)), + ty::UintTy::U128 => TyKind::RigidTy(RigidTy::Uint(UintTy::U128)), + }, + ty::Float(float_ty) => match float_ty { + ty::FloatTy::F32 => TyKind::RigidTy(RigidTy::Float(FloatTy::F32)), + ty::FloatTy::F64 => TyKind::RigidTy(RigidTy::Float(FloatTy::F64)), + }, ty::Adt(_, _) => todo!(), ty::Foreign(_) => todo!(), ty::Str => todo!(), @@ -89,9 +108,9 @@ impl<'tcx> Tables<'tcx> { ty::GeneratorWitness(_) => todo!(), ty::GeneratorWitnessMIR(_, _) => todo!(), ty::Never => todo!(), - ty::Tuple(fields) => { - TyKind::Tuple(fields.iter().map(|ty| self.intern_ty(ty)).collect()) - } + ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple( + fields.iter().map(|ty| self.intern_ty(ty)).collect(), + )), ty::Alias(_, _) => todo!(), ty::Param(_) => todo!(), ty::Bound(_, _) => todo!(), @@ -118,82 +137,95 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } } -fn rustc_statement_to_statement( - s: &rustc_middle::mir::Statement<'_>, -) -> stable_mir::mir::Statement { - use rustc_middle::mir::StatementKind::*; - match &s.kind { - Assign(assign) => stable_mir::mir::Statement::Assign( - rustc_place_to_place(&assign.0), - rustc_rvalue_to_rvalue(&assign.1), - ), - FakeRead(_) => todo!(), - SetDiscriminant { .. } => todo!(), - Deinit(_) => todo!(), - StorageLive(_) => todo!(), - StorageDead(_) => todo!(), - Retag(_, _) => todo!(), - PlaceMention(_) => todo!(), - AscribeUserType(_, _) => todo!(), - Coverage(_) => todo!(), - Intrinsic(_) => todo!(), - ConstEvalCounter => todo!(), - Nop => stable_mir::mir::Statement::Nop, +pub trait Stable { + type T; + fn stable(&self) -> Self::T; +} + +impl<'tcx> Stable for mir::Statement<'tcx> { + type T = stable_mir::mir::Statement; + fn stable(&self) -> Self::T { + use rustc_middle::mir::StatementKind::*; + match &self.kind { + Assign(assign) => { + stable_mir::mir::Statement::Assign(assign.0.stable(), assign.1.stable()) + } + FakeRead(_) => todo!(), + SetDiscriminant { .. } => todo!(), + Deinit(_) => todo!(), + StorageLive(_) => todo!(), + StorageDead(_) => todo!(), + Retag(_, _) => todo!(), + PlaceMention(_) => todo!(), + AscribeUserType(_, _) => todo!(), + Coverage(_) => todo!(), + Intrinsic(_) => todo!(), + ConstEvalCounter => todo!(), + Nop => stable_mir::mir::Statement::Nop, + } } } -fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Rvalue { - use rustc_middle::mir::Rvalue::*; - match rvalue { - Use(op) => stable_mir::mir::Rvalue::Use(rustc_op_to_op(op)), - Repeat(_, _) => todo!(), - Ref(_, _, _) => todo!(), - ThreadLocalRef(_) => todo!(), - AddressOf(_, _) => todo!(), - Len(_) => todo!(), - Cast(_, _, _) => todo!(), - BinaryOp(_, _) => todo!(), - CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( - rustc_bin_op_to_bin_op(bin_op), - rustc_op_to_op(&ops.0), - rustc_op_to_op(&ops.1), - ), - NullaryOp(_, _) => todo!(), - UnaryOp(un_op, op) => { - stable_mir::mir::Rvalue::UnaryOp(rustc_un_op_to_un_op(un_op), rustc_op_to_op(op)) +impl<'tcx> Stable for mir::Rvalue<'tcx> { + type T = stable_mir::mir::Rvalue; + fn stable(&self) -> Self::T { + use mir::Rvalue::*; + match self { + Use(op) => stable_mir::mir::Rvalue::Use(op.stable()), + Repeat(_, _) => todo!(), + Ref(_, _, _) => todo!(), + ThreadLocalRef(_) => todo!(), + AddressOf(_, _) => todo!(), + Len(_) => todo!(), + Cast(_, _, _) => todo!(), + BinaryOp(_, _) => todo!(), + CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( + bin_op.stable(), + ops.0.stable(), + ops.1.stable(), + ), + NullaryOp(_, _) => todo!(), + UnaryOp(un_op, op) => stable_mir::mir::Rvalue::UnaryOp(un_op.stable(), op.stable()), + Discriminant(_) => todo!(), + Aggregate(_, _) => todo!(), + ShallowInitBox(_, _) => todo!(), + CopyForDeref(_) => todo!(), } - Discriminant(_) => todo!(), - Aggregate(_, _) => todo!(), - ShallowInitBox(_, _) => todo!(), - CopyForDeref(_) => todo!(), } } -fn rustc_op_to_op(op: &rustc_middle::mir::Operand<'_>) -> stable_mir::mir::Operand { - use rustc_middle::mir::Operand::*; - match op { - Copy(place) => stable_mir::mir::Operand::Copy(rustc_place_to_place(place)), - Move(place) => stable_mir::mir::Operand::Move(rustc_place_to_place(place)), - Constant(c) => stable_mir::mir::Operand::Constant(c.to_string()), +impl<'tcx> Stable for mir::Operand<'tcx> { + type T = stable_mir::mir::Operand; + fn stable(&self) -> Self::T { + use mir::Operand::*; + match self { + Copy(place) => stable_mir::mir::Operand::Copy(place.stable()), + Move(place) => stable_mir::mir::Operand::Move(place.stable()), + Constant(c) => stable_mir::mir::Operand::Constant(c.to_string()), + } } } -fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir::Place { - stable_mir::mir::Place { - local: place.local.as_usize(), - projection: format!("{:?}", place.projection), +impl<'tcx> Stable for mir::Place<'tcx> { + type T = stable_mir::mir::Place; + fn stable(&self) -> Self::T { + stable_mir::mir::Place { + local: self.local.as_usize(), + projection: format!("{:?}", self.projection), + } } } -fn rustc_unwind_to_unwind( - unwind: &rustc_middle::mir::UnwindAction, -) -> stable_mir::mir::UnwindAction { - use rustc_middle::mir::UnwindAction; - match unwind { - UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, - UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, - UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate, - UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), +impl Stable for mir::UnwindAction { + type T = stable_mir::mir::UnwindAction; + fn stable(&self) -> Self::T { + use rustc_middle::mir::UnwindAction; + match self { + UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, + UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, + UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate, + UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), + } } } @@ -202,138 +234,168 @@ fn rustc_assert_msg_to_msg<'tcx>( ) -> stable_mir::mir::AssertMessage { use rustc_middle::mir::AssertKind; match assert_message { - AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck { - len: rustc_op_to_op(len), - index: rustc_op_to_op(index), - }, - AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow( - rustc_bin_op_to_bin_op(bin_op), - rustc_op_to_op(op1), - rustc_op_to_op(op2), - ), - AssertKind::OverflowNeg(op) => { - stable_mir::mir::AssertMessage::OverflowNeg(rustc_op_to_op(op)) + AssertKind::BoundsCheck { len, index } => { + stable_mir::mir::AssertMessage::BoundsCheck { len: len.stable(), index: index.stable() } + } + AssertKind::Overflow(bin_op, op1, op2) => { + stable_mir::mir::AssertMessage::Overflow(bin_op.stable(), op1.stable(), op2.stable()) } + AssertKind::OverflowNeg(op) => stable_mir::mir::AssertMessage::OverflowNeg(op.stable()), AssertKind::DivisionByZero(op) => { - stable_mir::mir::AssertMessage::DivisionByZero(rustc_op_to_op(op)) + stable_mir::mir::AssertMessage::DivisionByZero(op.stable()) } AssertKind::RemainderByZero(op) => { - stable_mir::mir::AssertMessage::RemainderByZero(rustc_op_to_op(op)) + stable_mir::mir::AssertMessage::RemainderByZero(op.stable()) } AssertKind::ResumedAfterReturn(generator) => { - stable_mir::mir::AssertMessage::ResumedAfterReturn(rustc_generator_to_generator( - generator, - )) + stable_mir::mir::AssertMessage::ResumedAfterReturn(generator.stable()) } AssertKind::ResumedAfterPanic(generator) => { - stable_mir::mir::AssertMessage::ResumedAfterPanic(rustc_generator_to_generator( - generator, - )) + stable_mir::mir::AssertMessage::ResumedAfterPanic(generator.stable()) } AssertKind::MisalignedPointerDereference { required, found } => { stable_mir::mir::AssertMessage::MisalignedPointerDereference { - required: rustc_op_to_op(required), - found: rustc_op_to_op(found), + required: required.stable(), + found: found.stable(), } } } } -fn rustc_bin_op_to_bin_op(bin_op: &rustc_middle::mir::BinOp) -> stable_mir::mir::BinOp { - use rustc_middle::mir::BinOp; - match bin_op { - BinOp::Add => stable_mir::mir::BinOp::Add, - BinOp::Sub => stable_mir::mir::BinOp::Sub, - BinOp::Mul => stable_mir::mir::BinOp::Mul, - BinOp::Div => stable_mir::mir::BinOp::Div, - BinOp::Rem => stable_mir::mir::BinOp::Rem, - BinOp::BitXor => stable_mir::mir::BinOp::BitXor, - BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, - BinOp::BitOr => stable_mir::mir::BinOp::BitOr, - BinOp::Shl => stable_mir::mir::BinOp::Shl, - BinOp::Shr => stable_mir::mir::BinOp::Shr, - BinOp::Eq => stable_mir::mir::BinOp::Eq, - BinOp::Lt => stable_mir::mir::BinOp::Lt, - BinOp::Le => stable_mir::mir::BinOp::Le, - BinOp::Ne => stable_mir::mir::BinOp::Ne, - BinOp::Ge => stable_mir::mir::BinOp::Ge, - BinOp::Gt => stable_mir::mir::BinOp::Gt, - BinOp::Offset => stable_mir::mir::BinOp::Offset, +impl Stable for mir::BinOp { + type T = stable_mir::mir::BinOp; + fn stable(&self) -> Self::T { + use mir::BinOp; + match self { + BinOp::Add => stable_mir::mir::BinOp::Add, + BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked, + BinOp::Sub => stable_mir::mir::BinOp::Sub, + BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked, + BinOp::Mul => stable_mir::mir::BinOp::Mul, + BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked, + BinOp::Div => stable_mir::mir::BinOp::Div, + BinOp::Rem => stable_mir::mir::BinOp::Rem, + BinOp::BitXor => stable_mir::mir::BinOp::BitXor, + BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, + BinOp::BitOr => stable_mir::mir::BinOp::BitOr, + BinOp::Shl => stable_mir::mir::BinOp::Shl, + BinOp::ShlUnchecked => stable_mir::mir::BinOp::ShlUnchecked, + BinOp::Shr => stable_mir::mir::BinOp::Shr, + BinOp::ShrUnchecked => stable_mir::mir::BinOp::ShrUnchecked, + BinOp::Eq => stable_mir::mir::BinOp::Eq, + BinOp::Lt => stable_mir::mir::BinOp::Lt, + BinOp::Le => stable_mir::mir::BinOp::Le, + BinOp::Ne => stable_mir::mir::BinOp::Ne, + BinOp::Ge => stable_mir::mir::BinOp::Ge, + BinOp::Gt => stable_mir::mir::BinOp::Gt, + BinOp::Offset => stable_mir::mir::BinOp::Offset, + } } } -fn rustc_un_op_to_un_op(unary_op: &rustc_middle::mir::UnOp) -> stable_mir::mir::UnOp { - use rustc_middle::mir::UnOp; - match unary_op { - UnOp::Not => stable_mir::mir::UnOp::Not, - UnOp::Neg => stable_mir::mir::UnOp::Neg, +impl Stable for mir::UnOp { + type T = stable_mir::mir::UnOp; + fn stable(&self) -> Self::T { + use mir::UnOp; + match self { + UnOp::Not => stable_mir::mir::UnOp::Not, + UnOp::Neg => stable_mir::mir::UnOp::Neg, + } } } -fn rustc_generator_to_generator( - generator: &rustc_hir::GeneratorKind, -) -> stable_mir::mir::GeneratorKind { - use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; - match generator { - GeneratorKind::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, - }; - stable_mir::mir::GeneratorKind::Async(async_gen) +impl Stable for rustc_hir::GeneratorKind { + type T = stable_mir::mir::GeneratorKind; + fn stable(&self) -> Self::T { + use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; + match self { + GeneratorKind::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, + }; + stable_mir::mir::GeneratorKind::Async(async_gen) + } + GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen, } - GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen, } } -fn rustc_terminator_to_terminator( - terminator: &rustc_middle::mir::Terminator<'_>, -) -> stable_mir::mir::Terminator { - use rustc_middle::mir::TerminatorKind::*; - use stable_mir::mir::Terminator; - match &terminator.kind { - Goto { target } => Terminator::Goto { target: target.as_usize() }, - SwitchInt { discr, targets } => Terminator::SwitchInt { - discr: rustc_op_to_op(discr), - targets: targets - .iter() - .map(|(value, target)| stable_mir::mir::SwitchTarget { - value, - target: target.as_usize(), - }) - .collect(), - otherwise: targets.otherwise().as_usize(), - }, - Resume => Terminator::Resume, - Terminate => Terminator::Abort, - Return => Terminator::Return, - Unreachable => Terminator::Unreachable, - Drop { place, target, unwind, replace: _ } => Terminator::Drop { - place: rustc_place_to_place(place), - target: target.as_usize(), - unwind: rustc_unwind_to_unwind(unwind), - }, - Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { - Terminator::Call { - func: rustc_op_to_op(func), - args: args.iter().map(|arg| rustc_op_to_op(arg)).collect(), - destination: rustc_place_to_place(destination), - target: target.map(|t| t.as_usize()), - unwind: rustc_unwind_to_unwind(unwind), +impl<'tcx> Stable for mir::InlineAsmOperand<'tcx> { + type T = stable_mir::mir::InlineAsmOperand; + fn stable(&self) -> Self::T { + use rustc_middle::mir::InlineAsmOperand; + + let (in_value, out_place) = match self { + InlineAsmOperand::In { value, .. } => (Some(value.stable()), None), + InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable())), + InlineAsmOperand::InOut { in_value, out_place, .. } => { + (Some(in_value.stable()), out_place.map(|place| place.stable())) + } + InlineAsmOperand::Const { .. } + | InlineAsmOperand::SymFn { .. } + | InlineAsmOperand::SymStatic { .. } => (None, None), + }; + + stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{:?}", self) } + } +} + +impl<'tcx> Stable for mir::Terminator<'tcx> { + type T = stable_mir::mir::Terminator; + fn stable(&self) -> Self::T { + use rustc_middle::mir::TerminatorKind::*; + use stable_mir::mir::Terminator; + match &self.kind { + Goto { target } => Terminator::Goto { target: target.as_usize() }, + SwitchInt { discr, targets } => Terminator::SwitchInt { + discr: discr.stable(), + targets: targets + .iter() + .map(|(value, target)| stable_mir::mir::SwitchTarget { + value, + target: target.as_usize(), + }) + .collect(), + otherwise: targets.otherwise().as_usize(), + }, + Resume => Terminator::Resume, + Terminate => Terminator::Abort, + Return => Terminator::Return, + Unreachable => Terminator::Unreachable, + Drop { place, target, unwind, replace: _ } => Terminator::Drop { + place: place.stable(), + target: target.as_usize(), + unwind: unwind.stable(), + }, + Call { func, args, destination, target, unwind, call_source: _, fn_span: _ } => { + Terminator::Call { + func: func.stable(), + args: args.iter().map(|arg| arg.stable()).collect(), + destination: destination.stable(), + target: target.map(|t| t.as_usize()), + unwind: unwind.stable(), + } + } + Assert { cond, expected, msg, target, unwind } => Terminator::Assert { + cond: cond.stable(), + expected: *expected, + msg: rustc_assert_msg_to_msg(msg), + target: target.as_usize(), + unwind: unwind.stable(), + }, + InlineAsm { template, operands, options, line_spans, destination, unwind } => { + Terminator::InlineAsm { + template: format!("{:?}", template), + operands: operands.iter().map(|operand| operand.stable()).collect(), + options: format!("{:?}", options), + line_spans: format!("{:?}", line_spans), + destination: destination.map(|d| d.as_usize()), + unwind: unwind.stable(), + } } + Yield { .. } | GeneratorDrop | FalseEdge { .. } | FalseUnwind { .. } => unreachable!(), } - Assert { cond, expected, msg, target, unwind } => Terminator::Assert { - cond: rustc_op_to_op(cond), - expected: *expected, - msg: rustc_assert_msg_to_msg(msg), - target: target.as_usize(), - unwind: rustc_unwind_to_unwind(unwind), - }, - Yield { .. } => todo!(), - GeneratorDrop => Terminator::GeneratorDrop, - FalseEdge { .. } => todo!(), - FalseUnwind { .. } => todo!(), - InlineAsm { .. } => todo!(), } } |