visit.rs 26.7 KB
Newer Older
N
Niko Matsakis 已提交
1 2 3 4 5 6 7 8 9 10
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

N
Niko Matsakis 已提交
11
use middle::const_eval::ConstVal;
12
use middle::def_id::DefId;
N
Niko Matsakis 已提交
13 14
use middle::subst::Substs;
use middle::ty::{ClosureSubsts, FnOutput, Region, Ty};
15
use mir::repr::*;
N
Niko Matsakis 已提交
16
use rustc_const_eval::ConstUsize;
17
use rustc_data_structures::tuple_slice::TupleSlice;
18
use syntax::codemap::Span;
N
Niko Matsakis 已提交
19

N
Niko Matsakis 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
// # The MIR Visitor
//
// ## Overview
//
// There are two visitors, one for immutable and one for mutable references,
// but both are generated by the following macro. The code is written according
// to the following conventions:
//
// - introduce a `visit_foo` and a `super_foo` method for every MIR type
// - `visit_foo`, by default, calls `super_foo`
// - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
//
// This allows you as a user to override `visit_foo` for types are
// interested in, and invoke (within that method) call
// `self.super_foo` to get the default behavior. Just as in an OO
// language, you should never call `super` methods ordinarily except
// in that circumstance.
//
// For the most part, we do not destructure things external to the
// MIR, e.g. types, spans, etc, but simply visit them and stop. This
// avoids duplication with other visitors like `TypeFoldable`. But
// there is one exception: we do destructure the `FnOutput` to reach
// the type within. Just because.
//
// ## Updating
//
// The code is written in a very deliberate style intended to minimize
// the chance of things being overlooked. You'll notice that we always
// use pattern matching to reference fields and we ensure that all
// matches are exhaustive.
//
// For example, the `super_basic_block_data` method begins like this:
//
// ```rust
// fn super_basic_block_data(&mut self,
//                           block: BasicBlock,
//                           data: & $($mutability)* BasicBlockData<'tcx>) {
//     let BasicBlockData {
//         ref $($mutability)* statements,
//         ref $($mutability)* terminator,
//         is_cleanup: _
//     } = *data;
//
//     for statement in statements {
//         self.visit_statement(block, statement);
//     }
//
//     ...
// }
// ```
//
// Here we used `let BasicBlockData { <fields> } = *data` deliberately,
// rather than writing `data.statements` in the body. This is because if one
// adds a new field to `BasicBlockData`, one will be forced to revise this code,
// and hence one will (hopefully) invoke the correct visit methods (if any).
//
// For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
// That means you never write `..` to skip over fields, nor do you write `_`
// to skip over variants in a `match`.
//
// The only place that `_` is acceptable is to match a field (or
// variant argument) that does not require visiting, as in
// `is_cleanup` above.

