|
| 1 | +//! Implement methods to pretty print stable MIR body. |
1 | 2 | use std::fmt::Debug;
|
2 | 3 | use std::io::Write;
|
3 | 4 | use std::{fmt, io, iter};
|
4 | 5 |
|
5 | 6 | use fmt::{Display, Formatter};
|
6 | 7 |
|
7 |
| -use super::{AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind}; |
| 8 | +use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind}; |
8 | 9 | use 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}; |
11 | 12 |
|
12 | 13 | impl Display for Ty {
|
13 | 14 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
@@ -73,39 +74,40 @@ pub(crate) fn function_body<W: Write>(writer: &mut W, body: &Body, name: &str) -
|
73 | 74 | }
|
74 | 75 |
|
75 | 76 | fn pretty_statement<W: Write>(writer: &mut W, statement: &StatementKind) -> io::Result<()> {
|
| 77 | + const INDENT: &str = " "; |
76 | 78 | match statement {
|
77 | 79 | StatementKind::Assign(place, rval) => {
|
78 |
| - write!(writer, " {place:?} = ")?; |
| 80 | + write!(writer, "{INDENT}{place:?} = ")?; |
79 | 81 | pretty_rvalue(writer, rval)?;
|
80 | 82 | writeln!(writer, ";")
|
81 | 83 | }
|
82 | 84 | // FIXME: Add rest of the statements
|
83 | 85 | StatementKind::FakeRead(cause, place) => {
|
84 |
| - writeln!(writer, "FakeRead({cause:?}, {place:?});") |
| 86 | + writeln!(writer, "{INDENT}FakeRead({cause:?}, {place:?});") |
85 | 87 | }
|
86 | 88 | StatementKind::SetDiscriminant { place, variant_index } => {
|
87 |
| - writeln!(writer, "discriminant({place:?} = {};", variant_index.to_index()) |
| 89 | + writeln!(writer, "{INDENT}discriminant({place:?} = {};", variant_index.to_index()) |
88 | 90 | }
|
89 | 91 | StatementKind::Deinit(place) => writeln!(writer, "Deinit({place:?};"),
|
90 | 92 | StatementKind::StorageLive(local) => {
|
91 |
| - writeln!(writer, "StorageLive(_{local});") |
| 93 | + writeln!(writer, "{INDENT}StorageLive(_{local});") |
92 | 94 | }
|
93 | 95 | StatementKind::StorageDead(local) => {
|
94 |
| - writeln!(writer, "StorageDead(_{local});") |
| 96 | + writeln!(writer, "{INDENT}StorageDead(_{local});") |
95 | 97 | }
|
96 | 98 | StatementKind::Retag(kind, place) => writeln!(writer, "Retag({kind:?}, {place:?});"),
|
97 | 99 | StatementKind::PlaceMention(place) => {
|
98 |
| - writeln!(writer, "PlaceMention({place:?};") |
| 100 | + writeln!(writer, "{INDENT}PlaceMention({place:?};") |
99 | 101 | }
|
100 | 102 | StatementKind::ConstEvalCounter => {
|
101 |
| - writeln!(writer, "ConstEvalCounter;") |
| 103 | + writeln!(writer, "{INDENT}ConstEvalCounter;") |
102 | 104 | }
|
103 |
| - StatementKind::Nop => writeln!(writer, "nop;"), |
| 105 | + StatementKind::Nop => writeln!(writer, "{INDENT}nop;"), |
104 | 106 | StatementKind::AscribeUserType { .. }
|
105 | 107 | | StatementKind::Coverage(_)
|
106 | 108 | | StatementKind::Intrinsic(_) => {
|
107 | 109 | // FIX-ME: Make them pretty.
|
108 |
| - writeln!(writer, "{statement:?};") |
| 110 | + writeln!(writer, "{INDENT}{statement:?};") |
109 | 111 | }
|
110 | 112 | }
|
111 | 113 | }
|
@@ -322,15 +324,11 @@ fn pretty_ty_const(ct: &TyConst) -> String {
|
322 | 324 | fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
|
323 | 325 | match rval {
|
324 | 326 | Rvalue::AddressOf(mutability, place) => {
|
325 |
| - write!(writer, "&raw {}(*{:?})", pretty_mut(*mutability), place) |
| 327 | + write!(writer, "&raw {} {:?}", pretty_mut(*mutability), place) |
326 | 328 | }
|
327 | 329 | Rvalue::Aggregate(aggregate_kind, operands) => {
|
328 | 330 | // 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, ")") |
| 331 | + pretty_aggregate(writer, aggregate_kind, operands) |
334 | 332 | }
|
335 | 333 | Rvalue::BinaryOp(bin, op1, op2) => {
|
336 | 334 | write!(writer, "{:?}({}, {})", bin, pretty_operand(op1), pretty_operand(op2))
|
@@ -360,22 +358,74 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
|
360 | 358 | write!(writer, "{kind}{place:?}")
|
361 | 359 | }
|
362 | 360 | Rvalue::Repeat(op, cnst) => {
|
363 |
| - write!(writer, "{} \" \" {}", pretty_operand(op), pretty_ty_const(cnst)) |
| 361 | + write!(writer, "[{}; {}]", pretty_operand(op), pretty_ty_const(cnst)) |
364 | 362 | }
|
365 | 363 | Rvalue::ShallowInitBox(_, _) => Ok(()),
|
366 | 364 | Rvalue::ThreadLocalRef(item) => {
|
367 | 365 | write!(writer, "thread_local_ref{item:?}")
|
368 | 366 | }
|
369 | 367 | Rvalue::NullaryOp(nul, ty) => {
|
370 |
| - write!(writer, "{nul:?} {ty} \" \"") |
| 368 | + write!(writer, "{nul:?}::<{ty}>() \" \"") |
371 | 369 | }
|
372 | 370 | Rvalue::UnaryOp(un, op) => {
|
373 |
| - write!(writer, "{} \" \" {:?}", pretty_operand(op), un) |
| 371 | + write!(writer, "{:?}({})", un, pretty_operand(op)) |
374 | 372 | }
|
375 | 373 | Rvalue::Use(op) => write!(writer, "{}", pretty_operand(op)),
|
376 | 374 | }
|
377 | 375 | }
|
378 | 376 |
|
| 377 | +fn pretty_aggregate<W: Write>( |
| 378 | + writer: &mut W, |
| 379 | + aggregate_kind: &AggregateKind, |
| 380 | + operands: &Vec<Operand>, |
| 381 | +) -> io::Result<()> { |
| 382 | + let suffix = match aggregate_kind { |
| 383 | + AggregateKind::Array(_) => { |
| 384 | + write!(writer, "[")?; |
| 385 | + "]" |
| 386 | + } |
| 387 | + AggregateKind::Tuple => { |
| 388 | + write!(writer, "(")?; |
| 389 | + ")" |
| 390 | + } |
| 391 | + AggregateKind::Adt(def, var, _, _, _) => { |
| 392 | + if def.kind() == AdtKind::Enum { |
| 393 | + write!(writer, "{}::{}", def.name(), def.variant(*var).unwrap().name())?; |
| 394 | + } else { |
| 395 | + write!(writer, "{}", def.variant(*var).unwrap().name())?; |
| 396 | + } |
| 397 | + if operands.is_empty() { |
| 398 | + return Ok(()); |
| 399 | + } |
| 400 | + // FIXME: Change this once we have CtorKind in StableMIR. |
| 401 | + write!(writer, "(")?; |
| 402 | + ")" |
| 403 | + } |
| 404 | + AggregateKind::Closure(def, _) => { |
| 405 | + write!(writer, "{{closure@{:?}}}(", def.span())?; |
| 406 | + ")" |
| 407 | + } |
| 408 | + AggregateKind::Coroutine(def, _, _) => { |
| 409 | + write!(writer, "{{coroutine@{:?}}}(", def.span())?; |
| 410 | + ")" |
| 411 | + } |
| 412 | + AggregateKind::RawPtr(ty, mutability) => { |
| 413 | + write!( |
| 414 | + writer, |
| 415 | + "*{} {ty} from (", |
| 416 | + if *mutability == Mutability::Mut { "mut" } else { "const" } |
| 417 | + )?; |
| 418 | + ")" |
| 419 | + } |
| 420 | + }; |
| 421 | + let mut separator = ""; |
| 422 | + for op in operands { |
| 423 | + write!(writer, "{}{}", separator, pretty_operand(op))?; |
| 424 | + separator = ", "; |
| 425 | + } |
| 426 | + write!(writer, "{suffix}") |
| 427 | +} |
| 428 | + |
379 | 429 | fn pretty_mut(mutability: Mutability) -> &'static str {
|
380 | 430 | match mutability {
|
381 | 431 | Mutability::Not => " ",
|
|
0 commit comments