]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/thir/print.rs
address review
[rust.git] / compiler / rustc_middle / src / thir / print.rs
1 use crate::thir::*;
2 use crate::ty::{self, TyCtxt};
3
4 use std::fmt::{self, Write};
5
6 impl<'tcx> TyCtxt<'tcx> {
7     pub fn thir_tree_representation<'a>(self, thir: &'a Thir<'tcx>) -> String {
8         let mut printer = ThirPrinter::new(thir);
9         printer.print();
10         printer.into_buffer()
11     }
12 }
13
14 struct ThirPrinter<'a, 'tcx> {
15     thir: &'a Thir<'tcx>,
16     fmt: String,
17 }
18
19 const INDENT: &str = "    ";
20
21 macro_rules! print_indented {
22     ($writer:ident, $s:expr, $indent_lvl:expr) => {
23         let indent = (0..$indent_lvl).map(|_| INDENT).collect::<Vec<_>>().concat();
24         writeln!($writer, "{}{}", indent, $s).expect("unable to write to ThirPrinter");
25     };
26 }
27
28 impl<'a, 'tcx> Write for ThirPrinter<'a, 'tcx> {
29     fn write_str(&mut self, s: &str) -> fmt::Result {
30         self.fmt.push_str(s);
31         Ok(())
32     }
33 }
34
35 impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
36     fn new(thir: &'a Thir<'tcx>) -> Self {
37         Self { thir, fmt: String::new() }
38     }
39
40     fn print(&mut self) {
41         print_indented!(self, "params: [", 0);
42         for param in self.thir.params.iter() {
43             self.print_param(param, 1);
44         }
45         print_indented!(self, "]", 0);
46
47         print_indented!(self, "body:", 0);
48         let expr = ExprId::from_usize(self.thir.exprs.len() - 1);
49         self.print_expr(expr, 1);
50     }
51
52     fn into_buffer(self) -> String {
53         self.fmt
54     }
55
56     fn print_param(&mut self, param: &Param<'tcx>, depth_lvl: usize) {
57         let Param { pat, ty, ty_span, self_kind, hir_id } = param;
58
59         print_indented!(self, "Param {", depth_lvl);
60         print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
61         print_indented!(self, format!("ty_span: {:?}", ty_span), depth_lvl + 1);
62         print_indented!(self, format!("self_kind: {:?}", self_kind), depth_lvl + 1);
63         print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 1);
64
65         if let Some(pat) = pat {
66             print_indented!(self, "param: Some( ", depth_lvl + 1);
67             self.print_pat(pat, depth_lvl + 2);
68             print_indented!(self, ")", depth_lvl + 1);
69         } else {
70             print_indented!(self, "param: None", depth_lvl + 1);
71         }
72
73         print_indented!(self, "}", depth_lvl);
74     }
75
76     fn print_block(&mut self, block_id: BlockId, depth_lvl: usize) {
77         let Block {
78             targeted_by_break,
79             opt_destruction_scope,
80             span,
81             region_scope,
82             stmts,
83             expr,
84             safety_mode,
85         } = &self.thir.blocks[block_id];
86
87         print_indented!(self, "Block {", depth_lvl);
88         print_indented!(self, format!("targeted_by_break: {}", targeted_by_break), depth_lvl + 1);
89         print_indented!(
90             self,
91             format!("opt_destruction_scope: {:?}", opt_destruction_scope),
92             depth_lvl + 1
93         );
94         print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
95         print_indented!(self, format!("region_scope: {:?}", region_scope), depth_lvl + 1);
96         print_indented!(self, format!("safety_mode: {:?}", safety_mode), depth_lvl + 1);
97
98         if stmts.len() > 0 {
99             print_indented!(self, "stmts: [", depth_lvl + 1);
100             for stmt in stmts.iter() {
101                 self.print_stmt(*stmt, depth_lvl + 2);
102             }
103             print_indented!(self, "]", depth_lvl + 1);
104         } else {
105             print_indented!(self, "stmts: []", depth_lvl + 1);
106         }
107
108         if let Some(expr_id) = expr {
109             print_indented!(self, "expr:", depth_lvl + 1);
110             self.print_expr(*expr_id, depth_lvl + 2);
111         } else {
112             print_indented!(self, "expr: []", depth_lvl + 1);
113         }
114
115         print_indented!(self, "}", depth_lvl);
116     }
117
118     fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) {
119         let Stmt { kind, opt_destruction_scope } = &self.thir.stmts[stmt_id];
120
121         print_indented!(self, "Stmt {", depth_lvl);
122         print_indented!(
123             self,
124             format!("opt_destruction_scope: {:?}", opt_destruction_scope),
125             depth_lvl + 1
126         );
127
128         match kind {
129             StmtKind::Expr { scope, expr } => {
130                 print_indented!(self, "kind: Expr {", depth_lvl + 1);
131                 print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 2);
132                 print_indented!(self, "expr:", depth_lvl + 2);
133                 self.print_expr(*expr, depth_lvl + 3);
134                 print_indented!(self, "}", depth_lvl + 1);
135             }
136             StmtKind::Let {
137                 remainder_scope,
138                 init_scope,
139                 pattern,
140                 initializer,
141                 else_block,
142                 lint_level,
143             } => {
144                 print_indented!(self, "kind: Let {", depth_lvl + 1);
145                 print_indented!(
146                     self,
147                     format!("remainder_scope: {:?}", remainder_scope),
148                     depth_lvl + 2
149                 );
150                 print_indented!(self, format!("init_scope: {:?}", init_scope), depth_lvl + 2);
151
152                 print_indented!(self, "pattern: ", depth_lvl + 2);
153                 self.print_pat(pattern, depth_lvl + 3);
154                 print_indented!(self, ",", depth_lvl + 2);
155
156                 if let Some(init) = initializer {
157                     print_indented!(self, "initializer: Some(", depth_lvl + 2);
158                     self.print_expr(*init, depth_lvl + 3);
159                     print_indented!(self, ")", depth_lvl + 2);
160                 } else {
161                     print_indented!(self, "initializer: None", depth_lvl + 2);
162                 }
163
164                 if let Some(else_block) = else_block {
165                     print_indented!(self, "else_block: Some(", depth_lvl + 2);
166                     self.print_block(*else_block, depth_lvl + 3);
167                     print_indented!(self, ")", depth_lvl + 2);
168                 } else {
169                     print_indented!(self, "else_block: None", depth_lvl + 2);
170                 }
171
172                 print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2);
173                 print_indented!(self, "}", depth_lvl + 1);
174             }
175         }
176
177         print_indented!(self, "}", depth_lvl);
178     }
179
180     fn print_expr(&mut self, expr: ExprId, depth_lvl: usize) {
181         let Expr { ty, temp_lifetime, span, kind } = &self.thir[expr];
182         print_indented!(self, "Expr {", depth_lvl);
183         print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
184         print_indented!(self, format!("temp_lifetime: {:?}", temp_lifetime), depth_lvl + 1);
185         print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
186         print_indented!(self, "kind: ", depth_lvl + 1);
187         self.print_expr_kind(kind, depth_lvl + 2);
188         print_indented!(self, "}", depth_lvl);
189     }
190
191     fn print_expr_kind(&mut self, expr_kind: &ExprKind<'tcx>, depth_lvl: usize) {
192         use rustc_middle::thir::ExprKind::*;
193
194         match expr_kind {
195             Scope { region_scope, value, lint_level } => {
196                 print_indented!(self, "Scope {", depth_lvl);
197                 print_indented!(self, format!("region_scope: {:?}", region_scope), depth_lvl + 1);
198                 print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1);
199                 print_indented!(self, "value:", depth_lvl + 1);
200                 self.print_expr(*value, depth_lvl + 2);
201                 print_indented!(self, "}", depth_lvl);
202             }
203             Box { value } => {
204                 print_indented!(self, "Box {", depth_lvl);
205                 self.print_expr(*value, depth_lvl + 1);
206                 print_indented!(self, "}", depth_lvl);
207             }
208             If { if_then_scope, cond, then, else_opt } => {
209                 print_indented!(self, "If {", depth_lvl);
210                 print_indented!(self, format!("if_then_scope: {:?}", if_then_scope), depth_lvl + 1);
211                 print_indented!(self, "cond:", depth_lvl + 1);
212                 self.print_expr(*cond, depth_lvl + 2);
213                 print_indented!(self, "then:", depth_lvl + 1);
214                 self.print_expr(*then, depth_lvl + 2);
215
216                 if let Some(else_expr) = else_opt {
217                     print_indented!(self, "else:", depth_lvl + 1);
218                     self.print_expr(*else_expr, depth_lvl + 2);
219                 }
220
221                 print_indented!(self, "}", depth_lvl);
222             }
223             Call { fun, args, ty, from_hir_call, fn_span } => {
224                 print_indented!(self, "Call {", depth_lvl);
225                 print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
226                 print_indented!(self, format!("from_hir_call: {}", from_hir_call), depth_lvl + 1);
227                 print_indented!(self, format!("fn_span: {:?}", fn_span), depth_lvl + 1);
228                 print_indented!(self, "fun:", depth_lvl + 1);
229                 self.print_expr(*fun, depth_lvl + 2);
230
231                 if args.len() > 0 {
232                     print_indented!(self, "args: [", depth_lvl + 1);
233                     for arg in args.iter() {
234                         self.print_expr(*arg, depth_lvl + 2);
235                     }
236                     print_indented!(self, "]", depth_lvl + 1);
237                 } else {
238                     print_indented!(self, "args: []", depth_lvl + 1);
239                 }
240
241                 print_indented!(self, "}", depth_lvl);
242             }
243             Deref { arg } => {
244                 print_indented!(self, "Deref {", depth_lvl);
245                 self.print_expr(*arg, depth_lvl + 1);
246                 print_indented!(self, "}", depth_lvl);
247             }
248             Binary { op, lhs, rhs } => {
249                 print_indented!(self, "Binary {", depth_lvl);
250                 print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
251                 print_indented!(self, "lhs:", depth_lvl + 1);
252                 self.print_expr(*lhs, depth_lvl + 2);
253                 print_indented!(self, "rhs:", depth_lvl + 1);
254                 self.print_expr(*rhs, depth_lvl + 2);
255                 print_indented!(self, "}", depth_lvl);
256             }
257             LogicalOp { op, lhs, rhs } => {
258                 print_indented!(self, "LogicalOp {", depth_lvl);
259                 print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
260                 print_indented!(self, "lhs:", depth_lvl + 1);
261                 self.print_expr(*lhs, depth_lvl + 2);
262                 print_indented!(self, "rhs:", depth_lvl + 1);
263                 self.print_expr(*rhs, depth_lvl + 2);
264                 print_indented!(self, "}", depth_lvl);
265             }
266             Unary { op, arg } => {
267                 print_indented!(self, "Unary {", depth_lvl);
268                 print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
269                 print_indented!(self, "arg:", depth_lvl + 1);
270                 self.print_expr(*arg, depth_lvl + 2);
271                 print_indented!(self, "}", depth_lvl);
272             }
273             Cast { source } => {
274                 print_indented!(self, "Cast {", depth_lvl);
275                 print_indented!(self, "source:", depth_lvl + 1);
276                 self.print_expr(*source, depth_lvl + 2);
277                 print_indented!(self, "}", depth_lvl);
278             }
279             Use { source } => {
280                 print_indented!(self, "Use {", depth_lvl);
281                 print_indented!(self, "source:", depth_lvl + 1);
282                 self.print_expr(*source, depth_lvl + 2);
283                 print_indented!(self, "}", depth_lvl);
284             }
285             NeverToAny { source } => {
286                 print_indented!(self, "NeverToAny {", depth_lvl);
287                 print_indented!(self, "source:", depth_lvl + 1);
288                 self.print_expr(*source, depth_lvl + 2);
289                 print_indented!(self, "}", depth_lvl);
290             }
291             Pointer { cast, source } => {
292                 print_indented!(self, "Pointer {", depth_lvl);
293                 print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1);
294                 print_indented!(self, "source:", depth_lvl + 1);
295                 self.print_expr(*source, depth_lvl + 2);
296                 print_indented!(self, "}", depth_lvl);
297             }
298             Loop { body } => {
299                 print_indented!(self, "Loop (", depth_lvl);
300                 print_indented!(self, "body:", depth_lvl + 1);
301                 self.print_expr(*body, depth_lvl + 2);
302                 print_indented!(self, ")", depth_lvl);
303             }
304             Let { expr, pat } => {
305                 print_indented!(self, "Let {", depth_lvl);
306                 print_indented!(self, "expr:", depth_lvl + 1);
307                 self.print_expr(*expr, depth_lvl + 2);
308                 print_indented!(self, format!("pat: {:?}", pat), depth_lvl + 1);
309                 print_indented!(self, "}", depth_lvl);
310             }
311             Match { scrutinee, arms } => {
312                 print_indented!(self, "Match {", depth_lvl);
313                 print_indented!(self, "scrutinee:", depth_lvl + 1);
314                 self.print_expr(*scrutinee, depth_lvl + 2);
315
316                 print_indented!(self, "arms: [", depth_lvl + 1);
317                 for arm_id in arms.iter() {
318                     self.print_arm(*arm_id, depth_lvl + 2);
319                 }
320                 print_indented!(self, "]", depth_lvl + 1);
321                 print_indented!(self, "}", depth_lvl);
322             }
323             Block { block } => self.print_block(*block, depth_lvl),
324             Assign { lhs, rhs } => {
325                 print_indented!(self, "Assign {", depth_lvl);
326                 print_indented!(self, "lhs:", depth_lvl + 1);
327                 self.print_expr(*lhs, depth_lvl + 2);
328                 print_indented!(self, "rhs:", depth_lvl + 1);
329                 self.print_expr(*rhs, depth_lvl + 2);
330                 print_indented!(self, "}", depth_lvl);
331             }
332             AssignOp { op, lhs, rhs } => {
333                 print_indented!(self, "AssignOp {", depth_lvl);
334                 print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
335                 print_indented!(self, "lhs:", depth_lvl + 1);
336                 self.print_expr(*lhs, depth_lvl + 2);
337                 print_indented!(self, "rhs:", depth_lvl + 1);
338                 self.print_expr(*rhs, depth_lvl + 2);
339                 print_indented!(self, "}", depth_lvl);
340             }
341             Field { lhs, variant_index, name } => {
342                 print_indented!(self, "Field {", depth_lvl);
343                 print_indented!(self, format!("variant_index: {:?}", variant_index), depth_lvl + 1);
344                 print_indented!(self, format!("name: {:?}", name), depth_lvl + 1);
345                 print_indented!(self, "lhs:", depth_lvl + 1);
346                 self.print_expr(*lhs, depth_lvl + 2);
347                 print_indented!(self, "}", depth_lvl);
348             }
349             Index { lhs, index } => {
350                 print_indented!(self, "Index {", depth_lvl);
351                 print_indented!(self, format!("index: {:?}", index), depth_lvl + 1);
352                 print_indented!(self, "lhs:", depth_lvl + 1);
353                 self.print_expr(*lhs, depth_lvl + 2);
354                 print_indented!(self, "}", depth_lvl);
355             }
356             VarRef { id } => {
357                 print_indented!(self, "VarRef {", depth_lvl);
358                 print_indented!(self, format!("id: {:?}", id), depth_lvl + 1);
359                 print_indented!(self, "}", depth_lvl);
360             }
361             UpvarRef { closure_def_id, var_hir_id } => {
362                 print_indented!(self, "UpvarRef {", depth_lvl);
363                 print_indented!(
364                     self,
365                     format!("closure_def_id: {:?}", closure_def_id),
366                     depth_lvl + 1
367                 );
368                 print_indented!(self, format!("var_hir_id: {:?}", var_hir_id), depth_lvl + 1);
369                 print_indented!(self, "}", depth_lvl);
370             }
371             Borrow { borrow_kind, arg } => {
372                 print_indented!(self, "Borrow (", depth_lvl);
373                 print_indented!(self, format!("borrow_kind: {:?}", borrow_kind), depth_lvl + 1);
374                 print_indented!(self, "arg:", depth_lvl + 1);
375                 self.print_expr(*arg, depth_lvl + 2);
376                 print_indented!(self, ")", depth_lvl);
377             }
378             AddressOf { mutability, arg } => {
379                 print_indented!(self, "AddressOf {", depth_lvl);
380                 print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 1);
381                 print_indented!(self, "arg:", depth_lvl + 1);
382                 self.print_expr(*arg, depth_lvl + 2);
383                 print_indented!(self, "}", depth_lvl);
384             }
385             Break { label, value } => {
386                 print_indented!(self, "Break (", depth_lvl);
387                 print_indented!(self, format!("label: {:?}", label), depth_lvl + 1);
388
389                 if let Some(value) = value {
390                     print_indented!(self, "value:", depth_lvl + 1);
391                     self.print_expr(*value, depth_lvl + 2);
392                 }
393
394                 print_indented!(self, ")", depth_lvl);
395             }
396             Continue { label } => {
397                 print_indented!(self, "Continue {", depth_lvl);
398                 print_indented!(self, format!("label: {:?}", label), depth_lvl + 1);
399                 print_indented!(self, "}", depth_lvl);
400             }
401             Return { value } => {
402                 print_indented!(self, "Return {", depth_lvl);
403                 print_indented!(self, "value:", depth_lvl + 1);
404
405                 if let Some(value) = value {
406                     self.print_expr(*value, depth_lvl + 2);
407                 }
408
409                 print_indented!(self, "}", depth_lvl);
410             }
411             ConstBlock { did, substs } => {
412                 print_indented!(self, "ConstBlock {", depth_lvl);
413                 print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);
414                 print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
415                 print_indented!(self, "}", depth_lvl);
416             }
417             Repeat { value, count } => {
418                 print_indented!(self, "Repeat {", depth_lvl);
419                 print_indented!(self, format!("count: {:?}", count), depth_lvl + 1);
420                 print_indented!(self, "value:", depth_lvl + 1);
421                 self.print_expr(*value, depth_lvl + 2);
422                 print_indented!(self, "}", depth_lvl);
423             }
424             Array { fields } => {
425                 print_indented!(self, "Array {", depth_lvl);
426                 print_indented!(self, "fields: [", depth_lvl + 1);
427                 for field_id in fields.iter() {
428                     self.print_expr(*field_id, depth_lvl + 2);
429                 }
430                 print_indented!(self, "]", depth_lvl + 1);
431                 print_indented!(self, "}", depth_lvl);
432             }
433             Tuple { fields } => {
434                 print_indented!(self, "Tuple {", depth_lvl);
435                 print_indented!(self, "fields: [", depth_lvl + 1);
436                 for field_id in fields.iter() {
437                     self.print_expr(*field_id, depth_lvl + 2);
438                 }
439                 print_indented!(self, "]", depth_lvl + 1);
440                 print_indented!(self, "}", depth_lvl);
441             }
442             Adt(adt_expr) => {
443                 print_indented!(self, "Adt {", depth_lvl);
444                 self.print_adt_expr(&**adt_expr, depth_lvl + 1);
445                 print_indented!(self, "}", depth_lvl);
446             }
447             PlaceTypeAscription { source, user_ty } => {
448                 print_indented!(self, "PlaceTypeAscription {", depth_lvl);
449                 print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
450                 print_indented!(self, "source:", depth_lvl + 1);
451                 self.print_expr(*source, depth_lvl + 2);
452                 print_indented!(self, "}", depth_lvl);
453             }
454             ValueTypeAscription { source, user_ty } => {
455                 print_indented!(self, "ValueTypeAscription {", depth_lvl);
456                 print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
457                 print_indented!(self, "source:", depth_lvl + 1);
458                 self.print_expr(*source, depth_lvl + 2);
459                 print_indented!(self, "}", depth_lvl);
460             }
461             Closure(closure_expr) => {
462                 print_indented!(self, "Closure {", depth_lvl);
463                 print_indented!(self, "closure_expr:", depth_lvl + 1);
464                 self.print_closure_expr(&**closure_expr, depth_lvl + 2);
465                 print_indented!(self, "}", depth_lvl);
466             }
467             Literal { lit, neg } => {
468                 print_indented!(
469                     self,
470                     format!("Literal( lit: {:?}, neg: {:?})\n", lit, neg),
471                     depth_lvl
472                 );
473             }
474             NonHirLiteral { lit, user_ty } => {
475                 print_indented!(self, "NonHirLiteral {", depth_lvl);
476                 print_indented!(self, format!("lit: {:?}", lit), depth_lvl + 1);
477                 print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
478                 print_indented!(self, "}", depth_lvl);
479             }
480             ZstLiteral { user_ty } => {
481                 print_indented!(self, format!("ZstLiteral(user_ty: {:?})", user_ty), depth_lvl);
482             }
483             NamedConst { def_id, substs, user_ty } => {
484                 print_indented!(self, "NamedConst {", depth_lvl);
485                 print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
486                 print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
487                 print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
488                 print_indented!(self, "}", depth_lvl);
489             }
490             ConstParam { param, def_id } => {
491                 print_indented!(self, "ConstParam {", depth_lvl);
492                 print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
493                 print_indented!(self, format!("param: {:?}", param), depth_lvl + 1);
494                 print_indented!(self, "}", depth_lvl);
495             }
496             StaticRef { alloc_id, ty, def_id } => {
497                 print_indented!(self, "StaticRef {", depth_lvl);
498                 print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
499                 print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
500                 print_indented!(self, format!("alloc_id: {:?}", alloc_id), depth_lvl + 1);
501                 print_indented!(self, "}", depth_lvl);
502             }
503             InlineAsm(expr) => {
504                 print_indented!(self, "InlineAsm {", depth_lvl);
505                 print_indented!(self, "expr:", depth_lvl + 1);
506                 self.print_inline_asm_expr(&**expr, depth_lvl + 2);
507                 print_indented!(self, "}", depth_lvl);
508             }
509             ThreadLocalRef(def_id) => {
510                 print_indented!(self, "ThreadLocalRef {", depth_lvl);
511                 print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
512                 print_indented!(self, "}", depth_lvl);
513             }
514             Yield { value } => {
515                 print_indented!(self, "Yield {", depth_lvl);
516                 print_indented!(self, "value:", depth_lvl + 1);
517                 self.print_expr(*value, depth_lvl + 2);
518                 print_indented!(self, "}", depth_lvl);
519             }
520         }
521     }
522
523     fn print_adt_expr(&mut self, adt_expr: &AdtExpr<'tcx>, depth_lvl: usize) {
524         print_indented!(self, "adt_def:", depth_lvl);
525         self.print_adt_def(adt_expr.adt_def, depth_lvl + 1);
526         print_indented!(
527             self,
528             format!("variant_index: {:?}", adt_expr.variant_index),
529             depth_lvl + 1
530         );
531         print_indented!(self, format!("substs: {:?}", adt_expr.substs), depth_lvl + 1);
532         print_indented!(self, format!("user_ty: {:?}", adt_expr.user_ty), depth_lvl + 1);
533
534         for (i, field_expr) in adt_expr.fields.iter().enumerate() {
535             print_indented!(self, format!("field {}:", i), depth_lvl + 1);
536             self.print_expr(field_expr.expr, depth_lvl + 2);
537         }
538
539         if let Some(ref base) = adt_expr.base {
540             print_indented!(self, "base:", depth_lvl + 1);
541             self.print_fru_info(base, depth_lvl + 2);
542         } else {
543             print_indented!(self, "base: None", depth_lvl + 1);
544         }
545     }
546
547     fn print_adt_def(&mut self, adt_def: ty::AdtDef<'tcx>, depth_lvl: usize) {
548         print_indented!(self, "AdtDef {", depth_lvl);
549         print_indented!(self, format!("did: {:?}", adt_def.did()), depth_lvl + 1);
550         print_indented!(self, format!("variants: {:?}", adt_def.variants()), depth_lvl + 1);
551         print_indented!(self, format!("flags: {:?}", adt_def.flags()), depth_lvl + 1);
552         print_indented!(self, format!("repr: {:?}", adt_def.repr()), depth_lvl + 1);
553     }
554
555     fn print_fru_info(&mut self, fru_info: &FruInfo<'tcx>, depth_lvl: usize) {
556         print_indented!(self, "FruInfo {", depth_lvl);
557         print_indented!(self, "base: ", depth_lvl + 1);
558         self.print_expr(fru_info.base, depth_lvl + 2);
559         print_indented!(self, "field_types: [", depth_lvl + 1);
560         for ty in fru_info.field_types.iter() {
561             print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 2);
562         }
563         print_indented!(self, "}", depth_lvl);
564     }
565
566     fn print_arm(&mut self, arm_id: ArmId, depth_lvl: usize) {
567         print_indented!(self, "Arm {", depth_lvl);
568
569         let arm = &self.thir.arms[arm_id];
570         let Arm { pattern, guard, body, lint_level, scope, span } = arm;
571
572         print_indented!(self, "pattern: ", depth_lvl + 1);
573         self.print_pat(pattern, depth_lvl + 2);
574
575         if let Some(guard) = guard {
576             print_indented!(self, "guard: ", depth_lvl + 1);
577             self.print_guard(guard, depth_lvl + 2);
578         } else {
579             print_indented!(self, "guard: None", depth_lvl + 1);
580         }
581
582         print_indented!(self, "body: ", depth_lvl + 1);
583         self.print_expr(*body, depth_lvl + 2);
584         print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1);
585         print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 1);
586         print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
587         print_indented!(self, "}", depth_lvl);
588     }
589
590     fn print_pat(&mut self, pat: &Box<Pat<'tcx>>, depth_lvl: usize) {
591         let Pat { ty, span, kind } = &**pat;
592
593         print_indented!(self, "Pat: {", depth_lvl);
594         print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
595         print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
596         self.print_pat_kind(kind, depth_lvl + 1);
597         print_indented!(self, "}", depth_lvl);
598     }
599
600     fn print_pat_kind(&mut self, pat_kind: &PatKind<'tcx>, depth_lvl: usize) {
601         print_indented!(self, "kind: PatKind {", depth_lvl);
602
603         match pat_kind {
604             PatKind::Wild => {
605                 print_indented!(self, "Wild", depth_lvl + 1);
606             }
607             PatKind::AscribeUserType { ascription, subpattern } => {
608                 print_indented!(self, "AscribeUserType: {", depth_lvl + 1);
609                 print_indented!(self, format!("ascription: {:?}", ascription), depth_lvl + 2);
610                 print_indented!(self, "subpattern: ", depth_lvl + 2);
611                 self.print_pat(subpattern, depth_lvl + 3);
612                 print_indented!(self, "}", depth_lvl + 1);
613             }
614             PatKind::Binding { mutability, name, mode, var, ty, subpattern, is_primary } => {
615                 print_indented!(self, "Binding {", depth_lvl + 1);
616                 print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 2);
617                 print_indented!(self, format!("name: {:?}", name), depth_lvl + 2);
618                 print_indented!(self, format!("mode: {:?}", mode), depth_lvl + 2);
619                 print_indented!(self, format!("var: {:?}", var), depth_lvl + 2);
620                 print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 2);
621                 print_indented!(self, format!("is_primary: {:?}", is_primary), depth_lvl + 2);
622
623                 if let Some(subpattern) = subpattern {
624                     print_indented!(self, "subpattern: Some( ", depth_lvl + 2);
625                     self.print_pat(subpattern, depth_lvl + 3);
626                     print_indented!(self, ")", depth_lvl + 2);
627                 } else {
628                     print_indented!(self, "subpattern: None", depth_lvl + 2);
629                 }
630
631                 print_indented!(self, "}", depth_lvl + 1);
632             }
633             PatKind::Variant { adt_def, substs, variant_index, subpatterns } => {
634                 print_indented!(self, "Variant {", depth_lvl + 1);
635                 print_indented!(self, "adt_def: ", depth_lvl + 2);
636                 self.print_adt_def(*adt_def, depth_lvl + 3);
637                 print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 2);
638                 print_indented!(self, format!("variant_index: {:?}", variant_index), depth_lvl + 2);
639
640                 if subpatterns.len() > 0 {
641                     print_indented!(self, "subpatterns: [", depth_lvl + 2);
642                     for field_pat in subpatterns.iter() {
643                         self.print_pat(&field_pat.pattern, depth_lvl + 3);
644                     }
645                     print_indented!(self, "]", depth_lvl + 2);
646                 } else {
647                     print_indented!(self, "subpatterns: []", depth_lvl + 2);
648                 }
649
650                 print_indented!(self, "}", depth_lvl + 1);
651             }
652             PatKind::Leaf { subpatterns } => {
653                 print_indented!(self, "Leaf { ", depth_lvl + 1);
654                 print_indented!(self, "subpatterns: [", depth_lvl + 2);
655                 for field_pat in subpatterns.iter() {
656                     self.print_pat(&field_pat.pattern, depth_lvl + 3);
657                 }
658                 print_indented!(self, "]", depth_lvl + 2);
659                 print_indented!(self, "}", depth_lvl + 1);
660             }
661             PatKind::Deref { subpattern } => {
662                 print_indented!(self, "Deref { ", depth_lvl + 1);
663                 print_indented!(self, "subpattern: ", depth_lvl + 2);
664                 self.print_pat(subpattern, depth_lvl + 2);
665                 print_indented!(self, "}", depth_lvl + 1);
666             }
667             PatKind::Constant { value } => {
668                 print_indented!(self, "Constant {", depth_lvl + 1);
669                 print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
670                 print_indented!(self, "}", depth_lvl + 1);
671             }
672             PatKind::Range(pat_range) => {
673                 print_indented!(self, format!("Range ( {:?} )", pat_range), depth_lvl + 1);
674             }
675             PatKind::Slice { prefix, slice, suffix } => {
676                 print_indented!(self, "Slice {", depth_lvl + 1);
677
678                 print_indented!(self, "prefix: [", depth_lvl + 2);
679                 for prefix_pat in prefix.iter() {
680                     self.print_pat(prefix_pat, depth_lvl + 3);
681                 }
682                 print_indented!(self, "]", depth_lvl + 2);
683
684                 if let Some(slice) = slice {
685                     print_indented!(self, "slice: ", depth_lvl + 2);
686                     self.print_pat(slice, depth_lvl + 3);
687                 }
688
689                 print_indented!(self, "suffix: [", depth_lvl + 2);
690                 for suffix_pat in suffix.iter() {
691                     self.print_pat(suffix_pat, depth_lvl + 3);
692                 }
693                 print_indented!(self, "]", depth_lvl + 2);
694
695                 print_indented!(self, "}", depth_lvl + 1);
696             }
697             PatKind::Array { prefix, slice, suffix } => {
698                 print_indented!(self, "Array {", depth_lvl + 1);
699
700                 print_indented!(self, "prefix: [", depth_lvl + 2);
701                 for prefix_pat in prefix.iter() {
702                     self.print_pat(prefix_pat, depth_lvl + 3);
703                 }
704                 print_indented!(self, "]", depth_lvl + 2);
705
706                 if let Some(slice) = slice {
707                     print_indented!(self, "slice: ", depth_lvl + 2);
708                     self.print_pat(slice, depth_lvl + 3);
709                 }
710
711                 print_indented!(self, "suffix: [", depth_lvl + 2);
712                 for suffix_pat in suffix.iter() {
713                     self.print_pat(suffix_pat, depth_lvl + 3);
714                 }
715                 print_indented!(self, "]", depth_lvl + 2);
716
717                 print_indented!(self, "}", depth_lvl + 1);
718             }
719             PatKind::Or { pats } => {
720                 print_indented!(self, "Or {", depth_lvl + 1);
721                 print_indented!(self, "pats: [", depth_lvl + 2);
722                 for pat in pats.iter() {
723                     self.print_pat(pat, depth_lvl + 3);
724                 }
725                 print_indented!(self, "]", depth_lvl + 2);
726                 print_indented!(self, "}", depth_lvl + 1);
727             }
728         }
729
730         print_indented!(self, "}", depth_lvl);
731     }
732
733     fn print_guard(&mut self, guard: &Guard<'tcx>, depth_lvl: usize) {
734         print_indented!(self, "Guard {", depth_lvl);
735
736         match guard {
737             Guard::If(expr_id) => {
738                 print_indented!(self, "If (", depth_lvl + 1);
739                 self.print_expr(*expr_id, depth_lvl + 2);
740                 print_indented!(self, ")", depth_lvl + 1);
741             }
742             Guard::IfLet(pat, expr_id) => {
743                 print_indented!(self, "IfLet (", depth_lvl + 1);
744                 self.print_pat(pat, depth_lvl + 2);
745                 print_indented!(self, ",", depth_lvl + 1);
746                 self.print_expr(*expr_id, depth_lvl + 2);
747                 print_indented!(self, ")", depth_lvl + 1);
748             }
749         }
750
751         print_indented!(self, "}", depth_lvl);
752     }
753
754     fn print_closure_expr(&mut self, expr: &ClosureExpr<'tcx>, depth_lvl: usize) {
755         let ClosureExpr { closure_id, substs, upvars, movability, fake_reads } = expr;
756
757         print_indented!(self, "ClosureExpr {", depth_lvl);
758         print_indented!(self, format!("closure_id: {:?}", closure_id), depth_lvl + 1);
759         print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
760
761         if upvars.len() > 0 {
762             print_indented!(self, "upvars: [", depth_lvl + 1);
763             for upvar in upvars.iter() {
764                 self.print_expr(*upvar, depth_lvl + 2);
765                 print_indented!(self, ",", depth_lvl + 1);
766             }
767             print_indented!(self, "]", depth_lvl + 1);
768         } else {
769             print_indented!(self, "upvars: []", depth_lvl + 1);
770         }
771
772         print_indented!(self, format!("movability: {:?}", movability), depth_lvl + 1);
773
774         if fake_reads.len() > 0 {
775             print_indented!(self, "fake_reads: [", depth_lvl + 1);
776             for (fake_read_expr, cause, hir_id) in fake_reads.iter() {
777                 print_indented!(self, "(", depth_lvl + 2);
778                 self.print_expr(*fake_read_expr, depth_lvl + 3);
779                 print_indented!(self, ",", depth_lvl + 2);
780                 print_indented!(self, format!("cause: {:?}", cause), depth_lvl + 3);
781                 print_indented!(self, ",", depth_lvl + 2);
782                 print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 3);
783                 print_indented!(self, "),", depth_lvl + 2);
784             }
785             print_indented!(self, "]", depth_lvl + 1);
786         } else {
787             print_indented!(self, "fake_reads: []", depth_lvl + 1);
788         }
789
790         print_indented!(self, "}", depth_lvl);
791     }
792
793     fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
794         let InlineAsmExpr { template, operands, options, line_spans } = expr;
795
796         print_indented!(self, "InlineAsmExpr {", depth_lvl);
797
798         print_indented!(self, "template: [", depth_lvl + 1);
799         for template_piece in template.iter() {
800             print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);
801         }
802         print_indented!(self, "]", depth_lvl + 1);
803
804         print_indented!(self, "operands: [", depth_lvl + 1);
805         for operand in operands.iter() {
806             self.print_inline_operand(operand, depth_lvl + 2);
807         }
808         print_indented!(self, "]", depth_lvl + 1);
809
810         print_indented!(self, format!("options: {:?}", options), depth_lvl + 1);
811         print_indented!(self, format!("line_spans: {:?}", line_spans), depth_lvl + 1);
812     }
813
814     fn print_inline_operand(&mut self, operand: &InlineAsmOperand<'tcx>, depth_lvl: usize) {
815         match operand {
816             InlineAsmOperand::In { reg, expr } => {
817                 print_indented!(self, "InlineAsmOperand::In {", depth_lvl);
818                 print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
819                 print_indented!(self, "expr: ", depth_lvl + 1);
820                 self.print_expr(*expr, depth_lvl + 2);
821                 print_indented!(self, "}", depth_lvl + 1);
822             }
823             InlineAsmOperand::Out { reg, late, expr } => {
824                 print_indented!(self, "InlineAsmOperand::Out {", depth_lvl);
825                 print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
826                 print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
827
828                 if let Some(out) = expr {
829                     print_indented!(self, "place: Some( ", depth_lvl + 1);
830                     self.print_expr(*out, depth_lvl + 2);
831                     print_indented!(self, ")", depth_lvl + 1);
832                 } else {
833                     print_indented!(self, "place: None", depth_lvl + 1);
834                 }
835                 print_indented!(self, "}", depth_lvl + 1);
836             }
837             InlineAsmOperand::InOut { reg, late, expr } => {
838                 print_indented!(self, "InlineAsmOperand::InOut {", depth_lvl);
839                 print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
840                 print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
841                 print_indented!(self, "expr: ", depth_lvl + 1);
842                 self.print_expr(*expr, depth_lvl + 2);
843                 print_indented!(self, "}", depth_lvl + 1);
844             }
845             InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
846                 print_indented!(self, "InlineAsmOperand::SplitInOut {", depth_lvl);
847                 print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
848                 print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
849                 print_indented!(self, "in_expr: ", depth_lvl + 1);
850                 self.print_expr(*in_expr, depth_lvl + 2);
851
852                 if let Some(out_expr) = out_expr {
853                     print_indented!(self, "out_expr: Some( ", depth_lvl + 1);
854                     self.print_expr(*out_expr, depth_lvl + 2);
855                     print_indented!(self, ")", depth_lvl + 1);
856                 } else {
857                     print_indented!(self, "out_expr: None", depth_lvl + 1);
858                 }
859
860                 print_indented!(self, "}", depth_lvl + 1);
861             }
862             InlineAsmOperand::Const { value, span } => {
863                 print_indented!(self, "InlineAsmOperand::Const {", depth_lvl);
864                 print_indented!(self, format!("value: {:?}", value), depth_lvl + 1);
865                 print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
866                 print_indented!(self, "}", depth_lvl + 1);
867             }
868             InlineAsmOperand::SymFn { value, span } => {
869                 print_indented!(self, "InlineAsmOperand::SymFn {", depth_lvl);
870                 print_indented!(self, format!("value: {:?}", *value), depth_lvl + 1);
871                 print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
872                 print_indented!(self, "}", depth_lvl + 1);
873             }
874             InlineAsmOperand::SymStatic { def_id } => {
875                 print_indented!(self, "InlineAsmOperand::SymStatic {", depth_lvl);
876                 print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
877                 print_indented!(self, "}", depth_lvl + 1);
878             }
879         }
880     }
881 }