]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/thir/visit.rs
bump version to 1.81.0+dfsg1-2~bpo12+pve1
[rustc.git] / compiler / rustc_middle / src / thir / visit.rs
CommitLineData
c295e0f8 1use super::{
c0240ec0 2 AdtExpr, Arm, Block, ClosureExpr, Expr, ExprKind, InlineAsmExpr, InlineAsmOperand, Pat,
f2b60f7d 3 PatKind, Stmt, StmtKind, Thir,
c295e0f8 4};
17df50a5 5
c0240ec0
FG
6pub trait Visitor<'thir, 'tcx: 'thir>: Sized {
7 fn thir(&self) -> &'thir Thir<'tcx>;
17df50a5 8
c0240ec0 9 fn visit_expr(&mut self, expr: &'thir Expr<'tcx>) {
17df50a5
XL
10 walk_expr(self, expr);
11 }
12
c0240ec0 13 fn visit_stmt(&mut self, stmt: &'thir Stmt<'tcx>) {
17df50a5
XL
14 walk_stmt(self, stmt);
15 }
16
c0240ec0 17 fn visit_block(&mut self, block: &'thir Block) {
17df50a5
XL
18 walk_block(self, block);
19 }
20
c0240ec0 21 fn visit_arm(&mut self, arm: &'thir Arm<'tcx>) {
17df50a5
XL
22 walk_arm(self, arm);
23 }
24
c0240ec0 25 fn visit_pat(&mut self, pat: &'thir Pat<'tcx>) {
136023e0
XL
26 walk_pat(self, pat);
27 }
04454e1e 28
781aab86 29 // Note: We don't have visitors for `ty::Const` and `mir::Const`
04454e1e
FG
30 // (even though these types occur in THIR) for consistency and to reduce confusion,
31 // since the lazy creation of constants during thir construction causes most
781aab86 32 // 'constants' to not be of type `ty::Const` or `mir::Const` at that
04454e1e
FG
33 // stage (they are mostly still identified by `DefId` or `hir::Lit`, see
34 // the variants `Literal`, `NonHirLiteral` and `NamedConst` in `thir::ExprKind`).
781aab86 35 // You have to manually visit `ty::Const` and `mir::Const` through the
04454e1e 36 // other `visit*` functions.
17df50a5
XL
37}
38
c0240ec0
FG
39pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
40 visitor: &mut V,
41 expr: &'thir Expr<'tcx>,
42) {
17df50a5
XL
43 use ExprKind::*;
44 match expr.kind {
45 Scope { value, region_scope: _, lint_level: _ } => {
46 visitor.visit_expr(&visitor.thir()[value])
47 }
48 Box { value } => visitor.visit_expr(&visitor.thir()[value]),
94222f64 49 If { cond, then, else_opt, if_then_scope: _ } => {
17df50a5
XL
50 visitor.visit_expr(&visitor.thir()[cond]);
51 visitor.visit_expr(&visitor.thir()[then]);
52 if let Some(else_expr) = else_opt {
53 visitor.visit_expr(&visitor.thir()[else_expr]);
54 }
55 }
56 Call { fun, ref args, ty: _, from_hir_call: _, fn_span: _ } => {
57 visitor.visit_expr(&visitor.thir()[fun]);
58 for &arg in &**args {
59 visitor.visit_expr(&visitor.thir()[arg]);
60 }
61 }
62 Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]),
63 Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
64 visitor.visit_expr(&visitor.thir()[lhs]);
65 visitor.visit_expr(&visitor.thir()[rhs]);
66 }
67 Unary { arg, op: _ } => visitor.visit_expr(&visitor.thir()[arg]),
68 Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
69 Use { source } => visitor.visit_expr(&visitor.thir()[source]),
70 NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
fe692bf9 71 PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
ed00b5ec 72 Let { expr, ref pat } => {
94222f64 73 visitor.visit_expr(&visitor.thir()[expr]);
ed00b5ec 74 visitor.visit_pat(pat);
94222f64 75 }
17df50a5 76 Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
add651ee 77 Match { scrutinee, ref arms, .. } => {
17df50a5
XL
78 visitor.visit_expr(&visitor.thir()[scrutinee]);
79 for &arm in &**arms {
80 visitor.visit_arm(&visitor.thir()[arm]);
81 }
82 }
f2b60f7d 83 Block { block } => visitor.visit_block(&visitor.thir()[block]),
17df50a5
XL
84 Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
85 visitor.visit_expr(&visitor.thir()[lhs]);
86 visitor.visit_expr(&visitor.thir()[rhs]);
87 }
923072b8 88 Field { lhs, variant_index: _, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
17df50a5
XL
89 Index { lhs, index } => {
90 visitor.visit_expr(&visitor.thir()[lhs]);
91 visitor.visit_expr(&visitor.thir()[index]);
92 }
93 VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
94 Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
95 AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
96 Break { value, label: _ } => {
97 if let Some(value) = value {
98 visitor.visit_expr(&visitor.thir()[value])
99 }
100 }
101 Continue { label: _ } => {}
102 Return { value } => {
103 if let Some(value) = value {
104 visitor.visit_expr(&visitor.thir()[value])
105 }
106 }
fe692bf9 107 Become { value } => visitor.visit_expr(&visitor.thir()[value]),
add651ee 108 ConstBlock { did: _, args: _ } => {}
5e7ed085 109 Repeat { value, count: _ } => {
17df50a5 110 visitor.visit_expr(&visitor.thir()[value]);
17df50a5
XL
111 }
112 Array { ref fields } | Tuple { ref fields } => {
113 for &field in &**fields {
114 visitor.visit_expr(&visitor.thir()[field]);
115 }
116 }
f2b60f7d 117 Adt(box AdtExpr {
136023e0
XL
118 ref fields,
119 ref base,
120 adt_def: _,
121 variant_index: _,
add651ee 122 args: _,
136023e0
XL
123 user_ty: _,
124 }) => {
17df50a5
XL
125 for field in &**fields {
126 visitor.visit_expr(&visitor.thir()[field.expr]);
127 }
128 if let Some(base) = base {
129 visitor.visit_expr(&visitor.thir()[base.base]);
130 }
131 }
132 PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
133 visitor.visit_expr(&visitor.thir()[source])
134 }
f2b60f7d
FG
135 Closure(box ClosureExpr {
136 closure_id: _,
add651ee 137 args: _,
f2b60f7d
FG
138 upvars: _,
139 movability: _,
140 fake_reads: _,
141 }) => {}
5e7ed085
FG
142 Literal { lit: _, neg: _ } => {}
143 NonHirLiteral { lit: _, user_ty: _ } => {}
064997fb 144 ZstLiteral { user_ty: _ } => {}
add651ee 145 NamedConst { def_id: _, args: _, user_ty: _ } => {}
5e7ed085
FG
146 ConstParam { param: _, def_id: _ } => {}
147 StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
f2b60f7d 148 InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
17df50a5
XL
149 for op in &**operands {
150 use InlineAsmOperand::*;
151 match op {
152 In { expr, reg: _ }
153 | Out { expr: Some(expr), reg: _, late: _ }
04454e1e 154 | InOut { expr, reg: _, late: _ } => visitor.visit_expr(&visitor.thir()[*expr]),
17df50a5
XL
155 SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
156 visitor.visit_expr(&visitor.thir()[*in_expr]);
157 if let Some(out_expr) = out_expr {
158 visitor.visit_expr(&visitor.thir()[*out_expr]);
159 }
160 }
161 Out { expr: None, reg: _, late: _ }
162 | Const { value: _, span: _ }
04454e1e 163 | SymFn { value: _, span: _ }
17df50a5 164 | SymStatic { def_id: _ } => {}
c620b35d 165 Label { block } => visitor.visit_block(&visitor.thir()[*block]),
17df50a5
XL
166 }
167 }
168 }
49aad941 169 OffsetOf { container: _, fields: _ } => {}
17df50a5 170 ThreadLocalRef(_) => {}
17df50a5
XL
171 Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
172 }
173}
174
c0240ec0
FG
175pub fn walk_stmt<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
176 visitor: &mut V,
177 stmt: &'thir Stmt<'tcx>,
178) {
136023e0
XL
179 match &stmt.kind {
180 StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[*expr]),
17df50a5
XL
181 StmtKind::Let {
182 initializer,
183 remainder_scope: _,
184 init_scope: _,
136023e0 185 ref pattern,
17df50a5 186 lint_level: _,
064997fb 187 else_block,
353b0b11 188 span: _,
17df50a5
XL
189 } => {
190 if let Some(init) = initializer {
136023e0 191 visitor.visit_expr(&visitor.thir()[*init]);
17df50a5 192 }
136023e0 193 visitor.visit_pat(pattern);
064997fb 194 if let Some(block) = else_block {
f2b60f7d 195 visitor.visit_block(&visitor.thir()[*block])
064997fb 196 }
17df50a5
XL
197 }
198 }
199}
200
c0240ec0
FG
201pub fn walk_block<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
202 visitor: &mut V,
203 block: &'thir Block,
204) {
17df50a5
XL
205 for &stmt in &*block.stmts {
206 visitor.visit_stmt(&visitor.thir()[stmt]);
207 }
208 if let Some(expr) = block.expr {
209 visitor.visit_expr(&visitor.thir()[expr]);
210 }
211}
212
c0240ec0
FG
213pub fn walk_arm<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
214 visitor: &mut V,
215 arm: &'thir Arm<'tcx>,
216) {
217 if let Some(expr) = arm.guard {
218 visitor.visit_expr(&visitor.thir()[expr])
17df50a5 219 }
136023e0 220 visitor.visit_pat(&arm.pattern);
17df50a5
XL
221 visitor.visit_expr(&visitor.thir()[arm.body]);
222}
136023e0 223
c0240ec0
FG
224pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
225 visitor: &mut V,
226 pat: &'thir Pat<'tcx>,
227) {
136023e0 228 use PatKind::*;
f2b60f7d 229 match &pat.kind {
136023e0
XL
230 AscribeUserType { subpattern, ascription: _ }
231 | Deref { subpattern }
e8be2606
FG
232 | DerefPattern { subpattern, .. }
233 | Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(subpattern),
4b012472 234 Binding { .. } | Wild | Never | Error(_) => {}
add651ee 235 Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
136023e0
XL
236 for subpattern in subpatterns {
237 visitor.visit_pat(&subpattern.pattern);
238 }
239 }
5e7ed085 240 Constant { value: _ } => {}
ed00b5ec 241 InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern),
5e7ed085 242 Range(_) => {}
136023e0 243 Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
f2b60f7d 244 for subpattern in prefix.iter() {
ed00b5ec 245 visitor.visit_pat(subpattern);
136023e0
XL
246 }
247 if let Some(pat) = slice {
ed00b5ec 248 visitor.visit_pat(pat);
136023e0 249 }
f2b60f7d 250 for subpattern in suffix.iter() {
ed00b5ec 251 visitor.visit_pat(subpattern);
136023e0
XL
252 }
253 }
254 Or { pats } => {
f2b60f7d 255 for pat in pats.iter() {
4b012472 256 visitor.visit_pat(pat);
136023e0
XL
257 }
258 }
259 };
260}