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