2 use crate::ty::{self, TyCtxt};
4 use std::fmt::{self, Write};
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);
14 struct ThirPrinter<'a, 'tcx> {
19 const INDENT: &str = " ";
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");
28 impl<'a, 'tcx> Write for ThirPrinter<'a, 'tcx> {
29 fn write_str(&mut self, s: &str) -> fmt::Result {
35 impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
36 fn new(thir: &'a Thir<'tcx>) -> Self {
37 Self { thir, fmt: String::new() }
41 print_indented!(self, "params: [", 0);
42 for param in self.thir.params.iter() {
43 self.print_param(param, 1);
45 print_indented!(self, "]", 0);
47 print_indented!(self, "body:", 0);
48 let expr = ExprId::from_usize(self.thir.exprs.len() - 1);
49 self.print_expr(expr, 1);
52 fn into_buffer(self) -> String {
56 fn print_param(&mut self, param: &Param<'tcx>, depth_lvl: usize) {
57 let Param { pat, ty, ty_span, self_kind, hir_id } = param;
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);
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);
70 print_indented!(self, "param: None", depth_lvl + 1);
73 print_indented!(self, "}", depth_lvl);
76 fn print_block(&mut self, block_id: BlockId, depth_lvl: usize) {
79 opt_destruction_scope,
85 } = &self.thir.blocks[block_id];
87 print_indented!(self, "Block {", depth_lvl);
88 print_indented!(self, format!("targeted_by_break: {}", targeted_by_break), depth_lvl + 1);
91 format!("opt_destruction_scope: {:?}", opt_destruction_scope),
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);
99 print_indented!(self, "stmts: [", depth_lvl + 1);
100 for stmt in stmts.iter() {
101 self.print_stmt(*stmt, depth_lvl + 2);
103 print_indented!(self, "]", depth_lvl + 1);
105 print_indented!(self, "stmts: []", depth_lvl + 1);
108 if let Some(expr_id) = expr {
109 print_indented!(self, "expr:", depth_lvl + 1);
110 self.print_expr(*expr_id, depth_lvl + 2);
112 print_indented!(self, "expr: []", depth_lvl + 1);
115 print_indented!(self, "}", depth_lvl);
118 fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) {
119 let Stmt { kind, opt_destruction_scope } = &self.thir.stmts[stmt_id];
121 print_indented!(self, "Stmt {", depth_lvl);
124 format!("opt_destruction_scope: {:?}", opt_destruction_scope),
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);
144 print_indented!(self, "kind: Let {", depth_lvl + 1);
147 format!("remainder_scope: {:?}", remainder_scope),
150 print_indented!(self, format!("init_scope: {:?}", init_scope), depth_lvl + 2);
152 print_indented!(self, "pattern: ", depth_lvl + 2);
153 self.print_pat(pattern, depth_lvl + 3);
154 print_indented!(self, ",", depth_lvl + 2);
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);
161 print_indented!(self, "initializer: None", depth_lvl + 2);
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);
169 print_indented!(self, "else_block: None", depth_lvl + 2);
172 print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2);
173 print_indented!(self, "}", depth_lvl + 1);
177 print_indented!(self, "}", depth_lvl);
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);
191 fn print_expr_kind(&mut self, expr_kind: &ExprKind<'tcx>, depth_lvl: usize) {
192 use rustc_middle::thir::ExprKind::*;
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);
204 print_indented!(self, "Box {", depth_lvl);
205 self.print_expr(*value, depth_lvl + 1);
206 print_indented!(self, "}", depth_lvl);
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);
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);
221 print_indented!(self, "}", depth_lvl);
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);
232 print_indented!(self, "args: [", depth_lvl + 1);
233 for arg in args.iter() {
234 self.print_expr(*arg, depth_lvl + 2);
236 print_indented!(self, "]", depth_lvl + 1);
238 print_indented!(self, "args: []", depth_lvl + 1);
241 print_indented!(self, "}", depth_lvl);
244 print_indented!(self, "Deref {", depth_lvl);
245 self.print_expr(*arg, depth_lvl + 1);
246 print_indented!(self, "}", depth_lvl);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
316 print_indented!(self, "arms: [", depth_lvl + 1);
317 for arm_id in arms.iter() {
318 self.print_arm(*arm_id, depth_lvl + 2);
320 print_indented!(self, "]", depth_lvl + 1);
321 print_indented!(self, "}", depth_lvl);
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);
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);
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);
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);
357 print_indented!(self, "VarRef {", depth_lvl);
358 print_indented!(self, format!("id: {:?}", id), depth_lvl + 1);
359 print_indented!(self, "}", depth_lvl);
361 UpvarRef { closure_def_id, var_hir_id } => {
362 print_indented!(self, "UpvarRef {", depth_lvl);
365 format!("closure_def_id: {:?}", closure_def_id),
368 print_indented!(self, format!("var_hir_id: {:?}", var_hir_id), depth_lvl + 1);
369 print_indented!(self, "}", depth_lvl);
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);
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);
385 Break { label, value } => {
386 print_indented!(self, "Break (", depth_lvl);
387 print_indented!(self, format!("label: {:?}", label), depth_lvl + 1);
389 if let Some(value) = value {
390 print_indented!(self, "value:", depth_lvl + 1);
391 self.print_expr(*value, depth_lvl + 2);
394 print_indented!(self, ")", depth_lvl);
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);
401 Return { value } => {
402 print_indented!(self, "Return {", depth_lvl);
403 print_indented!(self, "value:", depth_lvl + 1);
405 if let Some(value) = value {
406 self.print_expr(*value, depth_lvl + 2);
409 print_indented!(self, "}", depth_lvl);
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);
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);
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);
430 print_indented!(self, "]", depth_lvl + 1);
431 print_indented!(self, "}", depth_lvl);
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);
439 print_indented!(self, "]", depth_lvl + 1);
440 print_indented!(self, "}", depth_lvl);
443 print_indented!(self, "Adt {", depth_lvl);
444 self.print_adt_expr(&**adt_expr, depth_lvl + 1);
445 print_indented!(self, "}", depth_lvl);
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);
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);
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);
467 Literal { lit, neg } => {
470 format!("Literal( lit: {:?}, neg: {:?})\n", lit, neg),
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);
480 ZstLiteral { user_ty } => {
481 print_indented!(self, format!("ZstLiteral(user_ty: {:?})", user_ty), depth_lvl);
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);
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);
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);
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);
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);
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);
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);
528 format!("variant_index: {:?}", adt_expr.variant_index),
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);
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);
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);
543 print_indented!(self, "base: None", depth_lvl + 1);
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);
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);
563 print_indented!(self, "}", depth_lvl);
566 fn print_arm(&mut self, arm_id: ArmId, depth_lvl: usize) {
567 print_indented!(self, "Arm {", depth_lvl);
569 let arm = &self.thir.arms[arm_id];
570 let Arm { pattern, guard, body, lint_level, scope, span } = arm;
572 print_indented!(self, "pattern: ", depth_lvl + 1);
573 self.print_pat(pattern, depth_lvl + 2);
575 if let Some(guard) = guard {
576 print_indented!(self, "guard: ", depth_lvl + 1);
577 self.print_guard(guard, depth_lvl + 2);
579 print_indented!(self, "guard: None", depth_lvl + 1);
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);
590 fn print_pat(&mut self, pat: &Box<Pat<'tcx>>, depth_lvl: usize) {
591 let Pat { ty, span, kind } = &**pat;
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);
600 fn print_pat_kind(&mut self, pat_kind: &PatKind<'tcx>, depth_lvl: usize) {
601 print_indented!(self, "kind: PatKind {", depth_lvl);
605 print_indented!(self, "Wild", depth_lvl + 1);
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);
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);
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);
628 print_indented!(self, "subpattern: None", depth_lvl + 2);
631 print_indented!(self, "}", depth_lvl + 1);
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);
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);
645 print_indented!(self, "]", depth_lvl + 2);
647 print_indented!(self, "subpatterns: []", depth_lvl + 2);
650 print_indented!(self, "}", depth_lvl + 1);
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);
658 print_indented!(self, "]", depth_lvl + 2);
659 print_indented!(self, "}", depth_lvl + 1);
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);
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);
672 PatKind::Range(pat_range) => {
673 print_indented!(self, format!("Range ( {:?} )", pat_range), depth_lvl + 1);
675 PatKind::Slice { prefix, slice, suffix } => {
676 print_indented!(self, "Slice {", depth_lvl + 1);
678 print_indented!(self, "prefix: [", depth_lvl + 2);
679 for prefix_pat in prefix.iter() {
680 self.print_pat(prefix_pat, depth_lvl + 3);
682 print_indented!(self, "]", depth_lvl + 2);
684 if let Some(slice) = slice {
685 print_indented!(self, "slice: ", depth_lvl + 2);
686 self.print_pat(slice, depth_lvl + 3);
689 print_indented!(self, "suffix: [", depth_lvl + 2);
690 for suffix_pat in suffix.iter() {
691 self.print_pat(suffix_pat, depth_lvl + 3);
693 print_indented!(self, "]", depth_lvl + 2);
695 print_indented!(self, "}", depth_lvl + 1);
697 PatKind::Array { prefix, slice, suffix } => {
698 print_indented!(self, "Array {", depth_lvl + 1);
700 print_indented!(self, "prefix: [", depth_lvl + 2);
701 for prefix_pat in prefix.iter() {
702 self.print_pat(prefix_pat, depth_lvl + 3);
704 print_indented!(self, "]", depth_lvl + 2);
706 if let Some(slice) = slice {
707 print_indented!(self, "slice: ", depth_lvl + 2);
708 self.print_pat(slice, depth_lvl + 3);
711 print_indented!(self, "suffix: [", depth_lvl + 2);
712 for suffix_pat in suffix.iter() {
713 self.print_pat(suffix_pat, depth_lvl + 3);
715 print_indented!(self, "]", depth_lvl + 2);
717 print_indented!(self, "}", depth_lvl + 1);
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);
725 print_indented!(self, "]", depth_lvl + 2);
726 print_indented!(self, "}", depth_lvl + 1);
730 print_indented!(self, "}", depth_lvl);
733 fn print_guard(&mut self, guard: &Guard<'tcx>, depth_lvl: usize) {
734 print_indented!(self, "Guard {", depth_lvl);
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);
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);
751 print_indented!(self, "}", depth_lvl);
754 fn print_closure_expr(&mut self, expr: &ClosureExpr<'tcx>, depth_lvl: usize) {
755 let ClosureExpr { closure_id, substs, upvars, movability, fake_reads } = expr;
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);
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);
767 print_indented!(self, "]", depth_lvl + 1);
769 print_indented!(self, "upvars: []", depth_lvl + 1);
772 print_indented!(self, format!("movability: {:?}", movability), depth_lvl + 1);
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);
785 print_indented!(self, "]", depth_lvl + 1);
787 print_indented!(self, "fake_reads: []", depth_lvl + 1);
790 print_indented!(self, "}", depth_lvl);
793 fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
794 let InlineAsmExpr { template, operands, options, line_spans } = expr;
796 print_indented!(self, "InlineAsmExpr {", depth_lvl);
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);
802 print_indented!(self, "]", depth_lvl + 1);
804 print_indented!(self, "operands: [", depth_lvl + 1);
805 for operand in operands.iter() {
806 self.print_inline_operand(operand, depth_lvl + 2);
808 print_indented!(self, "]", depth_lvl + 1);
810 print_indented!(self, format!("options: {:?}", options), depth_lvl + 1);
811 print_indented!(self, format!("line_spans: {:?}", line_spans), depth_lvl + 1);
814 fn print_inline_operand(&mut self, operand: &InlineAsmOperand<'tcx>, depth_lvl: usize) {
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);
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);
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);
833 print_indented!(self, "place: None", depth_lvl + 1);
835 print_indented!(self, "}", depth_lvl + 1);
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);
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);
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);
857 print_indented!(self, "out_expr: None", depth_lvl + 1);
860 print_indented!(self, "}", depth_lvl + 1);
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);
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);
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);