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