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