]>
Commit | Line | Data |
---|---|---|
c295e0f8 XL |
1 | use super::{ |
2 | Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir, | |
3 | }; | |
17df50a5 XL |
4 | |
5 | pub trait Visitor<'a, 'tcx: 'a>: Sized { | |
6 | fn thir(&self) -> &'a Thir<'tcx>; | |
7 | ||
8 | fn visit_expr(&mut self, expr: &Expr<'tcx>) { | |
9 | walk_expr(self, expr); | |
10 | } | |
11 | ||
12 | fn visit_stmt(&mut self, stmt: &Stmt<'tcx>) { | |
13 | walk_stmt(self, stmt); | |
14 | } | |
15 | ||
16 | fn visit_block(&mut self, block: &Block) { | |
17 | walk_block(self, block); | |
18 | } | |
19 | ||
20 | fn visit_arm(&mut self, arm: &Arm<'tcx>) { | |
21 | walk_arm(self, arm); | |
22 | } | |
23 | ||
136023e0 XL |
24 | fn visit_pat(&mut self, pat: &Pat<'tcx>) { |
25 | walk_pat(self, pat); | |
26 | } | |
17df50a5 XL |
27 | } |
28 | ||
29 | pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) { | |
30 | use ExprKind::*; | |
31 | match expr.kind { | |
32 | Scope { value, region_scope: _, lint_level: _ } => { | |
33 | visitor.visit_expr(&visitor.thir()[value]) | |
34 | } | |
35 | Box { value } => visitor.visit_expr(&visitor.thir()[value]), | |
94222f64 | 36 | If { cond, then, else_opt, if_then_scope: _ } => { |
17df50a5 XL |
37 | visitor.visit_expr(&visitor.thir()[cond]); |
38 | visitor.visit_expr(&visitor.thir()[then]); | |
39 | if let Some(else_expr) = else_opt { | |
40 | visitor.visit_expr(&visitor.thir()[else_expr]); | |
41 | } | |
42 | } | |
43 | Call { fun, ref args, ty: _, from_hir_call: _, fn_span: _ } => { | |
44 | visitor.visit_expr(&visitor.thir()[fun]); | |
45 | for &arg in &**args { | |
46 | visitor.visit_expr(&visitor.thir()[arg]); | |
47 | } | |
48 | } | |
49 | Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]), | |
50 | Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => { | |
51 | visitor.visit_expr(&visitor.thir()[lhs]); | |
52 | visitor.visit_expr(&visitor.thir()[rhs]); | |
53 | } | |
54 | Unary { arg, op: _ } => visitor.visit_expr(&visitor.thir()[arg]), | |
55 | Cast { source } => visitor.visit_expr(&visitor.thir()[source]), | |
56 | Use { source } => visitor.visit_expr(&visitor.thir()[source]), | |
57 | NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]), | |
58 | Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]), | |
94222f64 XL |
59 | Let { expr, .. } => { |
60 | visitor.visit_expr(&visitor.thir()[expr]); | |
61 | } | |
17df50a5 XL |
62 | Loop { body } => visitor.visit_expr(&visitor.thir()[body]), |
63 | Match { scrutinee, ref arms } => { | |
64 | visitor.visit_expr(&visitor.thir()[scrutinee]); | |
65 | for &arm in &**arms { | |
66 | visitor.visit_arm(&visitor.thir()[arm]); | |
67 | } | |
68 | } | |
69 | Block { ref body } => visitor.visit_block(body), | |
70 | Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => { | |
71 | visitor.visit_expr(&visitor.thir()[lhs]); | |
72 | visitor.visit_expr(&visitor.thir()[rhs]); | |
73 | } | |
74 | Field { lhs, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]), | |
75 | Index { lhs, index } => { | |
76 | visitor.visit_expr(&visitor.thir()[lhs]); | |
77 | visitor.visit_expr(&visitor.thir()[index]); | |
78 | } | |
79 | VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {} | |
80 | Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]), | |
81 | AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]), | |
82 | Break { value, label: _ } => { | |
83 | if let Some(value) = value { | |
84 | visitor.visit_expr(&visitor.thir()[value]) | |
85 | } | |
86 | } | |
87 | Continue { label: _ } => {} | |
88 | Return { value } => { | |
89 | if let Some(value) = value { | |
90 | visitor.visit_expr(&visitor.thir()[value]) | |
91 | } | |
92 | } | |
5e7ed085 FG |
93 | ConstBlock { did: _, substs: _ } => {} |
94 | Repeat { value, count: _ } => { | |
17df50a5 | 95 | visitor.visit_expr(&visitor.thir()[value]); |
17df50a5 XL |
96 | } |
97 | Array { ref fields } | Tuple { ref fields } => { | |
98 | for &field in &**fields { | |
99 | visitor.visit_expr(&visitor.thir()[field]); | |
100 | } | |
101 | } | |
c295e0f8 | 102 | Adt(box crate::thir::Adt { |
136023e0 XL |
103 | ref fields, |
104 | ref base, | |
105 | adt_def: _, | |
106 | variant_index: _, | |
107 | substs: _, | |
108 | user_ty: _, | |
109 | }) => { | |
17df50a5 XL |
110 | for field in &**fields { |
111 | visitor.visit_expr(&visitor.thir()[field.expr]); | |
112 | } | |
113 | if let Some(base) = base { | |
114 | visitor.visit_expr(&visitor.thir()[base.base]); | |
115 | } | |
116 | } | |
117 | PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => { | |
118 | visitor.visit_expr(&visitor.thir()[source]) | |
119 | } | |
120 | Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {} | |
5e7ed085 FG |
121 | Literal { lit: _, neg: _ } => {} |
122 | NonHirLiteral { lit: _, user_ty: _ } => {} | |
123 | NamedConst { def_id: _, substs: _, user_ty: _ } => {} | |
124 | ConstParam { param: _, def_id: _ } => {} | |
125 | StaticRef { alloc_id: _, ty: _, def_id: _ } => {} | |
17df50a5 XL |
126 | InlineAsm { ref operands, template: _, options: _, line_spans: _ } => { |
127 | for op in &**operands { | |
128 | use InlineAsmOperand::*; | |
129 | match op { | |
130 | In { expr, reg: _ } | |
131 | | Out { expr: Some(expr), reg: _, late: _ } | |
132 | | InOut { expr, reg: _, late: _ } | |
133 | | SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]), | |
134 | SplitInOut { in_expr, out_expr, reg: _, late: _ } => { | |
135 | visitor.visit_expr(&visitor.thir()[*in_expr]); | |
136 | if let Some(out_expr) = out_expr { | |
137 | visitor.visit_expr(&visitor.thir()[*out_expr]); | |
138 | } | |
139 | } | |
140 | Out { expr: None, reg: _, late: _ } | |
141 | | Const { value: _, span: _ } | |
142 | | SymStatic { def_id: _ } => {} | |
143 | } | |
144 | } | |
145 | } | |
146 | ThreadLocalRef(_) => {} | |
17df50a5 XL |
147 | Yield { value } => visitor.visit_expr(&visitor.thir()[value]), |
148 | } | |
149 | } | |
150 | ||
151 | pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stmt<'tcx>) { | |
136023e0 XL |
152 | match &stmt.kind { |
153 | StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[*expr]), | |
17df50a5 XL |
154 | StmtKind::Let { |
155 | initializer, | |
156 | remainder_scope: _, | |
157 | init_scope: _, | |
136023e0 | 158 | ref pattern, |
17df50a5 XL |
159 | lint_level: _, |
160 | } => { | |
161 | if let Some(init) = initializer { | |
136023e0 | 162 | visitor.visit_expr(&visitor.thir()[*init]); |
17df50a5 | 163 | } |
136023e0 | 164 | visitor.visit_pat(pattern); |
17df50a5 XL |
165 | } |
166 | } | |
167 | } | |
168 | ||
169 | pub fn walk_block<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, block: &Block) { | |
170 | for &stmt in &*block.stmts { | |
171 | visitor.visit_stmt(&visitor.thir()[stmt]); | |
172 | } | |
173 | if let Some(expr) = block.expr { | |
174 | visitor.visit_expr(&visitor.thir()[expr]); | |
175 | } | |
176 | } | |
177 | ||
178 | pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'tcx>) { | |
179 | match arm.guard { | |
180 | Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]), | |
136023e0 XL |
181 | Some(Guard::IfLet(ref pat, expr)) => { |
182 | visitor.visit_pat(pat); | |
17df50a5 XL |
183 | visitor.visit_expr(&visitor.thir()[expr]); |
184 | } | |
185 | None => {} | |
186 | } | |
136023e0 | 187 | visitor.visit_pat(&arm.pattern); |
17df50a5 XL |
188 | visitor.visit_expr(&visitor.thir()[arm.body]); |
189 | } | |
136023e0 XL |
190 | |
191 | pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) { | |
192 | use PatKind::*; | |
193 | match pat.kind.as_ref() { | |
194 | AscribeUserType { subpattern, ascription: _ } | |
195 | | Deref { subpattern } | |
196 | | Binding { | |
197 | subpattern: Some(subpattern), | |
198 | mutability: _, | |
199 | mode: _, | |
200 | var: _, | |
201 | ty: _, | |
202 | is_primary: _, | |
203 | name: _, | |
204 | } => visitor.visit_pat(&subpattern), | |
205 | Binding { .. } | Wild => {} | |
206 | Variant { subpatterns, adt_def: _, substs: _, variant_index: _ } | Leaf { subpatterns } => { | |
207 | for subpattern in subpatterns { | |
208 | visitor.visit_pat(&subpattern.pattern); | |
209 | } | |
210 | } | |
5e7ed085 FG |
211 | Constant { value: _ } => {} |
212 | Range(_) => {} | |
136023e0 XL |
213 | Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => { |
214 | for subpattern in prefix { | |
215 | visitor.visit_pat(&subpattern); | |
216 | } | |
217 | if let Some(pat) = slice { | |
218 | visitor.visit_pat(pat); | |
219 | } | |
220 | for subpattern in suffix { | |
221 | visitor.visit_pat(&subpattern); | |
222 | } | |
223 | } | |
224 | Or { pats } => { | |
225 | for pat in pats { | |
226 | visitor.visit_pat(&pat); | |
227 | } | |
228 | } | |
229 | }; | |
230 | } |