Skip to content

Commit 8b971ee

Browse files
committed
add pretty_terminator
1 parent cc4bb0d commit 8b971ee

File tree

3 files changed

+134
-2
lines changed

3 files changed

+134
-2
lines changed

compiler/stable_mir/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ impl std::fmt::Display for Opaque {
332332

333333
impl std::fmt::Debug for Opaque {
334334
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
335-
write!(f, "{:?}", self.0)
335+
write!(f, "{}", self.0)
336336
}
337337
}
338338

compiler/stable_mir/src/mir/body.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::mir::pretty::{function_body, pretty_statement};
1+
use crate::mir::pretty::{function_body, pretty_statement, pretty_terminator};
22
use crate::ty::{
33
AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
44
};
@@ -83,6 +83,7 @@ impl Body {
8383
Ok(())
8484
})
8585
.collect::<Vec<_>>();
86+
writeln!(w, "{}", pretty_terminator(&block.terminator.kind))?;
8687
writeln!(w, " }}").unwrap();
8788
Ok(())
8889
})

compiler/stable_mir/src/mir/pretty.rs

+131
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use crate::mir::{Operand, Rvalue, StatementKind};
22
use crate::ty::{DynKind, FloatTy, IntTy, RigidTy, TyKind, UintTy};
33
use crate::{with, Body, CrateItem, Mutability};
44

