1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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
})))
},
)
}
}
|