84 85 86 87 88
macro_rules! make_mir_visitor {
    ($visitor_trait_name:ident, $($mutability:ident)*) => {
        pub trait $visitor_trait_name<'tcx> {
            // Override these, and call `self.super_xxx` to revert back to the
            // default behavior.
N
Niko Matsakis 已提交
89

90 91
            fn visit_mir(&mut self, mir: & $($mutability)* Mir<'tcx>) {
                self.super_mir(mir);
N
Niko Matsakis 已提交
92 93
            }

94 95 96 97
            fn visit_basic_block_data(&mut self,
                                      block: BasicBlock,
                                      data: & $($mutability)* BasicBlockData<'tcx>) {
                self.super_basic_block_data(block, data);
N
Niko Matsakis 已提交
98 99
            }

N
Niko Matsakis 已提交
100 101 102 103 104
            fn visit_scope_data(&mut self,
                                scope_data: & $($mutability)* ScopeData) {
                self.super_scope_data(scope_data);
            }

105 106 107 108
            fn visit_statement(&mut self,
                               block: BasicBlock,
                               statement: & $($mutability)* Statement<'tcx>) {
                self.super_statement(block, statement);
N
Niko Matsakis 已提交
109 110
            }

111 112 113 114 115
            fn visit_assign(&mut self,
                            block: BasicBlock,
                            lvalue: & $($mutability)* Lvalue<'tcx>,
                            rvalue: & $($mutability)* Rvalue<'tcx>) {
                self.super_assign(block, lvalue, rvalue);
N
Niko Matsakis 已提交
116 117
            }

118 119 120 121
            fn visit_terminator(&mut self,
                                block: BasicBlock,
                                terminator: & $($mutability)* Terminator<'tcx>) {
                self.super_terminator(block, terminator);
122 123
            }

N
Niko Matsakis 已提交
124 125 126 127 128 129
            fn visit_terminator_kind(&mut self,
                                     block: BasicBlock,
                                     kind: & $($mutability)* TerminatorKind<'tcx>) {
                self.super_terminator_kind(block, kind);
            }

130 131 132
            fn visit_rvalue(&mut self,
                            rvalue: & $($mutability)* Rvalue<'tcx>) {
                self.super_rvalue(rvalue);
N
Niko Matsakis 已提交
133 134
            }

135 136 137
            fn visit_operand(&mut self,
                             operand: & $($mutability)* Operand<'tcx>) {
                self.super_operand(operand);
138
            }
N
Niko Matsakis 已提交
139

140 141 142 143
            fn visit_lvalue(&mut self,
                            lvalue: & $($mutability)* Lvalue<'tcx>,
                            context: LvalueContext) {
                self.super_lvalue(lvalue, context);
N
Niko Matsakis 已提交
144 145
            }

N
Niko Matsakis 已提交
146 147 148 149 150 151 152 153 154 155 156 157
            fn visit_projection(&mut self,
                                lvalue: & $($mutability)* LvalueProjection<'tcx>,
                                context: LvalueContext) {
                self.super_projection(lvalue, context);
            }

            fn visit_projection_elem(&mut self,
                                     lvalue: & $($mutability)* LvalueElem<'tcx>,
                                     context: LvalueContext) {
                self.super_projection_elem(lvalue, context);
            }

158 159 160 161
            fn visit_branch(&mut self,
                            source: BasicBlock,
                            target: BasicBlock) {
                self.super_branch(source, target);
N
Niko Matsakis 已提交
162 163
            }

164 165 166
            fn visit_constant(&mut self,
                              constant: & $($mutability)* Constant<'tcx>) {
                self.super_constant(constant);
N
Niko Matsakis 已提交
167 168
            }

169 170 171
            fn visit_literal(&mut self,
                             literal: & $($mutability)* Literal<'tcx>) {
                self.super_literal(literal);
N
Niko Matsakis 已提交
172 173
            }

174 175 176
            fn visit_def_id(&mut self,
                            def_id: & $($mutability)* DefId) {
                self.super_def_id(def_id);
N
Niko Matsakis 已提交
177 178
            }

179 180 181
            fn visit_span(&mut self,
                          span: & $($mutability)* Span) {
                self.super_span(span);
N
Niko Matsakis 已提交
182 183
            }

N
Niko Matsakis 已提交
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
            fn visit_fn_output(&mut self,
                               fn_output: & $($mutability)* FnOutput<'tcx>) {
                self.super_fn_output(fn_output);
            }

            fn visit_ty(&mut self,
                        ty: & $($mutability)* Ty<'tcx>) {
                self.super_ty(ty);
            }

            fn visit_substs(&mut self,
                            substs: & $($mutability)* &'tcx Substs<'tcx>) {
                self.super_substs(substs);
            }

            fn visit_closure_substs(&mut self,
                                    substs: & $($mutability)* &'tcx ClosureSubsts<'tcx>) {
                self.super_closure_substs(substs);
            }

            fn visit_const_val(&mut self,
                               const_val: & $($mutability)* ConstVal) {
                self.super_const_val(const_val);
            }

            fn visit_const_usize(&mut self,
                                 const_usize: & $($mutability)* ConstUsize) {
                self.super_const_usize(const_usize);
            }

            fn visit_typed_const_val(&mut self,
                                     val: & $($mutability)* TypedConstVal<'tcx>) {
                self.super_typed_const_val(val);
            }

            fn visit_var_decl(&mut self,
                              var_decl: & $($mutability)* VarDecl<'tcx>) {
                self.super_var_decl(var_decl);
            }

            fn visit_temp_decl(&mut self,
                               temp_decl: & $($mutability)* TempDecl<'tcx>) {
                self.super_temp_decl(temp_decl);
            }

            fn visit_arg_decl(&mut self,
                              arg_decl: & $($mutability)* ArgDecl<'tcx>) {
                self.super_arg_decl(arg_decl);
            }

            fn visit_scope_id(&mut self,
                              scope_id: & $($mutability)* ScopeId) {
                self.super_scope_id(scope_id);
            }

239
            // The `super_xxx` methods comprise the default behavior and are
C
Carlos E. Garcia 已提交
240
            // not meant to be overridden.
N
Niko Matsakis 已提交
241

242 243
            fn super_mir(&mut self,
                         mir: & $($mutability)* Mir<'tcx>) {
N
Niko Matsakis 已提交
244 245 246 247 248 249 250 251 252 253 254 255
                let Mir {
                    ref $($mutability)* basic_blocks,
                    ref $($mutability)* scopes,
                    ref $($mutability)* return_ty,
                    ref $($mutability)* var_decls,
                    ref $($mutability)* arg_decls,
                    ref $($mutability)* temp_decls,
                    ref $($mutability)* span,
                } = *mir;

                for (index, data) in basic_blocks.into_iter().enumerate() {
                    let block = BasicBlock::new(index);
256 257
                    self.visit_basic_block_data(block, data);
                }
N
Niko Matsakis 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277

                for scope in scopes {
                    self.visit_scope_data(scope);
                }

                self.visit_fn_output(return_ty);

                for var_decl in var_decls {
                    self.visit_var_decl(var_decl);
                }

                for arg_decl in arg_decls {
                    self.visit_arg_decl(arg_decl);
                }

                for temp_decl in temp_decls {
                    self.visit_temp_decl(temp_decl);
                }

                self.visit_span(span);
N
Niko Matsakis 已提交
278 279
            }

280 281 282
            fn super_basic_block_data(&mut self,
                                      block: BasicBlock,
                                      data: & $($mutability)* BasicBlockData<'tcx>) {
N
Niko Matsakis 已提交
283 284 285 286 287 288 289
                let BasicBlockData {
                    ref $($mutability)* statements,
                    ref $($mutability)* terminator,
                    is_cleanup: _
                } = *data;

                for statement in statements {
290
                    self.visit_statement(block, statement);
N
Niko Matsakis 已提交
291 292
                }

N
Niko Matsakis 已提交
293
                if let Some(ref $($mutability)* terminator) = *terminator {
294 295
                    self.visit_terminator(block, terminator);
                }
N
Niko Matsakis 已提交
296 297
            }

N
Niko Matsakis 已提交
298 299 300 301 302 303 304 305 306 307 308
            fn super_scope_data(&mut self,
                                scope_data: & $($mutability)* ScopeData) {
                let ScopeData {
                    ref $($mutability)* parent_scope,
                } = *scope_data;

                if let Some(ref $($mutability)* parent_scope) = *parent_scope {
                    self.visit_scope_id(parent_scope);
                }
            }

309 310 311
            fn super_statement(&mut self,
                               block: BasicBlock,
                               statement: & $($mutability)* Statement<'tcx>) {
N
Niko Matsakis 已提交
312 313 314 315 316 317 318 319 320
                let Statement {
                    ref $($mutability)* span,
                    ref $($mutability)* scope,
                    ref $($mutability)* kind,
                } = *statement;

                self.visit_span(span);
                self.visit_scope_id(scope);
                match *kind {
321 322 323 324 325
                    StatementKind::Assign(ref $($mutability)* lvalue,
                                          ref $($mutability)* rvalue) => {
                        self.visit_assign(block, lvalue, rvalue);
                    }
                }
N
Niko Matsakis 已提交
326
            }
327

328 329 330 331 332 333
            fn super_assign(&mut self,
                            _block: BasicBlock,
                            lvalue: &$($mutability)* Lvalue<'tcx>,
                            rvalue: &$($mutability)* Rvalue<'tcx>) {
                self.visit_lvalue(lvalue, LvalueContext::Store);
                self.visit_rvalue(rvalue);
334
            }
335

336 337 338
            fn super_terminator(&mut self,
                                block: BasicBlock,
                                terminator: &$($mutability)* Terminator<'tcx>) {
N
Niko Matsakis 已提交
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
                let Terminator {
                    ref $($mutability)* span,
                    ref $($mutability)* scope,
                    ref $($mutability)* kind,
                } = *terminator;

                self.visit_span(span);
                self.visit_scope_id(scope);
                self.visit_terminator_kind(block, kind);
            }

            fn super_terminator_kind(&mut self,
                                     block: BasicBlock,
                                     kind: & $($mutability)* TerminatorKind<'tcx>) {
                match *kind {
354
                    TerminatorKind::Goto { target } => {
355 356
                        self.visit_branch(block, target);
                    }
357

358 359
                    TerminatorKind::If { ref $($mutability)* cond,
                                         ref $($mutability)* targets } => {
360 361 362 363 364
                        self.visit_operand(cond);
                        for &target in targets.as_slice() {
                            self.visit_branch(block, target);
                        }
                    }
365

366 367 368
                    TerminatorKind::Switch { ref $($mutability)* discr,
                                             adt_def: _,
                                             ref targets } => {
369 370 371 372 373
                        self.visit_lvalue(discr, LvalueContext::Inspect);
                        for &target in targets {
                            self.visit_branch(block, target);
                        }
                    }
374

375
                    TerminatorKind::SwitchInt { ref $($mutability)* discr,
N
Niko Matsakis 已提交
376 377
                                                ref $($mutability)* switch_ty,
                                                ref $($mutability)* values,
378
                                                ref targets } => {
379
                        self.visit_lvalue(discr, LvalueContext::Inspect);
N
Niko Matsakis 已提交
380 381 382 383
                        self.visit_ty(switch_ty);
                        for value in values {
                            self.visit_const_val(value);
                        }
384 385 386 387
                        for &target in targets {
                            self.visit_branch(block, target);
                        }
                    }
388

389 390
                    TerminatorKind::Resume |
                    TerminatorKind::Return => {
391
                    }
392

393 394 395
                    TerminatorKind::Drop { ref $($mutability)* value,
                                           target,
                                           unwind } => {
396 397 398 399 400
                        self.visit_lvalue(value, LvalueContext::Drop);
                        self.visit_branch(block, target);
                        unwind.map(|t| self.visit_branch(block, t));
                    }

401 402 403 404
                    TerminatorKind::Call { ref $($mutability)* func,
                                           ref $($mutability)* args,
                                           ref $($mutability)* destination,
                                           cleanup } => {
405 406 407 408
                        self.visit_operand(func);
                        for arg in args {
                            self.visit_operand(arg);
                        }
S
Simonas Kazlauskas 已提交
409 410
                        if let Some((ref $($mutability)* destination, target)) = *destination {
                            self.visit_lvalue(destination, LvalueContext::Store);
411 412
                            self.visit_branch(block, target);
                        }
S
Simonas Kazlauskas 已提交
413
                        cleanup.map(|t| self.visit_branch(block, t));
414 415 416
                    }
                }
            }
417

418 419 420 421 422 423
            fn super_rvalue(&mut self,
                            rvalue: & $($mutability)* Rvalue<'tcx>) {
                match *rvalue {
                    Rvalue::Use(ref $($mutability)* operand) => {
                        self.visit_operand(operand);
                    }
424

425
                    Rvalue::Repeat(ref $($mutability)* value,
N
Niko Matsakis 已提交
426
                                   ref $($mutability)* typed_const_val) => {
427
                        self.visit_operand(value);
N
Niko Matsakis 已提交
428
                        self.visit_typed_const_val(typed_const_val);
429
                    }
430

431 432 433 434 435 436
                    Rvalue::Ref(r, bk, ref $($mutability)* path) => {
                        self.visit_lvalue(path, LvalueContext::Borrow {
                            region: r,
                            kind: bk
                        });
                    }
437

438 439 440
                    Rvalue::Len(ref $($mutability)* path) => {
                        self.visit_lvalue(path, LvalueContext::Inspect);
                    }
441

N
Niko Matsakis 已提交
442 443 444
                    Rvalue::Cast(_cast_kind,
                                 ref $($mutability)* operand,
                                 ref $($mutability)* ty) => {
445
                        self.visit_operand(operand);
N
Niko Matsakis 已提交
446
                        self.visit_ty(ty);
447
                    }
448

N
Niko Matsakis 已提交
449
                    Rvalue::BinaryOp(_bin_op,
450 451 452 453 454
                                     ref $($mutability)* lhs,
                                     ref $($mutability)* rhs) => {
                        self.visit_operand(lhs);
                        self.visit_operand(rhs);
                    }
455

N
Niko Matsakis 已提交
456
                    Rvalue::UnaryOp(_un_op, ref $($mutability)* op) => {
457 458
                        self.visit_operand(op);
                    }
459

N
Niko Matsakis 已提交
460 461
                    Rvalue::Box(ref $($mutability)* ty) => {
                        self.visit_ty(ty);
462
                    }
463

464 465 466
                    Rvalue::Aggregate(ref $($mutability)* kind,
                                      ref $($mutability)* operands) => {
                        match *kind {
N
Niko Matsakis 已提交
467 468 469 470 471 472 473 474 475 476 477
                            AggregateKind::Vec => {
                            }
                            AggregateKind::Tuple => {
                            }
                            AggregateKind::Adt(_adt_def,
                                               _variant_index,
                                               ref $($mutability)* substs) => {
                                self.visit_substs(substs);
                            }
                            AggregateKind::Closure(ref $($mutability)* def_id,
                                                   ref $($mutability)* closure_substs) => {
478
                                self.visit_def_id(def_id);
N
Niko Matsakis 已提交
479
                                self.visit_closure_substs(closure_substs);
480 481 482
                            }
                        }

N
Niko Matsakis 已提交
483
                        for operand in operands {
484 485 486
                            self.visit_operand(operand);
                        }
                    }
487

488 489 490 491 492 493 494 495
                    Rvalue::Slice { ref $($mutability)* input,
                                    from_start,
                                    from_end } => {
                        self.visit_lvalue(input, LvalueContext::Slice {
                            from_start: from_start,
                            from_end: from_end,
                        });
                    }
496

497
                    Rvalue::InlineAsm { ref $($mutability)* outputs,
N
Niko Matsakis 已提交
498 499
                                        ref $($mutability)* inputs,
                                        asm: _ } => {
500 501 502 503 504 505
                        for output in & $($mutability)* outputs[..] {
                            self.visit_lvalue(output, LvalueContext::Store);
                        }
                        for input in & $($mutability)* inputs[..] {
                            self.visit_operand(input);
                        }
506
                    }
507 508 509
                }
            }

510 511 512 513 514 515 516 517 518
            fn super_operand(&mut self,
                             operand: & $($mutability)* Operand<'tcx>) {
                match *operand {
                    Operand::Consume(ref $($mutability)* lvalue) => {
                        self.visit_lvalue(lvalue, LvalueContext::Consume);
                    }
                    Operand::Constant(ref $($mutability)* constant) => {
                        self.visit_constant(constant);
                    }
519 520 521
                }
            }

522 523
            fn super_lvalue(&mut self,
                            lvalue: & $($mutability)* Lvalue<'tcx>,
N
Niko Matsakis 已提交
524
                            context: LvalueContext) {
525 526 527 528 529 530 531 532 533 534
                match *lvalue {
                    Lvalue::Var(_) |
                    Lvalue::Temp(_) |
                    Lvalue::Arg(_) |
                    Lvalue::ReturnPointer => {
                    }
                    Lvalue::Static(ref $($mutability)* def_id) => {
                        self.visit_def_id(def_id);
                    }
                    Lvalue::Projection(ref $($mutability)* proj) => {
N
Niko Matsakis 已提交
535
                        self.visit_projection(proj, context);
536
                    }
537 538
                }
            }
539

N
Niko Matsakis 已提交
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
            fn super_projection(&mut self,
                                proj: & $($mutability)* LvalueProjection<'tcx>,
                                context: LvalueContext) {
                let Projection {
                    ref $($mutability)* base,
                    ref $($mutability)* elem,
                } = *proj;
                self.visit_lvalue(base, LvalueContext::Projection);
                self.visit_projection_elem(elem, context);
            }

            fn super_projection_elem(&mut self,
                                     proj: & $($mutability)* LvalueElem<'tcx>,
                                     _context: LvalueContext) {
                match *proj {
                    ProjectionElem::Deref => {
                    }
                    ProjectionElem::Field(_field, ref $($mutability)* ty) => {
                        self.visit_ty(ty);
                    }
                    ProjectionElem::Index(ref $($mutability)* operand) => {
                        self.visit_operand(operand);
                    }
                    ProjectionElem::ConstantIndex { offset: _,
                                                    min_length: _,
                                                    from_end: _ } => {
                    }
                    ProjectionElem::Downcast(_adt_def, _variant_index) => {
                    }
                }
            }

            fn super_var_decl(&mut self,
                              var_decl: & $($mutability)* VarDecl<'tcx>) {
                let VarDecl {
                    mutability: _,
                    name: _,
                    ref $($mutability)* ty,
                    ref $($mutability)* scope,
                    ref $($mutability)* span,
                } = *var_decl;

                self.visit_ty(ty);
                self.visit_scope_id(scope);
                self.visit_span(span);
            }

            fn super_temp_decl(&mut self,
                               temp_decl: & $($mutability)* TempDecl<'tcx>) {
                let TempDecl {
                    ref $($mutability)* ty,
                } = *temp_decl;

                self.visit_ty(ty);
            }

            fn super_arg_decl(&mut self,
                              arg_decl: & $($mutability)* ArgDecl<'tcx>) {
                let ArgDecl {
                    ref $($mutability)* ty,
                    spread: _
                } = *arg_decl;

                self.visit_ty(ty);
            }

            fn super_scope_id(&mut self,
                              _scope_id: & $($mutability)* ScopeId) {
            }

610 611 612
            fn super_branch(&mut self,
                            _source: BasicBlock,
                            _target: BasicBlock) {
613 614
            }

615 616 617
            fn super_constant(&mut self,
                              constant: & $($mutability)* Constant<'tcx>) {
                self.visit_span(& $($mutability)* constant.span);
N
Niko Matsakis 已提交
618
                self.visit_ty(& $($mutability)* constant.ty);
619
                self.visit_literal(& $($mutability)* constant.literal);
620 621
            }

N
Niko Matsakis 已提交
622 623 624 625 626 627 628 629 630 631 632 633
            fn super_typed_const_val(&mut self,
                                     constant: & $($mutability)* TypedConstVal<'tcx>) {
                let TypedConstVal {
                    ref $($mutability)* span,
                    ref $($mutability)* ty,
                    ref $($mutability)* value,
                } = *constant;
                self.visit_span(span);
                self.visit_ty(ty);
                self.visit_const_usize(value);
            }

634 635 636
            fn super_literal(&mut self,
                             literal: & $($mutability)* Literal<'tcx>) {
                match *literal {
N
Niko Matsakis 已提交
637 638
                    Literal::Item { ref $($mutability)* def_id,
                                    ref $($mutability)* substs } => {
639
                        self.visit_def_id(def_id);
N
Niko Matsakis 已提交
640
                        self.visit_substs(substs);
641
                    },
N
Niko Matsakis 已提交
642 643
                    Literal::Value { ref $($mutability)* value } => {
                        self.visit_const_val(value);
644 645 646 647
                    }
                }
            }

648
            fn super_def_id(&mut self, _def_id: & $($mutability)* DefId) {
649 650
            }

651
            fn super_span(&mut self, _span: & $($mutability)* Span) {
652
            }
N
Niko Matsakis 已提交
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677

            fn super_fn_output(&mut self, fn_output: & $($mutability)* FnOutput<'tcx>) {
                match *fn_output {
                    FnOutput::FnConverging(ref $($mutability)* ty) => {
                        self.visit_ty(ty);
                    }
                    FnOutput::FnDiverging => {
                    }
                }
            }

            fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) {
            }

            fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) {
            }

            fn super_closure_substs(&mut self, _substs: & $($mutability)* &'tcx ClosureSubsts<'tcx>) {
            }

            fn super_const_val(&mut self, _substs: & $($mutability)* ConstVal) {
            }

            fn super_const_usize(&mut self, _substs: & $($mutability)* ConstUsize) {
            }
678 679
        }
    }
680
}
681

682 683
make_mir_visitor!(Visitor,);
make_mir_visitor!(MutVisitor,mut);
684

685 686 687 688
#[derive(Copy, Clone, Debug)]
pub enum LvalueContext {
    // Appears as LHS of an assignment or as dest of a call
    Store,
689

690 691
    // Being dropped
    Drop,
692

693 694
    // Being inspected in some way, like loading a len
    Inspect,
695

696 697
    // Being borrowed
    Borrow { region: Region, kind: BorrowKind },
698

699 700
    // Being sliced -- this should be same as being borrowed, probably
    Slice { from_start: usize, from_end: usize },
701

702 703 704 705 706
    // Used as base for another lvalue, e.g. `x` in `x.y`
    Projection,

    // Consumed as part of an operand
    Consume,
707
}