5+
use super::{AssertMessage, BinOp, TerminatorKind};
6+
57
pub fn function_name(item: CrateItem) -> String {
68
let mut pretty_name = String::new();
79
let body = item.body();
@@ -69,6 +71,135 @@ pub fn pretty_statement(statement: &StatementKind) -> String {
6971
pretty
7072
}
7173

74+
pub fn pretty_terminator(terminator: &TerminatorKind) -> String {
75+
let mut pretty = String::new();
76+
match terminator {
77+
TerminatorKind::Goto { .. } => format!(" goto"),
78+
TerminatorKind::SwitchInt { discr, .. } => {
79+
format!(" switch({})", pretty_operand(discr))
80+
}
81+
TerminatorKind::Resume => format!(" resume"),
82+
TerminatorKind::Abort => format!(" abort"),
83+
TerminatorKind::Return => format!(" return"),
84+
TerminatorKind::Unreachable => format!(" unreachable"),
85+
TerminatorKind::Drop { place, .. } => format!(" drop({:?})", place.local),
86+
TerminatorKind::Call { func, args, destination, .. } => {
87+
pretty.push_str(" ");
88+
pretty.push_str(format!("{} = ", destination.local).as_str());
89+
pretty.push_str(&pretty_operand(func));
90+
pretty.push_str("(");
91+
args.iter().enumerate().for_each(|(i, arg)| {
92+
if i > 0 {
93+
pretty.push_str(", ");
94+
}
95+
pretty.push_str(&pretty_operand(arg));
96+
});
97+
pretty.push_str(")");
98+
pretty
99+
}
100+
TerminatorKind::Assert { cond, expected, msg, target: _, unwind: _ } => {
101+
pretty.push_str(" assert(");
102+
if !expected {
103+
pretty.push_str("!");
104+
}
105+
pretty.push_str(&pretty_operand(cond));
106+
pretty.push_str(&pretty_assert_message(msg));
107+
pretty.push_str(")");
108+
pretty
109+
}
110+
TerminatorKind::CoroutineDrop => format!(" coroutine_drop"),
111+
TerminatorKind::InlineAsm { .. } => todo!(),
112+
}
113+
}
114+
115+
pub fn pretty_assert_message(msg: &AssertMessage) -> String {
116+
let mut pretty = String::new();
117+
match msg {
118+
AssertMessage::BoundsCheck { len, index } => {
119+
let pretty_len = pretty_operand(len);
120+
let pretty_index = pretty_operand(index);
121+
pretty.push_str(format!("\"index out of bounds: the length is {{}} but the index is {{}}\", {pretty_len}, {pretty_index}").as_str());
122+
pretty
123+
}
124+
AssertMessage::Overflow(BinOp::Add, l, r) => {
125+
let pretty_l = pretty_operand(l);
126+
let pretty_r = pretty_operand(r);
127+
pretty.push_str(format!("\"attempt to compute `{{}} + {{}}`, which would overflow\", {pretty_l}, {pretty_r}").as_str());
128+
pretty
129+
}
130+
AssertMessage::Overflow(BinOp::Sub, l, r) => {
131+
let pretty_l = pretty_operand(l);
132+
let pretty_r = pretty_operand(r);
133+
pretty.push_str(format!("\"attempt to compute `{{}} - {{}}`, which would overflow\", {pretty_l}, {pretty_r}").as_str());
134+
pretty
135+
}
136+
AssertMessage::Overflow(BinOp::Mul, l, r) => {
137+
let pretty_l = pretty_operand(l);
138+
let pretty_r = pretty_operand(r);
139+
pretty.push_str(format!("\"attempt to compute `{{}} * {{}}`, which would overflow\", {pretty_l}, {pretty_r}").as_str());
140+
pretty
141+
}
142+
AssertMessage::Overflow(BinOp::Div, l, r) => {
143+
let pretty_l = pretty_operand(l);
144+
let pretty_r = pretty_operand(r);
145+
pretty.push_str(format!("\"attempt to compute `{{}} / {{}}`, which would overflow\", {pretty_l}, {pretty_r}").as_str());
146+
pretty
147+
}
148+
AssertMessage::Overflow(BinOp::Rem, l, r) => {
149+
let pretty_l = pretty_operand(l);
150+
let pretty_r = pretty_operand(r);
151+
pretty.push_str(format!("\"attempt to compute `{{}} % {{}}`, which would overflow\", {pretty_l}, {pretty_r}").as_str());
152+
pretty
153+
}
154+
AssertMessage::Overflow(BinOp::Shr, _, r) => {
155+
let pretty_r = pretty_operand(r);
156+
pretty.push_str(
157+
format!("\"attempt to shift right by `{{}}`, which would overflow\", {pretty_r}")
158+
.as_str(),
159+
);
160+
pretty
161+
}
162+
AssertMessage::Overflow(BinOp::Shl, _, r) => {
163+
let pretty_r = pretty_operand(r);
164+
pretty.push_str(
165+
format!("\"attempt to shift left by `{{}}`, which would overflow\", {pretty_r}")
166+
.as_str(),
167+
);
168+
pretty
169+
}
170+
AssertMessage::OverflowNeg(op) => {
171+
let pretty_op = pretty_operand(op);
172+
pretty.push_str(
173+
format!("\"attempt to negate `{{}}`, which would overflow\", {pretty_op}").as_str(),
174+
);
175+
pretty
176+
}
177+
AssertMessage::DivisionByZero(op) => {
178+
let pretty_op = pretty_operand(op);
179+
pretty.push_str(format!("\"attempt to divide `{{}}` by zero\", {pretty_op}").as_str());
180+
pretty
181+
}
182+
AssertMessage::RemainderByZero(op) => {
183+
let pretty_op = pretty_operand(op);
184+
pretty.push_str(
185+
format!("\"attempt to calculate the remainder of `{{}}` with a divisor of zero\", {pretty_op}").as_str(),
186+
);
187+
pretty
188+
}
189+
AssertMessage::ResumedAfterReturn(_) => {
190+
format!("attempt to resume a generator after completion")
191+
}
192+
AssertMessage::ResumedAfterPanic(_) => format!("attempt to resume a panicked generator"),
193+
AssertMessage::MisalignedPointerDereference { required, found } => {
194+
let pretty_required = pretty_operand(required);
195+
let pretty_found = pretty_operand(found);
196+
pretty.push_str(format!("\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}").as_str());
197+
pretty
198+
}
199+
_ => todo!(),
200+
}
201+
}
202+
72203
pub fn pretty_operand(operand: &Operand) -> String {
73204
let mut pretty = String::new();
74205
match operand {

0 commit comments

Comments
 (0)