summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src/build/custom/parse/instruction.rs')
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs105
1 files changed, 105 insertions, 0 deletions
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
new file mode 100644
index 000000000..03206af33
--- /dev/null
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -0,0 +1,105 @@
+use rustc_middle::mir::interpret::{ConstValue, Scalar};
+use rustc_middle::{mir::*, thir::*, ty};
+
+use super::{parse_by_kind, PResult, ParseCtxt};
+
+impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
+ pub fn parse_statement(&self, expr_id: ExprId) -> PResult<StatementKind<'tcx>> {
+ parse_by_kind!(self, expr_id, _, "statement",
+ @call("mir_retag", args) => {
+ Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
+ },
+ @call("mir_retag_raw", args) => {
+ Ok(StatementKind::Retag(RetagKind::Raw, Box::new(self.parse_place(args[0])?)))
+ },
+ ExprKind::Assign { lhs, rhs } => {
+ let lhs = self.parse_place(*lhs)?;
+ let rhs = self.parse_rvalue(*rhs)?;
+ Ok(StatementKind::Assign(Box::new((lhs, rhs))))
+ },
+ )
+ }
+
+ pub fn parse_terminator(&self, expr_id: ExprId) -> PResult<TerminatorKind<'tcx>> {
+ parse_by_kind!(self, expr_id, _, "terminator",
+ @call("mir_return", _args) => {
+ Ok(TerminatorKind::Return)
+ },
+ @call("mir_goto", args) => {
+ Ok(TerminatorKind::Goto { target: self.parse_block(args[0])? } )
+ },
+ )
+ }
+
+ fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
+ parse_by_kind!(self, expr_id, _, "rvalue",
+ ExprKind::Borrow { borrow_kind, arg } => Ok(
+ Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
+ ),
+ ExprKind::AddressOf { mutability, arg } => Ok(
+ Rvalue::AddressOf(*mutability, self.parse_place(*arg)?)
+ ),
+ _ => self.parse_operand(expr_id).map(Rvalue::Use),
+ )
+ }
+
+ fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
+ parse_by_kind!(self, expr_id, expr, "operand",
+ @call("mir_move", args) => self.parse_place(args[0]).map(Operand::Move),
+ @call("mir_static", args) => self.parse_static(args[0]),
+ @call("mir_static_mut", args) => self.parse_static(args[0]),
+ ExprKind::Literal { .. }
+ | ExprKind::NamedConst { .. }
+ | ExprKind::NonHirLiteral { .. }
+ | ExprKind::ZstLiteral { .. }
+ | ExprKind::ConstParam { .. }
+ | ExprKind::ConstBlock { .. } => {
+ Ok(Operand::Constant(Box::new(
+ crate::build::expr::as_constant::as_constant_inner(expr, |_| None, self.tcx)
+ )))
+ },
+ _ => self.parse_place(expr_id).map(Operand::Copy),
+ )
+ }
+
+ fn parse_place(&self, expr_id: ExprId) -> PResult<Place<'tcx>> {
+ parse_by_kind!(self, expr_id, _, "place",
+ ExprKind::Deref { arg } => Ok(
+ self.parse_place(*arg)?.project_deeper(&[PlaceElem::Deref], self.tcx)
+ ),
+ _ => self.parse_local(expr_id).map(Place::from),
+ )
+ }
+
+ fn parse_local(&self, expr_id: ExprId) -> PResult<Local> {
+ parse_by_kind!(self, expr_id, _, "local",
+ ExprKind::VarRef { id } => Ok(self.local_map[id]),
+ )
+ }
+
+ fn parse_block(&self, expr_id: ExprId) -> PResult<BasicBlock> {
+ parse_by_kind!(self, expr_id, _, "basic block",
+ ExprKind::VarRef { id } => Ok(self.block_map[id]),
+ )
+ }
+
+ fn parse_static(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
+ let expr_id = parse_by_kind!(self, expr_id, _, "static",
+ ExprKind::Deref { arg } => *arg,
+ );
+
+ parse_by_kind!(self, expr_id, expr, "static",
+ ExprKind::StaticRef { alloc_id, ty, .. } => {
+ let const_val =
+ ConstValue::Scalar(Scalar::from_pointer((*alloc_id).into(), &self.tcx));
+ let literal = ConstantKind::Val(const_val, *ty);
+
+ Ok(Operand::Constant(Box::new(Constant {
+ span: expr.span,
+ user_ty: None,
+ literal
+ })))
+ },
+ )
+ }
+}