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 {
@@ -23,10 +24,11 @@ impl Debug for Place {
23
24
24
25
pub ( crate ) fn function_body < W : Write > ( writer : & mut W , body : & Body , name : & str ) -> io:: Result < ( ) > {
25
26
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
+ }
30
32
write ! ( writer, ")" ) ?;
31
33
32
34
let return_local = body. ret_local ( ) ;
@@ -73,39 +75,40 @@ pub(crate) fn function_body<W: Write>(writer: &mut W, body: &Body, name: &str) -
73
75
}
74
76
75
77
fn pretty_statement < W : Write > ( writer : & mut W , statement : & StatementKind ) -> io:: Result < ( ) > {
78
+ const INDENT : & str = " " ;
76
79
match statement {
77
80
StatementKind :: Assign ( place, rval) => {
78
- write ! ( writer, " {place:?} = " ) ?;
81
+ write ! ( writer, "{INDENT} {place:?} = " ) ?;
79
82
pretty_rvalue ( writer, rval) ?;
80
83
writeln ! ( writer, ";" )
81
84
}
82
85
// FIXME: Add rest of the statements
83
86
StatementKind :: FakeRead ( cause, place) => {
84
- writeln ! ( writer, "FakeRead({cause:?}, {place:?});" )
87
+ writeln ! ( writer, "{INDENT} FakeRead({cause:?}, {place:?});" )
85
88
}
86
89
StatementKind :: SetDiscriminant { place, variant_index } => {
87
- writeln ! ( writer, "discriminant({place:?} = {};" , variant_index. to_index( ) )
90
+ writeln ! ( writer, "{INDENT} discriminant({place:?} = {};" , variant_index. to_index( ) )
88
91
}
89
92
StatementKind :: Deinit ( place) => writeln ! ( writer, "Deinit({place:?};" ) ,
90
93
StatementKind :: StorageLive ( local) => {
91
- writeln ! ( writer, "StorageLive(_{local});" )
94
+ writeln ! ( writer, "{INDENT} StorageLive(_{local});" )
92
95
}
93
96
StatementKind :: StorageDead ( local) => {
94
- writeln ! ( writer, "StorageDead(_{local});" )
97
+ writeln ! ( writer, "{INDENT} StorageDead(_{local});" )
95
98
}
96
99
StatementKind :: Retag ( kind, place) => writeln ! ( writer, "Retag({kind:?}, {place:?});" ) ,
97
100
StatementKind :: PlaceMention ( place) => {
98
- writeln ! ( writer, "PlaceMention({place:?};" )
101
+ writeln ! ( writer, "{INDENT} PlaceMention({place:?};" )
99
102
}
100
103
StatementKind :: ConstEvalCounter => {
101
- writeln ! ( writer, "ConstEvalCounter;" )
104
+ writeln ! ( writer, "{INDENT} ConstEvalCounter;" )
102
105
}
103
- StatementKind :: Nop => writeln ! ( writer, "nop;" ) ,
106
+ StatementKind :: Nop => writeln ! ( writer, "{INDENT} nop;" ) ,
104
107
StatementKind :: AscribeUserType { .. }
105
108
| StatementKind :: Coverage ( _)
106
109
| StatementKind :: Intrinsic ( _) => {
107
110
// FIX-ME: Make them pretty.
108
- writeln ! ( writer, "{statement:?};" )
111
+ writeln ! ( writer, "{INDENT}{ statement:?};" )
109
112
}
110
113
}
111
114
}
@@ -322,15 +325,11 @@ fn pretty_ty_const(ct: &TyConst) -> String {
322
325
fn pretty_rvalue < W : Write > ( writer : & mut W , rval : & Rvalue ) -> io:: Result < ( ) > {
323
326
match rval {
324
327
Rvalue :: AddressOf ( mutability, place) => {
325
- write ! ( writer, "&raw {}(* {:?}) " , pretty_mut( * mutability) , place)
328
+ write ! ( writer, "&raw {} {:?}" , pretty_mut( * mutability) , place)
326
329
}
327
330
Rvalue :: Aggregate ( aggregate_kind, operands) => {
328
331
// 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)
334
333
}
335
334
Rvalue :: BinaryOp ( bin, op1, op2) => {
336
335
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<()> {
360
359
write ! ( writer, "{kind}{place:?}" )
361
360
}
362
361
Rvalue :: Repeat ( op, cnst) => {
363
- write ! ( writer, "{} \" \" {} " , pretty_operand( op) , pretty_ty_const( cnst) )
362
+ write ! ( writer, "[{}; {}] " , pretty_operand( op) , pretty_ty_const( cnst) )
364
363
}
365
364
Rvalue :: ShallowInitBox ( _, _) => Ok ( ( ) ) ,
366
365
Rvalue :: ThreadLocalRef ( item) => {
367
366
write ! ( writer, "thread_local_ref{item:?}" )
368
367
}
369
368
Rvalue :: NullaryOp ( nul, ty) => {
370
- write ! ( writer, "{nul:?} {ty} \" \" " )
369
+ write ! ( writer, "{nul:?}::< {ty}>() \" \" " )
371
370
}
372
371
Rvalue :: UnaryOp ( un, op) => {
373
- write ! ( writer, "{} \" \" { :?}" , pretty_operand( op) , un )
372
+ write ! ( writer, "{:?}({}) " , un , pretty_operand( op) )
374
373
}
375
374
Rvalue :: Use ( op) => write ! ( writer, "{}" , pretty_operand( op) ) ,
376
375
}
377
376
}
378
377
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
+
379
430
fn pretty_mut ( mutability : Mutability ) -> & ' static str {
380
431
match mutability {
381
432
Mutability :: Not => " " ,
0 commit comments