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