]>
Commit | Line | Data |
---|---|---|
92a42be0 SL |
1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
54a0048b SL |
11 | use middle::const_val::ConstVal; |
12 | use hir::def_id::DefId; | |
13 | use ty::subst::Substs; | |
14 | use ty::{ClosureSubsts, FnOutput, Region, Ty}; | |
92a42be0 | 15 | use mir::repr::*; |
54a0048b | 16 | use rustc_const_math::ConstUsize; |
9cc50fc6 SL |
17 | use rustc_data_structures::tuple_slice::TupleSlice; |
18 | use syntax::codemap::Span; | |
92a42be0 | 19 | |
54a0048b SL |
20 | // # The MIR Visitor |
21 | // | |
22 | // ## Overview | |
23 | // | |
24 | // There are two visitors, one for immutable and one for mutable references, | |
25 | // but both are generated by the following macro. The code is written according | |
26 | // to the following conventions: | |
27 | // | |
28 | // - introduce a `visit_foo` and a `super_foo` method for every MIR type | |
29 | // - `visit_foo`, by default, calls `super_foo` | |
30 | // - `super_foo`, by default, destructures the `foo` and calls `visit_foo` | |
31 | // | |
32 | // This allows you as a user to override `visit_foo` for types are | |
33 | // interested in, and invoke (within that method) call | |
34 | // `self.super_foo` to get the default behavior. Just as in an OO | |
35 | // language, you should never call `super` methods ordinarily except | |
36 | // in that circumstance. | |
37 | // | |
38 | // For the most part, we do not destructure things external to the | |
39 | // MIR, e.g. types, spans, etc, but simply visit them and stop. This | |
40 | // avoids duplication with other visitors like `TypeFoldable`. But | |
41 | // there is one exception: we do destructure the `FnOutput` to reach | |
42 | // the type within. Just because. | |
43 | // | |
44 | // ## Updating | |
45 | // | |
46 | // The code is written in a very deliberate style intended to minimize | |
47 | // the chance of things being overlooked. You'll notice that we always | |
48 | // use pattern matching to reference fields and we ensure that all | |
49 | // matches are exhaustive. | |
50 | // | |
51 | // For example, the `super_basic_block_data` method begins like this: | |
52 | // | |
53 | // ```rust | |
54 | // fn super_basic_block_data(&mut self, | |
55 | // block: BasicBlock, | |
56 | // data: & $($mutability)* BasicBlockData<'tcx>) { | |
57 | // let BasicBlockData { | |
58 | // ref $($mutability)* statements, | |
59 | // ref $($mutability)* terminator, | |
60 | // is_cleanup: _ | |
61 | // } = *data; | |
62 | // | |
63 | // for statement in statements { | |
64 | // self.visit_statement(block, statement); | |
65 | // } | |
66 | // | |
67 | // ... | |
68 | // } | |
69 | // ``` | |
70 | // | |
71 | // Here we used `let BasicBlockData { <fields> } = *data` deliberately, | |
72 | // rather than writing `data.statements` in the body. This is because if one | |
73 | // adds a new field to `BasicBlockData`, one will be forced to revise this code, | |
74 | // and hence one will (hopefully) invoke the correct visit methods (if any). | |
75 | // | |
76 | // For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS. | |
77 | // That means you never write `..` to skip over fields, nor do you write `_` | |
78 | // to skip over variants in a `match`. | |
79 | // | |
80 | // The only place that `_` is acceptable is to match a field (or | |
81 | // variant argument) that does not require visiting, as in | |
82 | // `is_cleanup` above. | |
83 | ||
9cc50fc6 SL |
84 | macro_rules! make_mir_visitor { |
85 | ($visitor_trait_name:ident, $($mutability:ident)*) => { | |
86 | pub trait $visitor_trait_name<'tcx> { | |
87 | // Override these, and call `self.super_xxx` to revert back to the | |
88 | // default behavior. | |
92a42be0 | 89 | |
9cc50fc6 SL |
90 | fn visit_mir(&mut self, mir: & $($mutability)* Mir<'tcx>) { |
91 | self.super_mir(mir); | |
92 | } | |
92a42be0 | 93 | |
9cc50fc6 SL |
94 | fn visit_basic_block_data(&mut self, |
95 | block: BasicBlock, | |
96 | data: & $($mutability)* BasicBlockData<'tcx>) { | |
97 | self.super_basic_block_data(block, data); | |
98 | } | |
92a42be0 | 99 | |
54a0048b SL |
100 | fn visit_scope_data(&mut self, |
101 | scope_data: & $($mutability)* ScopeData) { | |
102 | self.super_scope_data(scope_data); | |
103 | } | |
104 | ||
9cc50fc6 SL |
105 | fn visit_statement(&mut self, |
106 | block: BasicBlock, | |
107 | statement: & $($mutability)* Statement<'tcx>) { | |
108 | self.super_statement(block, statement); | |
92a42be0 | 109 | } |
9cc50fc6 SL |
110 | |
111 | fn visit_assign(&mut self, | |
112 | block: BasicBlock, | |
113 | lvalue: & $($mutability)* Lvalue<'tcx>, | |
114 | rvalue: & $($mutability)* Rvalue<'tcx>) { | |
115 | self.super_assign(block, lvalue, rvalue); | |
92a42be0 | 116 | } |
92a42be0 | 117 | |
9cc50fc6 SL |
118 | fn visit_terminator(&mut self, |
119 | block: BasicBlock, | |
120 | terminator: & $($mutability)* Terminator<'tcx>) { | |
121 | self.super_terminator(block, terminator); | |
122 | } | |
92a42be0 | 123 | |
54a0048b SL |
124 | fn visit_terminator_kind(&mut self, |
125 | block: BasicBlock, | |
126 | kind: & $($mutability)* TerminatorKind<'tcx>) { | |
127 | self.super_terminator_kind(block, kind); | |
128 | } | |
129 | ||
9cc50fc6 SL |
130 | fn visit_rvalue(&mut self, |
131 | rvalue: & $($mutability)* Rvalue<'tcx>) { | |
132 | self.super_rvalue(rvalue); | |
92a42be0 SL |
133 | } |
134 | ||
9cc50fc6 SL |
135 | fn visit_operand(&mut self, |
136 | operand: & $($mutability)* Operand<'tcx>) { | |
137 | self.super_operand(operand); | |
92a42be0 SL |
138 | } |
139 | ||
9cc50fc6 SL |
140 | fn visit_lvalue(&mut self, |
141 | lvalue: & $($mutability)* Lvalue<'tcx>, | |
142 | context: LvalueContext) { | |
143 | self.super_lvalue(lvalue, context); | |
92a42be0 SL |
144 | } |
145 | ||
54a0048b SL |
146 | fn visit_projection(&mut self, |
147 | lvalue: & $($mutability)* LvalueProjection<'tcx>, | |
148 | context: LvalueContext) { | |
149 | self.super_projection(lvalue, context); | |
150 | } | |
151 | ||
152 | fn visit_projection_elem(&mut self, | |
153 | lvalue: & $($mutability)* LvalueElem<'tcx>, | |
154 | context: LvalueContext) { | |
155 | self.super_projection_elem(lvalue, context); | |
156 | } | |
157 | ||
9cc50fc6 SL |
158 | fn visit_branch(&mut self, |
159 | source: BasicBlock, | |
160 | target: BasicBlock) { | |
161 | self.super_branch(source, target); | |
92a42be0 SL |
162 | } |
163 | ||
9cc50fc6 SL |
164 | fn visit_constant(&mut self, |
165 | constant: & $($mutability)* Constant<'tcx>) { | |
166 | self.super_constant(constant); | |
92a42be0 SL |
167 | } |
168 | ||
9cc50fc6 SL |
169 | fn visit_literal(&mut self, |
170 | literal: & $($mutability)* Literal<'tcx>) { | |
171 | self.super_literal(literal); | |
92a42be0 | 172 | } |
92a42be0 | 173 | |
9cc50fc6 SL |
174 | fn visit_def_id(&mut self, |
175 | def_id: & $($mutability)* DefId) { | |
176 | self.super_def_id(def_id); | |
92a42be0 SL |
177 | } |
178 | ||
9cc50fc6 SL |
179 | fn visit_span(&mut self, |
180 | span: & $($mutability)* Span) { | |
181 | self.super_span(span); | |
92a42be0 SL |
182 | } |
183 | ||
54a0048b SL |
184 | fn visit_fn_output(&mut self, |
185 | fn_output: & $($mutability)* FnOutput<'tcx>) { | |
186 | self.super_fn_output(fn_output); | |
187 | } | |
188 | ||
189 | fn visit_ty(&mut self, | |
190 | ty: & $($mutability)* Ty<'tcx>) { | |
191 | self.super_ty(ty); | |
192 | } | |
193 | ||
194 | fn visit_substs(&mut self, | |
195 | substs: & $($mutability)* &'tcx Substs<'tcx>) { | |
196 | self.super_substs(substs); | |
197 | } | |
198 | ||
199 | fn visit_closure_substs(&mut self, | |
200 | substs: & $($mutability)* &'tcx ClosureSubsts<'tcx>) { | |
201 | self.super_closure_substs(substs); | |
202 | } | |
203 | ||
204 | fn visit_const_val(&mut self, | |
205 | const_val: & $($mutability)* ConstVal) { | |
206 | self.super_const_val(const_val); | |
207 | } | |
208 | ||
209 | fn visit_const_usize(&mut self, | |
210 | const_usize: & $($mutability)* ConstUsize) { | |
211 | self.super_const_usize(const_usize); | |
212 | } | |
213 | ||
214 | fn visit_typed_const_val(&mut self, | |
215 | val: & $($mutability)* TypedConstVal<'tcx>) { | |
216 | self.super_typed_const_val(val); | |
217 | } | |
218 | ||
219 | fn visit_var_decl(&mut self, | |
220 | var_decl: & $($mutability)* VarDecl<'tcx>) { | |
221 | self.super_var_decl(var_decl); | |
222 | } | |
223 | ||
224 | fn visit_temp_decl(&mut self, | |
225 | temp_decl: & $($mutability)* TempDecl<'tcx>) { | |
226 | self.super_temp_decl(temp_decl); | |
227 | } | |
228 | ||
229 | fn visit_arg_decl(&mut self, | |
230 | arg_decl: & $($mutability)* ArgDecl<'tcx>) { | |
231 | self.super_arg_decl(arg_decl); | |
232 | } | |
233 | ||
234 | fn visit_scope_id(&mut self, | |
235 | scope_id: & $($mutability)* ScopeId) { | |
236 | self.super_scope_id(scope_id); | |
237 | } | |
238 | ||
9cc50fc6 | 239 | // The `super_xxx` methods comprise the default behavior and are |
7453a54e | 240 | // not meant to be overridden. |
9cc50fc6 SL |
241 | |
242 | fn super_mir(&mut self, | |
243 | mir: & $($mutability)* Mir<'tcx>) { | |
54a0048b SL |
244 | let Mir { |
245 | ref $($mutability)* basic_blocks, | |
246 | ref $($mutability)* scopes, | |
247 | ref $($mutability)* return_ty, | |
248 | ref $($mutability)* var_decls, | |
249 | ref $($mutability)* arg_decls, | |
250 | ref $($mutability)* temp_decls, | |
251 | ref $($mutability)* span, | |
252 | } = *mir; | |
253 | ||
254 | for (index, data) in basic_blocks.into_iter().enumerate() { | |
255 | let block = BasicBlock::new(index); | |
9cc50fc6 SL |
256 | self.visit_basic_block_data(block, data); |
257 | } | |
54a0048b SL |
258 | |
259 | for scope in scopes { | |
260 | self.visit_scope_data(scope); | |
261 | } | |
262 | ||
263 | self.visit_fn_output(return_ty); | |
264 | ||
265 | for var_decl in var_decls { | |
266 | self.visit_var_decl(var_decl); | |
267 | } | |
268 | ||
269 | for arg_decl in arg_decls { | |
270 | self.visit_arg_decl(arg_decl); | |
271 | } | |
272 | ||
273 | for temp_decl in temp_decls { | |
274 | self.visit_temp_decl(temp_decl); | |
275 | } | |
276 | ||
277 | self.visit_span(span); | |
92a42be0 SL |
278 | } |
279 | ||
9cc50fc6 SL |
280 | fn super_basic_block_data(&mut self, |
281 | block: BasicBlock, | |
282 | data: & $($mutability)* BasicBlockData<'tcx>) { | |
54a0048b SL |
283 | let BasicBlockData { |
284 | ref $($mutability)* statements, | |
285 | ref $($mutability)* terminator, | |
286 | is_cleanup: _ | |
287 | } = *data; | |
288 | ||
289 | for statement in statements { | |
9cc50fc6 SL |
290 | self.visit_statement(block, statement); |
291 | } | |
292 | ||
54a0048b | 293 | if let Some(ref $($mutability)* terminator) = *terminator { |
9cc50fc6 SL |
294 | self.visit_terminator(block, terminator); |
295 | } | |
92a42be0 SL |
296 | } |
297 | ||
54a0048b SL |
298 | fn super_scope_data(&mut self, |
299 | scope_data: & $($mutability)* ScopeData) { | |
300 | let ScopeData { | |
301 | ref $($mutability)* parent_scope, | |
302 | } = *scope_data; | |
303 | ||
304 | if let Some(ref $($mutability)* parent_scope) = *parent_scope { | |
305 | self.visit_scope_id(parent_scope); | |
306 | } | |
307 | } | |
308 | ||
9cc50fc6 SL |
309 | fn super_statement(&mut self, |
310 | block: BasicBlock, | |
311 | statement: & $($mutability)* Statement<'tcx>) { | |
54a0048b SL |
312 | let Statement { |
313 | ref $($mutability)* span, | |
314 | ref $($mutability)* scope, | |
315 | ref $($mutability)* kind, | |
316 | } = *statement; | |
317 | ||
318 | self.visit_span(span); | |
319 | self.visit_scope_id(scope); | |
320 | match *kind { | |
9cc50fc6 SL |
321 | StatementKind::Assign(ref $($mutability)* lvalue, |
322 | ref $($mutability)* rvalue) => { | |
323 | self.visit_assign(block, lvalue, rvalue); | |
324 | } | |
9cc50fc6 | 325 | } |
92a42be0 SL |
326 | } |
327 | ||
9cc50fc6 SL |
328 | fn super_assign(&mut self, |
329 | _block: BasicBlock, | |
330 | lvalue: &$($mutability)* Lvalue<'tcx>, | |
331 | rvalue: &$($mutability)* Rvalue<'tcx>) { | |
332 | self.visit_lvalue(lvalue, LvalueContext::Store); | |
333 | self.visit_rvalue(rvalue); | |
92a42be0 SL |
334 | } |
335 | ||
9cc50fc6 SL |
336 | fn super_terminator(&mut self, |
337 | block: BasicBlock, | |
338 | terminator: &$($mutability)* Terminator<'tcx>) { | |
54a0048b SL |
339 | let Terminator { |
340 | ref $($mutability)* span, | |
341 | ref $($mutability)* scope, | |
342 | ref $($mutability)* kind, | |
343 | } = *terminator; | |
344 | ||
345 | self.visit_span(span); | |
346 | self.visit_scope_id(scope); | |
347 | self.visit_terminator_kind(block, kind); | |
348 | } | |
349 | ||
350 | fn super_terminator_kind(&mut self, | |
351 | block: BasicBlock, | |
352 | kind: & $($mutability)* TerminatorKind<'tcx>) { | |
353 | match *kind { | |
354 | TerminatorKind::Goto { target } => { | |
9cc50fc6 SL |
355 | self.visit_branch(block, target); |
356 | } | |
357 | ||
54a0048b SL |
358 | TerminatorKind::If { ref $($mutability)* cond, |
359 | ref $($mutability)* targets } => { | |
9cc50fc6 SL |
360 | self.visit_operand(cond); |
361 | for &target in targets.as_slice() { | |
362 | self.visit_branch(block, target); | |
363 | } | |
364 | } | |
365 | ||
54a0048b SL |
366 | TerminatorKind::Switch { ref $($mutability)* discr, |
367 | adt_def: _, | |
368 | ref targets } => { | |
9cc50fc6 SL |
369 | self.visit_lvalue(discr, LvalueContext::Inspect); |
370 | for &target in targets { | |
371 | self.visit_branch(block, target); | |
372 | } | |
373 | } | |
374 | ||
54a0048b SL |
375 | TerminatorKind::SwitchInt { ref $($mutability)* discr, |
376 | ref $($mutability)* switch_ty, | |
377 | ref $($mutability)* values, | |
378 | ref targets } => { | |
9cc50fc6 | 379 | self.visit_lvalue(discr, LvalueContext::Inspect); |
54a0048b SL |
380 | self.visit_ty(switch_ty); |
381 | for value in values { | |
382 | self.visit_const_val(value); | |
383 | } | |
9cc50fc6 SL |
384 | for &target in targets { |
385 | self.visit_branch(block, target); | |
386 | } | |
387 | } | |
388 | ||
54a0048b SL |
389 | TerminatorKind::Resume | |
390 | TerminatorKind::Return => { | |
9cc50fc6 SL |
391 | } |
392 | ||
54a0048b SL |
393 | TerminatorKind::Drop { ref $($mutability)* value, |
394 | target, | |
395 | unwind } => { | |
7453a54e SL |
396 | self.visit_lvalue(value, LvalueContext::Drop); |
397 | self.visit_branch(block, target); | |
398 | unwind.map(|t| self.visit_branch(block, t)); | |
399 | } | |
400 | ||
54a0048b SL |
401 | TerminatorKind::Call { ref $($mutability)* func, |
402 | ref $($mutability)* args, | |
403 | ref $($mutability)* destination, | |
404 | cleanup } => { | |
9cc50fc6 SL |
405 | self.visit_operand(func); |
406 | for arg in args { | |
407 | self.visit_operand(arg); | |
408 | } | |
7453a54e | 409 | if let Some((ref $($mutability)* destination, target)) = *destination { |
54a0048b | 410 | self.visit_lvalue(destination, LvalueContext::Call); |
9cc50fc6 SL |
411 | self.visit_branch(block, target); |
412 | } | |
7453a54e | 413 | cleanup.map(|t| self.visit_branch(block, t)); |
9cc50fc6 SL |
414 | } |
415 | } | |
92a42be0 SL |
416 | } |
417 | ||
9cc50fc6 SL |
418 | fn super_rvalue(&mut self, |
419 | rvalue: & $($mutability)* Rvalue<'tcx>) { | |
420 | match *rvalue { | |
421 | Rvalue::Use(ref $($mutability)* operand) => { | |
422 | self.visit_operand(operand); | |
423 | } | |
424 | ||
425 | Rvalue::Repeat(ref $($mutability)* value, | |
54a0048b | 426 | ref $($mutability)* typed_const_val) => { |
9cc50fc6 | 427 | self.visit_operand(value); |
54a0048b | 428 | self.visit_typed_const_val(typed_const_val); |
9cc50fc6 SL |
429 | } |
430 | ||
431 | Rvalue::Ref(r, bk, ref $($mutability)* path) => { | |
432 | self.visit_lvalue(path, LvalueContext::Borrow { | |
433 | region: r, | |
434 | kind: bk | |
435 | }); | |
436 | } | |
437 | ||
438 | Rvalue::Len(ref $($mutability)* path) => { | |
439 | self.visit_lvalue(path, LvalueContext::Inspect); | |
440 | } | |
441 | ||
54a0048b SL |
442 | Rvalue::Cast(_cast_kind, |
443 | ref $($mutability)* operand, | |
444 | ref $($mutability)* ty) => { | |
9cc50fc6 | 445 | self.visit_operand(operand); |
54a0048b | 446 | self.visit_ty(ty); |
9cc50fc6 SL |
447 | } |
448 | ||
54a0048b | 449 | Rvalue::BinaryOp(_bin_op, |
9cc50fc6 SL |
450 | ref $($mutability)* lhs, |
451 | ref $($mutability)* rhs) => { | |
452 | self.visit_operand(lhs); | |
453 | self.visit_operand(rhs); | |
454 | } | |
455 | ||
54a0048b | 456 | Rvalue::UnaryOp(_un_op, ref $($mutability)* op) => { |
9cc50fc6 SL |
457 | self.visit_operand(op); |
458 | } | |
459 | ||
54a0048b SL |
460 | Rvalue::Box(ref $($mutability)* ty) => { |
461 | self.visit_ty(ty); | |
9cc50fc6 SL |
462 | } |
463 | ||
464 | Rvalue::Aggregate(ref $($mutability)* kind, | |
465 | ref $($mutability)* operands) => { | |
466 | match *kind { | |
54a0048b SL |
467 | AggregateKind::Vec => { |
468 | } | |
469 | AggregateKind::Tuple => { | |
470 | } | |
471 | AggregateKind::Adt(_adt_def, | |
472 | _variant_index, | |
473 | ref $($mutability)* substs) => { | |
474 | self.visit_substs(substs); | |
475 | } | |
476 | AggregateKind::Closure(ref $($mutability)* def_id, | |
477 | ref $($mutability)* closure_substs) => { | |
9cc50fc6 | 478 | self.visit_def_id(def_id); |
54a0048b | 479 | self.visit_closure_substs(closure_substs); |
9cc50fc6 | 480 | } |
9cc50fc6 SL |
481 | } |
482 | ||
54a0048b | 483 | for operand in operands { |
9cc50fc6 SL |
484 | self.visit_operand(operand); |
485 | } | |
486 | } | |
487 | ||
488 | Rvalue::Slice { ref $($mutability)* input, | |
489 | from_start, | |
490 | from_end } => { | |
491 | self.visit_lvalue(input, LvalueContext::Slice { | |
492 | from_start: from_start, | |
493 | from_end: from_end, | |
494 | }); | |
495 | } | |
496 | ||
54a0048b SL |
497 | Rvalue::InlineAsm { ref $($mutability)* outputs, |
498 | ref $($mutability)* inputs, | |
499 | asm: _ } => { | |
500 | for output in & $($mutability)* outputs[..] { | |
501 | self.visit_lvalue(output, LvalueContext::Store); | |
502 | } | |
503 | for input in & $($mutability)* inputs[..] { | |
504 | self.visit_operand(input); | |
505 | } | |
9cc50fc6 SL |
506 | } |
507 | } | |
92a42be0 SL |
508 | } |
509 | ||
9cc50fc6 SL |
510 | fn super_operand(&mut self, |
511 | operand: & $($mutability)* Operand<'tcx>) { | |
512 | match *operand { | |
513 | Operand::Consume(ref $($mutability)* lvalue) => { | |
514 | self.visit_lvalue(lvalue, LvalueContext::Consume); | |
515 | } | |
516 | Operand::Constant(ref $($mutability)* constant) => { | |
517 | self.visit_constant(constant); | |
518 | } | |
92a42be0 SL |
519 | } |
520 | } | |
521 | ||
9cc50fc6 SL |
522 | fn super_lvalue(&mut self, |
523 | lvalue: & $($mutability)* Lvalue<'tcx>, | |
54a0048b | 524 | context: LvalueContext) { |
9cc50fc6 SL |
525 | match *lvalue { |
526 | Lvalue::Var(_) | | |
527 | Lvalue::Temp(_) | | |
528 | Lvalue::Arg(_) | | |
529 | Lvalue::ReturnPointer => { | |
530 | } | |
531 | Lvalue::Static(ref $($mutability)* def_id) => { | |
532 | self.visit_def_id(def_id); | |
533 | } | |
534 | Lvalue::Projection(ref $($mutability)* proj) => { | |
54a0048b | 535 | self.visit_projection(proj, context); |
9cc50fc6 SL |
536 | } |
537 | } | |
92a42be0 SL |
538 | } |
539 | ||
54a0048b SL |
540 | fn super_projection(&mut self, |
541 | proj: & $($mutability)* LvalueProjection<'tcx>, | |
542 | context: LvalueContext) { | |
543 | let Projection { | |
544 | ref $($mutability)* base, | |
545 | ref $($mutability)* elem, | |
546 | } = *proj; | |
547 | self.visit_lvalue(base, LvalueContext::Projection); | |
548 | self.visit_projection_elem(elem, context); | |
549 | } | |
550 | ||
551 | fn super_projection_elem(&mut self, | |
552 | proj: & $($mutability)* LvalueElem<'tcx>, | |
553 | _context: LvalueContext) { | |
554 | match *proj { | |
555 | ProjectionElem::Deref => { | |
556 | } | |
557 | ProjectionElem::Field(_field, ref $($mutability)* ty) => { | |
558 | self.visit_ty(ty); | |
559 | } | |
560 | ProjectionElem::Index(ref $($mutability)* operand) => { | |
561 | self.visit_operand(operand); | |
562 | } | |
563 | ProjectionElem::ConstantIndex { offset: _, | |
564 | min_length: _, | |
565 | from_end: _ } => { | |
566 | } | |
567 | ProjectionElem::Downcast(_adt_def, _variant_index) => { | |
568 | } | |
569 | } | |
570 | } | |
571 | ||
572 | fn super_var_decl(&mut self, | |
573 | var_decl: & $($mutability)* VarDecl<'tcx>) { | |
574 | let VarDecl { | |
575 | mutability: _, | |
576 | name: _, | |
577 | ref $($mutability)* ty, | |
578 | ref $($mutability)* scope, | |
579 | ref $($mutability)* span, | |
580 | } = *var_decl; | |
581 | ||
582 | self.visit_ty(ty); | |
583 | self.visit_scope_id(scope); | |
584 | self.visit_span(span); | |
585 | } | |
586 | ||
587 | fn super_temp_decl(&mut self, | |
588 | temp_decl: & $($mutability)* TempDecl<'tcx>) { | |
589 | let TempDecl { | |
590 | ref $($mutability)* ty, | |
591 | } = *temp_decl; | |
592 | ||
593 | self.visit_ty(ty); | |
594 | } | |
595 | ||
596 | fn super_arg_decl(&mut self, | |
597 | arg_decl: & $($mutability)* ArgDecl<'tcx>) { | |
598 | let ArgDecl { | |
599 | ref $($mutability)* ty, | |
600 | spread: _ | |
601 | } = *arg_decl; | |
602 | ||
603 | self.visit_ty(ty); | |
604 | } | |
605 | ||
606 | fn super_scope_id(&mut self, | |
607 | _scope_id: & $($mutability)* ScopeId) { | |
608 | } | |
609 | ||
9cc50fc6 SL |
610 | fn super_branch(&mut self, |
611 | _source: BasicBlock, | |
612 | _target: BasicBlock) { | |
92a42be0 | 613 | } |
92a42be0 | 614 | |
9cc50fc6 SL |
615 | fn super_constant(&mut self, |
616 | constant: & $($mutability)* Constant<'tcx>) { | |
54a0048b SL |
617 | let Constant { |
618 | ref $($mutability)* span, | |
619 | ref $($mutability)* ty, | |
620 | ref $($mutability)* literal, | |
621 | } = *constant; | |
622 | ||
623 | self.visit_span(span); | |
624 | self.visit_ty(ty); | |
625 | self.visit_literal(literal); | |
626 | } | |
627 | ||
628 | fn super_typed_const_val(&mut self, | |
629 | constant: & $($mutability)* TypedConstVal<'tcx>) { | |
630 | let TypedConstVal { | |
631 | ref $($mutability)* span, | |
632 | ref $($mutability)* ty, | |
633 | ref $($mutability)* value, | |
634 | } = *constant; | |
635 | ||
636 | self.visit_span(span); | |
637 | self.visit_ty(ty); | |
638 | self.visit_const_usize(value); | |
92a42be0 | 639 | } |
9cc50fc6 SL |
640 | |
641 | fn super_literal(&mut self, | |
642 | literal: & $($mutability)* Literal<'tcx>) { | |
643 | match *literal { | |
54a0048b SL |
644 | Literal::Item { ref $($mutability)* def_id, |
645 | ref $($mutability)* substs } => { | |
9cc50fc6 | 646 | self.visit_def_id(def_id); |
54a0048b | 647 | self.visit_substs(substs); |
9cc50fc6 | 648 | }, |
54a0048b SL |
649 | Literal::Value { ref $($mutability)* value } => { |
650 | self.visit_const_val(value); | |
9cc50fc6 SL |
651 | } |
652 | } | |
92a42be0 | 653 | } |
92a42be0 | 654 | |
9cc50fc6 | 655 | fn super_def_id(&mut self, _def_id: & $($mutability)* DefId) { |
92a42be0 | 656 | } |
9cc50fc6 SL |
657 | |
658 | fn super_span(&mut self, _span: & $($mutability)* Span) { | |
92a42be0 | 659 | } |
54a0048b SL |
660 | |
661 | fn super_fn_output(&mut self, fn_output: & $($mutability)* FnOutput<'tcx>) { | |
662 | match *fn_output { | |
663 | FnOutput::FnConverging(ref $($mutability)* ty) => { | |
664 | self.visit_ty(ty); | |
665 | } | |
666 | FnOutput::FnDiverging => { | |
667 | } | |
668 | } | |
669 | } | |
670 | ||
671 | fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) { | |
672 | } | |
673 | ||
674 | fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) { | |
675 | } | |
676 | ||
677 | fn super_closure_substs(&mut self, | |
678 | _substs: & $($mutability)* &'tcx ClosureSubsts<'tcx>) { | |
679 | } | |
680 | ||
681 | fn super_const_val(&mut self, _substs: & $($mutability)* ConstVal) { | |
682 | } | |
683 | ||
684 | fn super_const_usize(&mut self, _substs: & $($mutability)* ConstUsize) { | |
685 | } | |
92a42be0 SL |
686 | } |
687 | } | |
92a42be0 SL |
688 | } |
689 | ||
9cc50fc6 SL |
690 | make_mir_visitor!(Visitor,); |
691 | make_mir_visitor!(MutVisitor,mut); | |
692 | ||
92a42be0 SL |
693 | #[derive(Copy, Clone, Debug)] |
694 | pub enum LvalueContext { | |
54a0048b | 695 | // Appears as LHS of an assignment |
92a42be0 SL |
696 | Store, |
697 | ||
54a0048b SL |
698 | // Dest of a call |
699 | Call, | |
700 | ||
92a42be0 SL |
701 | // Being dropped |
702 | Drop, | |
703 | ||
704 | // Being inspected in some way, like loading a len | |
705 | Inspect, | |
706 | ||
707 | // Being borrowed | |
708 | Borrow { region: Region, kind: BorrowKind }, | |
709 | ||
710 | // Being sliced -- this should be same as being borrowed, probably | |
711 | Slice { from_start: usize, from_end: usize }, | |
712 | ||
713 | // Used as base for another lvalue, e.g. `x` in `x.y` | |
714 | Projection, | |
715 | ||
716 | // Consumed as part of an operand | |
717 | Consume, | |
718 | } |