]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
Rollup merge of #104952 - jyn514:setup, r=Mark-Simulacrum
[rust.git] / compiler / rustc_mir_build / src / build / custom / parse / instruction.rs
1 use rustc_middle::mir::interpret::{ConstValue, Scalar};
2 use rustc_middle::{mir::*, thir::*, ty};
3
4 use super::{parse_by_kind, PResult, ParseCtxt};
5
6 impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
7     pub fn parse_statement(&self, expr_id: ExprId) -> PResult<StatementKind<'tcx>> {
8         parse_by_kind!(self, expr_id, _, "statement",
9             @call("mir_retag", args) => {
10                 Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
11             },
12             @call("mir_retag_raw", args) => {
13                 Ok(StatementKind::Retag(RetagKind::Raw, Box::new(self.parse_place(args[0])?)))
14             },
15             ExprKind::Assign { lhs, rhs } => {
16                 let lhs = self.parse_place(*lhs)?;
17                 let rhs = self.parse_rvalue(*rhs)?;
18                 Ok(StatementKind::Assign(Box::new((lhs, rhs))))
19             },
20         )
21     }
22
23     pub fn parse_terminator(&self, expr_id: ExprId) -> PResult<TerminatorKind<'tcx>> {
24         parse_by_kind!(self, expr_id, _, "terminator",
25             @call("mir_return", _args) => {
26                 Ok(TerminatorKind::Return)
27             },
28             @call("mir_goto", args) => {
29                 Ok(TerminatorKind::Goto { target: self.parse_block(args[0])? } )
30             },
31         )
32     }
33
34     fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
35         parse_by_kind!(self, expr_id, _, "rvalue",
36             ExprKind::Borrow { borrow_kind, arg } => Ok(
37                 Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
38             ),
39             ExprKind::AddressOf { mutability, arg } => Ok(
40                 Rvalue::AddressOf(*mutability, self.parse_place(*arg)?)
41             ),
42             _ => self.parse_operand(expr_id).map(Rvalue::Use),
43         )
44     }
45
46     fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
47         parse_by_kind!(self, expr_id, expr, "operand",
48             @call("mir_move", args) => self.parse_place(args[0]).map(Operand::Move),
49             @call("mir_static", args) => self.parse_static(args[0]),
50             @call("mir_static_mut", args) => self.parse_static(args[0]),
51             ExprKind::Literal { .. }
52             | ExprKind::NamedConst { .. }
53             | ExprKind::NonHirLiteral { .. }
54             | ExprKind::ZstLiteral { .. }
55             | ExprKind::ConstParam { .. }
56             | ExprKind::ConstBlock { .. } => {
57                 Ok(Operand::Constant(Box::new(
58                     crate::build::expr::as_constant::as_constant_inner(expr, |_| None, self.tcx)
59                 )))
60             },
61             _ => self.parse_place(expr_id).map(Operand::Copy),
62         )
63     }
64
65     fn parse_place(&self, expr_id: ExprId) -> PResult<Place<'tcx>> {
66         parse_by_kind!(self, expr_id, _, "place",
67             ExprKind::Deref { arg } => Ok(
68                 self.parse_place(*arg)?.project_deeper(&[PlaceElem::Deref], self.tcx)
69             ),
70             _ => self.parse_local(expr_id).map(Place::from),
71         )
72     }
73
74     fn parse_local(&self, expr_id: ExprId) -> PResult<Local> {
75         parse_by_kind!(self, expr_id, _, "local",
76             ExprKind::VarRef { id } => Ok(self.local_map[id]),
77         )
78     }
79
80     fn parse_block(&self, expr_id: ExprId) -> PResult<BasicBlock> {
81         parse_by_kind!(self, expr_id, _, "basic block",
82             ExprKind::VarRef { id } => Ok(self.block_map[id]),
83         )
84     }
85
86     fn parse_static(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
87         let expr_id = parse_by_kind!(self, expr_id, _, "static",
88             ExprKind::Deref { arg } => *arg,
89         );
90
91         parse_by_kind!(self, expr_id, expr, "static",
92             ExprKind::StaticRef { alloc_id, ty, .. } => {
93                 let const_val =
94                     ConstValue::Scalar(Scalar::from_pointer((*alloc_id).into(), &self.tcx));
95                 let literal = ConstantKind::Val(const_val, *ty);
96
97                 Ok(Operand::Constant(Box::new(Constant {
98                     span: expr.span,
99                     user_ty: None,
100                     literal
101                 })))
102             },
103         )
104     }
105 }