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