]> git.proxmox.com Git - rustc.git/blame - src/librustc/mir/visit.rs
Imported Upstream version 1.9.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;
14use ty::{ClosureSubsts, FnOutput, Region, Ty};
92a42be0 15use mir::repr::*;
54a0048b 16use rustc_const_math::ConstUsize;
9cc50fc6
SL
17use rustc_data_structures::tuple_slice::TupleSlice;
18use 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
84macro_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
690make_mir_visitor!(Visitor,);
691make_mir_visitor!(MutVisitor,mut);
692
92a42be0
SL
693#[derive(Copy, Clone, Debug)]
694pub 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}