1+ //! Implement methods to pretty print stable MIR body.
12use std::fmt::Debug;
23use std::io::Write;
34use std::{fmt, io, iter};
45
56use fmt::{Display, Formatter};
67
7- use super :: { AssertMessage , BinOp , BorrowKind , FakeBorrowKind , TerminatorKind } ;
8+ use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
89use crate::mir::{Operand, Place, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents};
9- use crate :: ty:: { IndexedVal , MirConst , Ty , TyConst } ;
10- use crate :: { Body , Mutability , with} ;
10+ use crate::ty::{AdtKind, IndexedVal, MirConst, Ty, TyConst};
11+ use crate::{Body, CrateDef, Mutability, with};
1112
1213impl Display for Ty {
1314 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -23,10 +24,11 @@ impl Debug for Place {
2324
2425pub(crate) fn function_body<W: Write>(writer: &mut W, body: &Body, name: &str) -> io::Result<()> {
2526 write!(writer, "fn {name}(")?;
26- body. arg_locals ( )
27- . iter ( )
28- . enumerate ( )
29- . try_for_each ( |( index, local) | write ! ( writer, "_{}: {}" , index + 1 , local. ty) ) ?;
27+ let mut sep = "";
28+ for (index, local) in body.arg_locals().iter().enumerate() {
29+ write!(writer, "{}_{}: {}", sep, index + 1, local.ty)?;
30+ sep = ", ";
31+ }
3032 write!(writer, ")")?;
3133
3234 let return_local = body.ret_local();
@@ -73,39 +75,40 @@ pub(crate) fn function_body<W: Write>(writer: &mut W, body: &Body, name: &str) -
7375}
7476
7577fn pretty_statement<W: Write>(writer: &mut W, statement: &StatementKind) -> io::Result<()> {
78+ const INDENT: &str = " ";
7679 match statement {
7780 StatementKind::Assign(place, rval) => {
78- write ! ( writer, " {place:?} = " ) ?;
81+ write!(writer, "{INDENT} {place:?} = ")?;
7982 pretty_rvalue(writer, rval)?;
8083 writeln!(writer, ";")
8184 }
8285 // FIXME: Add rest of the statements
8386 StatementKind::FakeRead(cause, place) => {
84- writeln ! ( writer, "FakeRead({cause:?}, {place:?});" )
87+ writeln!(writer, "{INDENT} FakeRead({cause:?}, {place:?});")
8588 }
8689 StatementKind::SetDiscriminant { place, variant_index } => {
87- writeln ! ( writer, "discriminant({place:?} = {};" , variant_index. to_index( ) )
90+ writeln!(writer, "{INDENT} discriminant({place:?} = {};", variant_index.to_index())
8891 }
8992 StatementKind::Deinit(place) => writeln!(writer, "Deinit({place:?};"),
9093 StatementKind::StorageLive(local) => {
91- writeln ! ( writer, "StorageLive(_{local});" )
94+ writeln!(writer, "{INDENT} StorageLive(_{local});")
9295 }
9396 StatementKind::StorageDead(local) => {
94- writeln ! ( writer, "StorageDead(_{local});" )
97+ writeln!(writer, "{INDENT} StorageDead(_{local});")
9598 }
9699 StatementKind::Retag(kind, place) => writeln!(writer, "Retag({kind:?}, {place:?});"),
97100 StatementKind::PlaceMention(place) => {
98- writeln ! ( writer, "PlaceMention({place:?};" )
101+ writeln!(writer, "{INDENT} PlaceMention({place:?};")
99102 }
100103 StatementKind::ConstEvalCounter => {
101- writeln ! ( writer, "ConstEvalCounter;" )
104+ writeln!(writer, "{INDENT} ConstEvalCounter;")
102105 }
103- StatementKind :: Nop => writeln ! ( writer, "nop;" ) ,
106+ StatementKind::Nop => writeln!(writer, "{INDENT} nop;"),
104107 StatementKind::AscribeUserType { .. }
105108 | StatementKind::Coverage(_)
106109 | StatementKind::Intrinsic(_) => {
107110 // FIX-ME: Make them pretty.
108- writeln ! ( writer, "{statement:?};" )
111+ writeln!(writer, "{INDENT}{ statement:?};")
109112 }
110113 }
111114}
@@ -322,15 +325,11 @@ fn pretty_ty_const(ct: &TyConst) -> String {
322325fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
323326 match rval {
324327 Rvalue::AddressOf(mutability, place) => {
325- write ! ( writer, "&raw {}(* {:?}) " , pretty_mut( * mutability) , place)
328+ write!(writer, "&raw {} {:?}", pretty_mut(*mutability), place)
326329 }
327330 Rvalue::Aggregate(aggregate_kind, operands) => {
328331 // FIXME: Add pretty_aggregate function that returns a pretty string
329- write ! ( writer, "{aggregate_kind:?} (" ) ?;
330- let mut op_iter = operands. iter ( ) ;
331- op_iter. next ( ) . map_or ( Ok ( ( ) ) , |op| write ! ( writer, "{}" , pretty_operand( op) ) ) ?;
332- op_iter. try_for_each ( |op| write ! ( writer, ", {}" , pretty_operand( op) ) ) ?;
333- write ! ( writer, ")" )
332+ pretty_aggregate(writer, aggregate_kind, operands)
334333 }
335334 Rvalue::BinaryOp(bin, op1, op2) => {
336335 write!(writer, "{:?}({}, {})", bin, pretty_operand(op1), pretty_operand(op2))
@@ -360,22 +359,74 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
360359 write!(writer, "{kind}{place:?}")
361360 }
362361 Rvalue::Repeat(op, cnst) => {
363- write ! ( writer, "{} \" \" {} " , pretty_operand( op) , pretty_ty_const( cnst) )
362+ write!(writer, "[{}; {}] ", pretty_operand(op), pretty_ty_const(cnst))
364363 }
365364 Rvalue::ShallowInitBox(_, _) => Ok(()),
366365 Rvalue::ThreadLocalRef(item) => {
367366 write!(writer, "thread_local_ref{item:?}")
368367 }
369368 Rvalue::NullaryOp(nul, ty) => {
370- write ! ( writer, "{nul:?} {ty} \" \" " )
369+ write!(writer, "{nul:?}::< {ty}>() \" \"")
371370 }
372371 Rvalue::UnaryOp(un, op) => {
373- write ! ( writer, "{} \" \" { :?}" , pretty_operand( op) , un )
372+ write!(writer, "{:?}({}) ", un, pretty_operand(op))
374373 }
375374 Rvalue::Use(op) => write!(writer, "{}", pretty_operand(op)),
376375 }
377376}
378377
378+ fn pretty_aggregate<W: Write>(
379+ writer: &mut W,
380+ aggregate_kind: &AggregateKind,
381+ operands: &Vec<Operand>,
382+ ) -> io::Result<()> {
383+ let suffix = match aggregate_kind {
384+ AggregateKind::Array(_) => {
385+ write!(writer, "[")?;
386+ "]"
387+ }
388+ AggregateKind::Tuple => {
389+ write!(writer, "(")?;
390+ ")"
391+ }
392+ AggregateKind::Adt(def, var, _, _, _) => {
393+ if def.kind() == AdtKind::Enum {
394+ write!(writer, "{}::{}", def.name(), def.variant(*var).unwrap().name())?;
395+ } else {
396+ write!(writer, "{}", def.variant(*var).unwrap().name())?;
397+ }
398+ if operands.is_empty() {
399+ return Ok(());
400+ }
401+ // FIXME: Change this once we have CtorKind in StableMIR.
402+ write!(writer, "(")?;
403+ ")"
404+ }
405+ AggregateKind::Closure(def, _) => {
406+ write!(writer, "{{closure@{}}}(", def.span().diagnostic())?;
407+ ")"
408+ }
409+ AggregateKind::Coroutine(def, _, _) => {
410+ write!(writer, "{{coroutine@{}}}(", def.span().diagnostic())?;
411+ ")"
412+ }
413+ AggregateKind::RawPtr(ty, mutability) => {
414+ write!(
415+ writer,
416+ "*{} {ty} from (",
417+ if *mutability == Mutability::Mut { "mut" } else { "const" }
418+ )?;
419+ ")"
420+ }
421+ };
422+ let mut separator = "";
423+ for op in operands {
424+ write!(writer, "{}{}", separator, pretty_operand(op))?;
425+ separator = ", ";
426+ }
427+ write!(writer, "{suffix}")
428+ }
429+
379430fn pretty_mut(mutability: Mutability) -> &'static str {
380431 match mutability {
381432 Mutability::Not => " ",
0 commit comments