@@ -2,37 +2,43 @@ use std::io;
2
2
3
3
use rustc_middle:: ty:: TyCtxt ;
4
4
use stable_mir:: {
5
+ mir:: { Mutability , Operand , Rvalue , StatementKind } ,
5
6
ty:: { RigidTy , TyKind } ,
6
- CrateItem , mir :: Mutability ,
7
+ CrateItem ,
7
8
} ;
8
9
9
-
10
10
use super :: { run, RustcInternal } ;
11
11
12
- pub fn write_smir_pretty < ' tcx > ( tcx : TyCtxt < ' tcx > , w : & mut dyn io:: Write ) -> io:: Result < ( ) > {
12
+ pub fn write_smir_pretty < ' tcx > ( tcx : TyCtxt < ' tcx > , w : & mut dyn io:: Write ) -> io:: Result < ( ) > {
13
13
run ( tcx, || {
14
14
let items = stable_mir:: all_local_items ( ) ;
15
15
items. iter ( ) . for_each ( |item| {
16
16
// Because we can't return a Result from a closure, we have to unwrap here.
17
- writeln ! ( w, "{}" , function_name( * item, tcx) ) . unwrap ( ) ;
18
- writeln ! ( w, "{}" , function_body( * item, tcx) ) . unwrap ( ) ;
17
+ writeln ! ( w, "{}" , function_name( * item, tcx) ) . unwrap ( ) ;
18
+ writeln ! ( w, "{}" , function_body( * item, tcx) ) . unwrap ( ) ;
19
+ writeln ! ( w, "------------------" ) . unwrap ( ) ;
20
+ item. body ( ) . blocks . iter ( ) . for_each ( |block| {
21
+ block. statements . iter ( ) . for_each ( |statement| {
22
+ writeln ! ( w, "{}" , pretty_statement( & statement. kind, tcx) ) . unwrap ( ) ;
23
+ } ) ;
24
+ } )
19
25
} )
20
26
} ) ;
21
27
Ok ( ( ) )
22
28
}
23
29
24
- pub fn function_name ( item : CrateItem , tcx : TyCtxt < ' _ > ) -> String {
30
+ pub fn function_name ( item : CrateItem , tcx : TyCtxt < ' _ > ) -> String {
25
31
let mut name = String :: new ( ) ;
26
- let body = item. body ( ) ;
32
+ let body = item. body ( ) ;
27
33
name. push_str ( "fn " ) ;
28
34
name. push_str ( item. name ( ) . as_str ( ) ) ;
29
35
if body. arg_locals ( ) . is_empty ( ) {
30
36
name. push_str ( "()" ) ;
31
- } else {
37
+ } else {
32
38
name. push_str ( "(" ) ;
33
39
}
34
40
body. arg_locals ( ) . iter ( ) . for_each ( |local| {
35
- name. push_str ( format ! ( "_{}: " , local. local) . as_str ( ) ) ;
41
+ name. push_str ( format ! ( "_{}: " , local. local) . as_str ( ) ) ;
36
42
name. push_str ( & pretty_ty ( local. ty . kind ( ) , tcx) ) ;
37
43
} ) ;
38
44
if !body. arg_locals ( ) . is_empty ( ) {
@@ -45,20 +51,18 @@ pub fn function_name(item: CrateItem,tcx: TyCtxt<'_>) -> String {
45
51
name
46
52
}
47
53
48
- pub fn function_body ( item : CrateItem , _tcx : TyCtxt < ' _ > ) -> String {
54
+ pub fn function_body ( item : CrateItem , _tcx : TyCtxt < ' _ > ) -> String {
49
55
let mut body_str = String :: new ( ) ;
50
- let body = item. body ( ) ;
56
+ let body = item. body ( ) ;
51
57
body. inner_locals ( ) . iter ( ) . for_each ( |local| {
52
58
body_str. push_str ( " " ) ;
53
- body_str. push_str ( format ! ( "let {}" , ret_mutability( & local. mutability) ) . as_str ( ) ) ;
54
- body_str. push_str ( format ! ( "_{}: " , local. local) . as_str ( ) ) ;
55
- body_str. push_str ( format ! ( "{}" , pretty_ty( local. ty. kind( ) , _tcx) ) . as_str ( ) ) ;
59
+ body_str. push_str ( format ! ( "let {}" , ret_mutability( & local. mutability) ) . as_str ( ) ) ;
60
+ body_str. push_str ( format ! ( "_{}: " , local. local) . as_str ( ) ) ;
61
+ body_str. push_str ( format ! ( "{}" , pretty_ty( local. ty. kind( ) , _tcx) ) . as_str ( ) ) ;
56
62
body_str. push_str ( ";\n " ) ;
57
-
58
63
} ) ;
59
64
body_str. push_str ( "}" ) ;
60
65
body_str
61
-
62
66
}
63
67
64
68
pub fn ret_mutability ( mutability : & Mutability ) -> String {
@@ -68,7 +72,129 @@ pub fn ret_mutability(mutability: &Mutability) -> String {
68
72
}
69
73
}
70
74
71
- pub fn pretty_ty < ' tcx > ( ty : TyKind , tcx : TyCtxt < ' tcx > ) -> String {
75
+ pub fn pretty_statement ( statement : & StatementKind , tcx : TyCtxt < ' _ > ) -> String {
76
+ let mut pretty = String :: new ( ) ;
77
+ match statement {
78
+ StatementKind :: Assign ( place, rval) => {
79
+ pretty. push_str ( format ! ( "_{} = " , place. local) . as_str ( ) ) ;
80
+ pretty. push_str ( & pretty_rvalue ( rval, tcx) )
81
+ }
82
+ StatementKind :: FakeRead ( _, _) => todo ! ( ) ,
83
+ StatementKind :: SetDiscriminant { .. } => todo ! ( ) ,
84
+ StatementKind :: Deinit ( _) => todo ! ( ) ,
85
+ StatementKind :: StorageLive ( _) => todo ! ( ) ,
86
+ StatementKind :: StorageDead ( _) => todo ! ( ) ,
87
+ StatementKind :: Retag ( _, _) => todo ! ( ) ,
88
+ StatementKind :: PlaceMention ( _) => todo ! ( ) ,
89
+ StatementKind :: AscribeUserType { .. } => todo ! ( ) ,
90
+ StatementKind :: Coverage ( _) => todo ! ( ) ,
91
+ StatementKind :: Intrinsic ( _) => todo ! ( ) ,
92
+ StatementKind :: ConstEvalCounter => ( ) ,
93
+ StatementKind :: Nop => ( ) ,
94
+ }
95
+ pretty
96
+ }
97
+
98
+ pub fn pretty_operand ( operand : & Operand , _tcx : TyCtxt < ' _ > ) -> String {
99
+ let mut pretty = String :: new ( ) ;
100
+ match operand {
101
+ Operand :: Copy ( copy) => {
102
+ pretty. push_str ( "" ) ;
103
+ pretty. push_str ( format ! ( "{}" , copy. local) . as_str ( ) ) ;
104
+ }
105
+ Operand :: Move ( mv) => {
106
+ pretty. push_str ( "move" ) ;
107
+ pretty. push_str ( format ! ( "{}" , mv. local) . as_str ( ) ) ;
108
+ }
109
+ Operand :: Constant ( cnst) => {
110
+ pretty. push_str ( "const " ) ;
111
+ pretty. push_str ( cnst. literal . internal_via_tls ( ) . to_string ( ) . as_str ( ) ) ;
112
+ }
113
+ }
114
+ pretty
115
+ }
116
+
117
+ pub fn pretty_rvalue ( rval : & Rvalue , tcx : TyCtxt < ' _ > ) -> String {
118
+ let mut pretty = String :: new ( ) ;
119
+ match rval {
120
+ Rvalue :: AddressOf ( muta, addr) => {
121
+ pretty. push_str ( "address_of" ) ;
122
+ pretty. push_str ( & ret_mutability ( & muta) ) ;
123
+ pretty. push_str ( format ! ( "{}" , addr. local) . as_str ( ) ) ;
124
+ }
125
+ Rvalue :: Aggregate ( aggregatekind, operands) => {
126
+ pretty. push_str ( format ! ( "{:#?}" , aggregatekind) . as_str ( ) ) ;
127
+ pretty. push_str ( "(" ) ;
128
+ operands. iter ( ) . enumerate ( ) . for_each ( |( i, op) | {
129
+ pretty. push_str ( & pretty_operand ( op, tcx) ) ;
130
+ if i != operands. len ( ) - 1 {
131
+ pretty. push_str ( ", " ) ;
132
+ }
133
+ } ) ;
134
+ pretty. push_str ( ")" ) ;
135
+ }
136
+ Rvalue :: BinaryOp ( bin, op, op2) => {
137
+ pretty. push_str ( & pretty_operand ( op, tcx) ) ;
138
+ pretty. push_str ( " " ) ;
139
+ pretty. push_str ( format ! ( "{:#?}" , bin) . as_str ( ) ) ;
140
+ pretty. push_str ( " " ) ;
141
+ pretty. push_str ( & pretty_operand ( op2, tcx) ) ;
142
+ }
143
+ Rvalue :: Cast ( _, op, ty) => {
144
+ pretty. push_str ( & pretty_operand ( op, tcx) ) ;
145
+ pretty. push_str ( " as " ) ;
146
+ pretty. push_str ( & pretty_ty ( ty. kind ( ) , tcx) ) ;
147
+ }
148
+ Rvalue :: CheckedBinaryOp ( bin, op1, op2) => {
149
+ pretty. push_str ( & pretty_operand ( op1, tcx) ) ;
150
+ pretty. push_str ( " " ) ;
151
+ pretty. push_str ( format ! ( "{:#?}" , bin) . as_str ( ) ) ;
152
+ pretty. push_str ( " " ) ;
153
+ pretty. push_str ( & pretty_operand ( op2, tcx) ) ;
154
+ }
155
+ Rvalue :: CopyForDeref ( deref) => {
156
+ pretty. push_str ( "CopyForDeref" ) ;
157
+ pretty. push_str ( format ! ( "{}" , deref. local) . as_str ( ) ) ;
158
+ }
159
+ Rvalue :: Discriminant ( place) => {
160
+ pretty. push_str ( "discriminant" ) ;
161
+ pretty. push_str ( format ! ( "{}" , place. local) . as_str ( ) ) ;
162
+ }
163
+ Rvalue :: Len ( len) => {
164
+ pretty. push_str ( "len" ) ;
165
+ pretty. push_str ( format ! ( "{}" , len. local) . as_str ( ) ) ;
166
+ }
167
+ Rvalue :: Ref ( _, borrowkind, place) => {
168
+ pretty. push_str ( "ref" ) ;
169
+ pretty. push_str ( format ! ( "{:#?}" , borrowkind) . as_str ( ) ) ;
170
+ pretty. push_str ( format ! ( "{}" , place. local) . as_str ( ) ) ;
171
+ }
172
+ Rvalue :: Repeat ( op, cnst) => {
173
+ pretty. push_str ( & pretty_operand ( op, tcx) ) ;
174
+ pretty. push_str ( " " ) ;
175
+ pretty. push_str ( & pretty_ty ( cnst. ty ( ) . kind ( ) , tcx) ) ;
176
+ }
177
+ Rvalue :: ShallowInitBox ( _, _) => todo ! ( ) ,
178
+ Rvalue :: ThreadLocalRef ( item) => {
179
+ pretty. push_str ( "thread_local_ref" ) ;
180
+ pretty. push_str ( format ! ( "{:#?}" , item) . as_str ( ) ) ;
181
+ }
182
+ Rvalue :: NullaryOp ( nul, ty) => {
183
+ pretty. push_str ( format ! ( "{:#?}" , nul) . as_str ( ) ) ;
184
+ pretty. push_str ( & & pretty_ty ( ty. kind ( ) , tcx) ) ;
185
+ pretty. push_str ( " " ) ;
186
+ }
187
+ Rvalue :: UnaryOp ( un, op) => {
188
+ pretty. push_str ( & pretty_operand ( op, tcx) ) ;
189
+ pretty. push_str ( " " ) ;
190
+ pretty. push_str ( format ! ( "{:#?}" , un) . as_str ( ) ) ;
191
+ }
192
+ Rvalue :: Use ( op) => pretty. push_str ( & pretty_operand ( op, tcx) ) ,
193
+ }
194
+ pretty
195
+ }
196
+
197
+ pub fn pretty_ty ( ty : TyKind , tcx : TyCtxt < ' _ > ) -> String {
72
198
let mut pretty = String :: new ( ) ;
73
199
pretty. push_str ( "" ) ;
74
200
match ty {
@@ -95,36 +221,39 @@ pub fn pretty_ty<'tcx>(ty: TyKind,tcx: TyCtxt<'tcx>) -> String {
95
221
stable_mir:: ty:: FloatTy :: F32 => "f32" . to_string ( ) ,
96
222
stable_mir:: ty:: FloatTy :: F64 => "f64" . to_string ( ) ,
97
223
} ,
98
- RigidTy :: Adt ( def, _) => format ! ( "{:#?}" , tcx. type_of( def. 0 . internal_via_tls( ) ) . instantiate_identity( ) ) ,
224
+ RigidTy :: Adt ( def, _) => {
225
+ format ! ( "{:#?}" , tcx. type_of( def. 0 . internal_via_tls( ) ) . instantiate_identity( ) )
226
+ }
99
227
RigidTy :: Foreign ( _) => format ! ( "{:#?}" , rigid_ty) ,
100
228
RigidTy :: Str => "str" . to_string ( ) ,
101
229
RigidTy :: Array ( _ty, len) => {
102
- format ! ( "[{};{:#?}]" , 1 , len. internal_via_tls( ) ) } ,
103
- RigidTy :: Slice ( ty) => pretty_ty ( ty. kind ( ) , tcx) ,
230
+ format ! ( "[{};{:#?}]" , 1 , len. internal_via_tls( ) )
231
+ }
232
+ RigidTy :: Slice ( ty) => pretty_ty ( ty. kind ( ) , tcx) ,
104
233
RigidTy :: RawPtr ( _, _) => format ! ( "{:#?}" , rigid_ty) ,
105
- RigidTy :: Ref ( _, ty, _) => pretty_ty ( ty. kind ( ) , tcx) ,
234
+ RigidTy :: Ref ( _, ty, _) => pretty_ty ( ty. kind ( ) , tcx) ,
106
235
RigidTy :: FnDef ( _, _) => format ! ( "{:#?}" , rigid_ty) ,
107
236
RigidTy :: FnPtr ( _) => format ! ( "{:#?}" , rigid_ty) ,
108
237
RigidTy :: Closure ( _, _) => format ! ( "{:#?}" , rigid_ty) ,
109
238
RigidTy :: Coroutine ( _, _, _) => format ! ( "{:#?}" , rigid_ty) ,
110
239
RigidTy :: Dynamic ( _, _, _) => format ! ( "{:#?}" , rigid_ty) ,
111
240
RigidTy :: Never => "!" . to_string ( ) ,
112
241
RigidTy :: Tuple ( tuple) => {
113
- if tuple. is_empty ( ) {
242
+ if tuple. is_empty ( ) {
114
243
"()" . to_string ( )
115
- } else {
244
+ } else {
116
245
let mut tuple_str = String :: new ( ) ;
117
246
tuple_str. push_str ( "(" ) ;
118
- tuple. iter ( ) . enumerate ( ) . for_each ( |( i, ty) | {
119
- tuple_str. push_str ( & pretty_ty ( ty. kind ( ) , tcx) ) ;
247
+ tuple. iter ( ) . enumerate ( ) . for_each ( |( i, ty) | {
248
+ tuple_str. push_str ( & pretty_ty ( ty. kind ( ) , tcx) ) ;
120
249
if i != tuple. len ( ) - 1 {
121
250
tuple_str. push_str ( ", " ) ;
122
251
}
123
252
} ) ;
124
253
tuple_str. push_str ( ")" ) ;
125
254
tuple_str
126
255
}
127
- } ,
256
+ }
128
257
} ,
129
258
TyKind :: Alias ( _, _) => format ! ( "{:#?}" , ty) ,
130
259
TyKind :: Param ( _) => format ! ( "{:#?}" , ty) ,
0 commit comments