@@ -2,37 +2,43 @@ use std::io;
22
33use rustc_middle:: ty:: TyCtxt ;
44use stable_mir:: {
5+ mir:: { Mutability , Operand , Rvalue , StatementKind } ,
56 ty:: { RigidTy , TyKind } ,
6- CrateItem , mir :: Mutability ,
7+ CrateItem ,
78} ;
89
9-
1010use super :: { run, RustcInternal } ;
1111
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 < ( ) > {
1313 run ( tcx, || {
1414 let items = stable_mir:: all_local_items ( ) ;
1515 items. iter ( ) . for_each ( |item| {
1616 // 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+ } )
1925 } )
2026 } ) ;
2127 Ok ( ( ) )
2228}
2329
24- pub fn function_name ( item : CrateItem , tcx : TyCtxt < ' _ > ) -> String {
30+ pub fn function_name ( item : CrateItem , tcx : TyCtxt < ' _ > ) -> String {
2531 let mut name = String :: new ( ) ;
26- let body = item. body ( ) ;
32+ let body = item. body ( ) ;
2733 name. push_str ( "fn " ) ;
2834 name. push_str ( item. name ( ) . as_str ( ) ) ;
2935 if body. arg_locals ( ) . is_empty ( ) {
3036 name. push_str ( "()" ) ;
31- } else {
37+ } else {
3238 name. push_str ( "(" ) ;
3339 }
3440 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 ( ) ) ;
3642 name. push_str ( & pretty_ty ( local. ty . kind ( ) , tcx) ) ;
3743 } ) ;
3844 if !body. arg_locals ( ) . is_empty ( ) {
@@ -45,20 +51,18 @@ pub fn function_name(item: CrateItem,tcx: TyCtxt<'_>) -> String {
4551 name
4652}
4753
48- pub fn function_body ( item : CrateItem , _tcx : TyCtxt < ' _ > ) -> String {
54+ pub fn function_body ( item : CrateItem , _tcx : TyCtxt < ' _ > ) -> String {
4955 let mut body_str = String :: new ( ) ;
50- let body = item. body ( ) ;
56+ let body = item. body ( ) ;
5157 body. inner_locals ( ) . iter ( ) . for_each ( |local| {
5258 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 ( ) ) ;
5662 body_str. push_str ( ";\n " ) ;
57-
5863 } ) ;
5964 body_str. push_str ( "}" ) ;
6065 body_str
61-
6266}
6367
6468pub fn ret_mutability ( mutability : & Mutability ) -> String {
@@ -68,7 +72,129 @@ pub fn ret_mutability(mutability: &Mutability) -> String {
6872 }
6973}
7074
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 {
72198 let mut pretty = String :: new ( ) ;
73199 pretty. push_str ( "" ) ;
74200 match ty {
@@ -95,36 +221,39 @@ pub fn pretty_ty<'tcx>(ty: TyKind,tcx: TyCtxt<'tcx>) -> String {
95221 stable_mir:: ty:: FloatTy :: F32 => "f32" . to_string ( ) ,
96222 stable_mir:: ty:: FloatTy :: F64 => "f64" . to_string ( ) ,
97223 } ,
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+ }
99227 RigidTy :: Foreign ( _) => format ! ( "{:#?}" , rigid_ty) ,
100228 RigidTy :: Str => "str" . to_string ( ) ,
101229 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) ,
104233 RigidTy :: RawPtr ( _, _) => format ! ( "{:#?}" , rigid_ty) ,
105- RigidTy :: Ref ( _, ty, _) => pretty_ty ( ty. kind ( ) , tcx) ,
234+ RigidTy :: Ref ( _, ty, _) => pretty_ty ( ty. kind ( ) , tcx) ,
106235 RigidTy :: FnDef ( _, _) => format ! ( "{:#?}" , rigid_ty) ,
107236 RigidTy :: FnPtr ( _) => format ! ( "{:#?}" , rigid_ty) ,
108237 RigidTy :: Closure ( _, _) => format ! ( "{:#?}" , rigid_ty) ,
109238 RigidTy :: Coroutine ( _, _, _) => format ! ( "{:#?}" , rigid_ty) ,
110239 RigidTy :: Dynamic ( _, _, _) => format ! ( "{:#?}" , rigid_ty) ,
111240 RigidTy :: Never => "!" . to_string ( ) ,
112241 RigidTy :: Tuple ( tuple) => {
113- if tuple. is_empty ( ) {
242+ if tuple. is_empty ( ) {
114243 "()" . to_string ( )
115- } else {
244+ } else {
116245 let mut tuple_str = String :: new ( ) ;
117246 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) ) ;
120249 if i != tuple. len ( ) - 1 {
121250 tuple_str. push_str ( ", " ) ;
122251 }
123252 } ) ;
124253 tuple_str. push_str ( ")" ) ;
125254 tuple_str
126255 }
127- } ,
256+ }
128257 } ,
129258 TyKind :: Alias ( _, _) => format ! ( "{:#?}" , ty) ,
130259 TyKind :: Param ( _) => format ! ( "{:#?}" , ty) ,
0 commit comments