Skip to content

Commit 879c7f9

Browse files
committed
add pretty_terminator
1 parent 16087ee commit 879c7f9

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
@@ -184,7 +184,7 @@ impl std::fmt::Display for Opaque {
184184

185185
impl std::fmt::Debug for Opaque {
186186
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
187-
write!(f, "{:?}", self.0)
187+
write!(f, "{}", self.0)
188188
}
189189
}
190190

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
@@ -3,6 +3,8 @@ use crate::mir::{Operand, Rvalue, StatementKind};
33
use crate::ty::{DynKind, FloatTy, IntTy, RigidTy, TyKind, UintTy};
44
use crate::{with, Body, CrateItem, Mutability};
55

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

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

0 commit comments

Comments
 (0)