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( ) ) ?;
407+ ")"
408+ }
409+ AggregateKind :: Coroutine ( def, _, _) => {
410+ write ! ( writer, "{{coroutine@{:?}}}(" , def. span( ) ) ?;
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