use crate::ty::subst::SubstsRef;
use crate::ty::{CanonicalUserTypeAnnotation, Ty};
use crate::mir::*;
use syntax_pos::Span;

// # 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`.
//
// ## 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 {
//         statements,
//         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.

macro_rules! body_cache_type {
    (mut $a:lifetime, $tcx:lifetime) => {
        &mut BodyCache<$tcx>
    };
    ($a:lifetime, $tcx:lifetime) => {
        ReadOnlyBodyCache<$a, $tcx>
    };
}

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.

            fn visit_body(
                &mut self,
                body: body_cache_type!($($mutability)? '_, 'tcx)
            ) {
                self.super_body(body);
            }

            fn visit_basic_block_data(&mut self,
                                      block: BasicBlock,
                                      data: & $($mutability)? BasicBlockData<'tcx>) {
                self.super_basic_block_data(block, data);
            }

            fn visit_source_scope_data(&mut self,
                                           scope_data: & $($mutability)? SourceScopeData) {
                self.super_source_scope_data(scope_data);
            }

            fn visit_statement(&mut self,
                               statement: & $($mutability)? Statement<'tcx>,
                               location: Location) {
                self.super_statement(statement, location);
            }

            fn visit_assign(&mut self,
                            place: & $($mutability)? Place<'tcx>,
                            rvalue: & $($mutability)? Rvalue<'tcx>,
                            location: Location) {
                self.super_assign(place, rvalue, location);
            }

            fn visit_terminator(&mut self,
                                terminator: & $($mutability)? Terminator<'tcx>,
                                location: Location) {
                self.super_terminator(terminator, location);
            }

            fn visit_terminator_kind(&mut self,
                                     kind: & $($mutability)? TerminatorKind<'tcx>,
                                     location: Location) {
                self.super_terminator_kind(kind, location);
            }

            fn visit_assert_message(&mut self,
                                    msg: & $($mutability)? AssertMessage<'tcx>,
                                    location: Location) {
                self.super_assert_message(msg, location);
            }

            fn visit_rvalue(&mut self,
                            rvalue: & $($mutability)? Rvalue<'tcx>,
                            location: Location) {
                self.super_rvalue(rvalue, location);
            }

            fn visit_operand(&mut self,
                             operand: & $($mutability)? Operand<'tcx>,
                             location: Location) {
                self.super_operand(operand, location);
            }

            fn visit_ascribe_user_ty(&mut self,
                                     place: & $($mutability)? Place<'tcx>,
                                     variance: & $($mutability)? ty::Variance,
                                     user_ty: & $($mutability)? UserTypeProjection,
                                     location: Location) {
                self.super_ascribe_user_ty(place, variance, user_ty, location);
            }

            fn visit_retag(&mut self,
                           kind: & $($mutability)? RetagKind,
                           place: & $($mutability)? Place<'tcx>,
                           location: Location) {
                self.super_retag(kind, place, location);
            }

            fn visit_place(&mut self,
                            place: & $($mutability)? Place<'tcx>,
                            context: PlaceContext,
                            location: Location) {
                self.super_place(place, context, location);
            }

            fn visit_place_base(&mut self,
                                base: & $($mutability)? PlaceBase<'tcx>,
                                context: PlaceContext,
                                location: Location) {
                self.super_place_base(base, context, location);
            }

            visit_place_fns!($($mutability)?);

            fn visit_constant(&mut self,
                              constant: & $($mutability)? Constant<'tcx>,
                              location: Location) {
                self.super_constant(constant, location);
            }

            fn visit_span(&mut self,
                          span: & $($mutability)? Span) {
                self.super_span(span);
            }

            fn visit_source_info(&mut self,
                                 source_info: & $($mutability)? SourceInfo) {
                self.super_source_info(source_info);
            }

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

            fn visit_user_type_projection(
                &mut self,
                ty: & $($mutability)? UserTypeProjection,
            ) {
                self.super_user_type_projection(ty);
            }

            fn visit_user_type_annotation(
                &mut self,
                index: UserTypeAnnotationIndex,
                ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
            ) {
                self.super_user_type_annotation(index, ty);
            }

            fn visit_region(&mut self,
                            region: & $($mutability)? ty::Region<'tcx>,
                            _: Location) {
                self.super_region(region);
            }

            fn visit_const(&mut self,
                           constant: & $($mutability)? &'tcx ty::Const<'tcx>,
                           _: Location) {
                self.super_const(constant);
            }

            fn visit_substs(&mut self,
                            substs: & $($mutability)? SubstsRef<'tcx>,
                            _: Location) {
                self.super_substs(substs);
            }

            fn visit_local_decl(&mut self,
                                local: Local,
                                local_decl: & $($mutability)? LocalDecl<'tcx>) {
                self.super_local_decl(local, local_decl);
            }

            fn visit_var_debug_info(&mut self,
                                    var_debug_info: & $($mutability)* VarDebugInfo<'tcx>) {
                self.super_var_debug_info(var_debug_info);
            }

            fn visit_local(&mut self,
                            _local: & $($mutability)? Local,
                            _context: PlaceContext,
                            _location: Location) {
            }

            fn visit_source_scope(&mut self,
                                      scope: & $($mutability)? SourceScope) {
                self.super_source_scope(scope);
            }

            // The `super_xxx` methods comprise the default behavior and are
            // not meant to be overridden.

            fn super_body(
                &mut self,
                $($mutability)? body: body_cache_type!($($mutability)? '_, 'tcx)
            ) {
                let span = body.span;
                if let Some(yield_ty) = &$($mutability)? body.yield_ty {
                    self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo {
                        span,
                        scope: OUTERMOST_SOURCE_SCOPE,
                    }));
                }

                // for best performance, we want to use an iterator rather
                // than a for-loop, to avoid calling `body::Body::invalidate` for
                // each basic block.
                macro_rules! basic_blocks {
                    (mut) => (body.basic_blocks_mut().iter_enumerated_mut());
                    () => (body.basic_blocks().iter_enumerated());
                };
                for (bb, data) in basic_blocks!($($mutability)?) {
                    self.visit_basic_block_data(bb, data);
                }

                let body: & $($mutability)? Body<'_> = & $($mutability)? body;
                for scope in &$($mutability)? body.source_scopes {
                    self.visit_source_scope_data(scope);
                }

                self.visit_ty(&$($mutability)? body.return_ty(), TyContext::ReturnTy(SourceInfo {
                    span: body.span,
                    scope: OUTERMOST_SOURCE_SCOPE,
                }));

                for local in body.local_decls.indices() {
                    self.visit_local_decl(local, & $($mutability)? body.local_decls[local]);
                }

                macro_rules! type_annotations {
                    (mut) => (body.user_type_annotations.iter_enumerated_mut());
                    () => (body.user_type_annotations.iter_enumerated());
                };

                for (index, annotation) in type_annotations!($($mutability)?) {
                    self.visit_user_type_annotation(
                        index, annotation
                    );
                }

                for var_debug_info in &$($mutability)? body.var_debug_info {
                    self.visit_var_debug_info(var_debug_info);
                }

                self.visit_span(&$($mutability)? body.span);
            }

            fn super_basic_block_data(&mut self,
                                      block: BasicBlock,
                                      data: & $($mutability)? BasicBlockData<'tcx>) {
                let BasicBlockData {
                    statements,
                    terminator,
                    is_cleanup: _
                } = data;

                let mut index = 0;
                for statement in statements {
                    let location = Location { block: block, statement_index: index };
                    self.visit_statement(statement, location);
                    index += 1;
                }

                if let Some(terminator) = terminator {
                    let location = Location { block: block, statement_index: index };
                    self.visit_terminator(terminator, location);
                }
            }

            fn super_source_scope_data(&mut self, scope_data: & $($mutability)? SourceScopeData) {
                let SourceScopeData {
                    span,
                    parent_scope,
                    local_data: _,
                } = scope_data;

                self.visit_span(span);
                if let Some(parent_scope) = parent_scope {
                    self.visit_source_scope(parent_scope);
                }
            }

            fn super_statement(&mut self,
                               statement: & $($mutability)? Statement<'tcx>,
                               location: Location) {
                let Statement {
                    source_info,
                    kind,
                } = statement;

                self.visit_source_info(source_info);
                match kind {
                    StatementKind::Assign(
                        box(ref $($mutability)? place, ref $($mutability)? rvalue)
                    ) => {
                        self.visit_assign(place, rvalue, location);
                    }
                    StatementKind::FakeRead(_, place) => {
                        self.visit_place(
                            place,
                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
                            location
                        );
                    }
                    StatementKind::SetDiscriminant { place, .. } => {
                        self.visit_place(
                            place,
                            PlaceContext::MutatingUse(MutatingUseContext::Store),
                            location
                        );
                    }
                    StatementKind::StorageLive(local) => {
                        self.visit_local(
                            local,
                            PlaceContext::NonUse(NonUseContext::StorageLive),
                            location
                        );
                    }
                    StatementKind::StorageDead(local) => {
                        self.visit_local(
                            local,
                            PlaceContext::NonUse(NonUseContext::StorageDead),
                            location
                        );
                    }
                    StatementKind::InlineAsm(asm) => {
                        for output in & $($mutability)? asm.outputs[..] {
                            self.visit_place(
                                output,
                                PlaceContext::MutatingUse(MutatingUseContext::AsmOutput),
                                location
                            );
                        }
                        for (span, input) in & $($mutability)? asm.inputs[..] {
                            self.visit_span(span);
                            self.visit_operand(input, location);
                        }
                    }
                    StatementKind::Retag(kind, place) => {
                        self.visit_retag(kind, place, location);
                    }
                    StatementKind::AscribeUserType(
                        box(ref $($mutability)? place, ref $($mutability)? user_ty),
                        variance
                    ) => {
                        self.visit_ascribe_user_ty(place, variance, user_ty, location);
                    }
                    StatementKind::Nop => {}
                }
            }

            fn super_assign(&mut self,
                            place: &$($mutability)? Place<'tcx>,
                            rvalue: &$($mutability)? Rvalue<'tcx>,
                            location: Location) {
                self.visit_place(
                    place,
                    PlaceContext::MutatingUse(MutatingUseContext::Store),
                    location
                );
                self.visit_rvalue(rvalue, location);
            }

            fn super_terminator(&mut self,
                                terminator: &$($mutability)? Terminator<'tcx>,
                                location: Location) {
                let Terminator { source_info, kind } = terminator;

                self.visit_source_info(source_info);
                self.visit_terminator_kind(kind, location);
            }

            fn super_terminator_kind(&mut self,
                                     kind: & $($mutability)? TerminatorKind<'tcx>,
                                     source_location: Location) {
                match kind {
                    TerminatorKind::Goto { .. } |
                    TerminatorKind::Resume |
                    TerminatorKind::Abort |
                    TerminatorKind::Return |
                    TerminatorKind::GeneratorDrop |
                    TerminatorKind::Unreachable |
                    TerminatorKind::FalseEdges { .. } |
                    TerminatorKind::FalseUnwind { .. } => {
                    }

                    TerminatorKind::SwitchInt {
                        discr,
                        switch_ty,
                        values: _,
                        targets: _
                    } => {
                        self.visit_operand(discr, source_location);
                        self.visit_ty(switch_ty, TyContext::Location(source_location));
                    }

                    TerminatorKind::Drop {
                        location,
                        target: _,
                        unwind: _,
                    } => {
                        self.visit_place(
                            location,
                            PlaceContext::MutatingUse(MutatingUseContext::Drop),
                            source_location
                        );
                    }

                    TerminatorKind::DropAndReplace {
                        location,
                        value,
                        target: _,
                        unwind: _,
                    } => {
                        self.visit_place(
                            location,
                            PlaceContext::MutatingUse(MutatingUseContext::Drop),
                            source_location
                        );
                        self.visit_operand(value, source_location);
                    }

                    TerminatorKind::Call {
                        func,
                        args,
                        destination,
                        cleanup: _,
                        from_hir_call: _,
                    } => {
                        self.visit_operand(func, source_location);
                        for arg in args {
                            self.visit_operand(arg, source_location);
                        }
                        if let Some((destination, _)) = destination {
                            self.visit_place(
                                destination,
                                PlaceContext::MutatingUse(MutatingUseContext::Call),
                                source_location
                            );
                        }
                    }

                    TerminatorKind::Assert {
                        cond,
                        expected: _,
                        msg,
                        target: _,
                        cleanup: _,
                    } => {
                        self.visit_operand(cond, source_location);
                        self.visit_assert_message(msg, source_location);
                    }

                    TerminatorKind::Yield {
                        value,
                        resume: _,
                        drop: _,
                    } => {
                        self.visit_operand(value, source_location);
                    }

                }
            }

            fn super_assert_message(&mut self,
                                    msg: & $($mutability)? AssertMessage<'tcx>,
                                    location: Location) {
                use crate::mir::interpret::PanicInfo::*;
                match msg {
                    BoundsCheck { len, index } => {
                        self.visit_operand(len, location);
                        self.visit_operand(index, location);
                    }
                    Panic { .. } | Overflow(_) | OverflowNeg | DivisionByZero | RemainderByZero |
                    ResumedAfterReturn(_) | ResumedAfterPanic(_) => {
                        // Nothing to visit
                    }
                }
            }

            fn super_rvalue(&mut self,
                            rvalue: & $($mutability)? Rvalue<'tcx>,
                            location: Location) {
                match rvalue {
                    Rvalue::Use(operand) => {
                        self.visit_operand(operand, location);
                    }

                    Rvalue::Repeat(value, _) => {
                        self.visit_operand(value, location);
                    }

                    Rvalue::Ref(r, bk, path) => {
                        self.visit_region(r, location);
                        let ctx = match bk {
                            BorrowKind::Shared => PlaceContext::NonMutatingUse(
                                NonMutatingUseContext::SharedBorrow
                            ),
                            BorrowKind::Shallow => PlaceContext::NonMutatingUse(
                                NonMutatingUseContext::ShallowBorrow
                            ),
                            BorrowKind::Unique => PlaceContext::NonMutatingUse(
                                NonMutatingUseContext::UniqueBorrow
                            ),
                            BorrowKind::Mut { .. } =>
                                PlaceContext::MutatingUse(MutatingUseContext::Borrow),
                        };
                        self.visit_place(path, ctx, location);
                    }

                    Rvalue::Len(path) => {
                        self.visit_place(
                            path,
                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
                            location
                        );
                    }

                    Rvalue::Cast(_cast_kind, operand, ty) => {
                        self.visit_operand(operand, location);
                        self.visit_ty(ty, TyContext::Location(location));
                    }

                    Rvalue::BinaryOp(_bin_op, lhs, rhs)
                    | Rvalue::CheckedBinaryOp(_bin_op, lhs, rhs) => {
                        self.visit_operand(lhs, location);
                        self.visit_operand(rhs, location);
                    }

                    Rvalue::UnaryOp(_un_op, op) => {
                        self.visit_operand(op, location);
                    }

                    Rvalue::Discriminant(place) => {
                        self.visit_place(
                            place,
                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
                            location
                        );
                    }

                    Rvalue::NullaryOp(_op, ty) => {
                        self.visit_ty(ty, TyContext::Location(location));
                    }

                    Rvalue::Aggregate(kind, operands) => {
                        let kind = &$($mutability)? **kind;
                        match kind {
                            AggregateKind::Array(ty) => {
                                self.visit_ty(ty, TyContext::Location(location));
                            }
                            AggregateKind::Tuple => {
                            }
                            AggregateKind::Adt(
                                _adt_def,
                                _variant_index,
                                substs,
                                _user_substs,
                                _active_field_index
                            ) => {
                                self.visit_substs(substs, location);
                            }
                            AggregateKind::Closure(
                                _,
                                closure_substs
                            ) => {
                                self.visit_substs(closure_substs, location);
                            }
                            AggregateKind::Generator(
                                _,
                                generator_substs,
                                _movability,
                            ) => {
                                self.visit_substs(generator_substs, location);
                            }
                        }

                        for operand in operands {
                            self.visit_operand(operand, location);
                        }
                    }
                }
            }

            fn super_operand(&mut self,
                             operand: & $($mutability)? Operand<'tcx>,
                             location: Location) {
                match operand {
                    Operand::Copy(place) => {
                        self.visit_place(
                            place,
                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
                            location
                        );
                    }
                    Operand::Move(place) => {
                        self.visit_place(
                            place,
                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
                            location
                        );
                    }
                    Operand::Constant(constant) => {
                        self.visit_constant(constant, location);
                    }
                }
            }

            fn super_ascribe_user_ty(&mut self,
                                     place: & $($mutability)? Place<'tcx>,
                                     _variance: & $($mutability)? ty::Variance,
                                     user_ty: & $($mutability)? UserTypeProjection,
                                     location: Location) {
                self.visit_place(
                    place,
                    PlaceContext::NonUse(NonUseContext::AscribeUserTy),
                    location
                );
                self.visit_user_type_projection(user_ty);
            }

            fn super_retag(&mut self,
                           _kind: & $($mutability)? RetagKind,
                           place: & $($mutability)? Place<'tcx>,
                           location: Location) {
                self.visit_place(
                    place,
                    PlaceContext::MutatingUse(MutatingUseContext::Retag),
                    location,
                );
            }

            fn super_place_base(&mut self,
                                place_base: & $($mutability)? PlaceBase<'tcx>,
                                context: PlaceContext,
                                location: Location) {
                match place_base {
                    PlaceBase::Local(local) => {
                        self.visit_local(local, context, location);
                    }
                    PlaceBase::Static(box Static { kind: _, ty, def_id: _ }) => {
                        self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
                    }
                }
            }

            fn super_local_decl(&mut self,
                                local: Local,
                                local_decl: & $($mutability)? LocalDecl<'tcx>) {
                let LocalDecl {
                    mutability: _,
                    ty,
                    user_ty,
                    source_info,
                    internal: _,
                    local_info: _,
                    is_block_tail: _,
                } = local_decl;

                self.visit_ty(ty, TyContext::LocalDecl {
                    local,
                    source_info: *source_info,
                });
                for (user_ty, _) in & $($mutability)? user_ty.contents {
                    self.visit_user_type_projection(user_ty);
                }
                self.visit_source_info(source_info);
            }

            fn super_var_debug_info(&mut self,
                                    var_debug_info: & $($mutability)? VarDebugInfo<'tcx>) {
                let VarDebugInfo {
                    name: _,
                    source_info,
                    place,
                } = var_debug_info;

                self.visit_source_info(source_info);
                let location = START_BLOCK.start_location();
                self.visit_place(
                    place,
                    PlaceContext::NonUse(NonUseContext::VarDebugInfo),
                    location,
                );
            }

            fn super_source_scope(&mut self,
                                      _scope: & $($mutability)? SourceScope) {
            }

            fn super_constant(&mut self,
                              constant: & $($mutability)? Constant<'tcx>,
                              location: Location) {
                let Constant {
                    span,
                    user_ty,
                    literal,
                } = constant;

                self.visit_span(span);
                drop(user_ty); // no visit method for this
                self.visit_const(literal, location);
            }

            fn super_span(&mut self, _span: & $($mutability)? Span) {
            }

            fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) {
                let SourceInfo {
                    span,
                    scope,
                } = source_info;

                self.visit_span(span);
                self.visit_source_scope(scope);
            }

            fn super_user_type_projection(
                &mut self,
                _ty: & $($mutability)? UserTypeProjection,
            ) {
            }

            fn super_user_type_annotation(
                &mut self,
                _index: UserTypeAnnotationIndex,
                ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
            ) {
                self.visit_span(& $($mutability)? ty.span);
                self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
            }

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

            fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {
            }

            fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) {
            }

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

            // Convenience methods

            fn visit_location(
                &mut self,
                body: body_cache_type!($($mutability)? '_, 'tcx),
                location: Location
            ) {
                let basic_block = & $($mutability)? body[location.block];
                if basic_block.statements.len() == location.statement_index {
                    if let Some(ref $($mutability)? terminator) = basic_block.terminator {
                        self.visit_terminator(terminator, location)
                    }
                } else {
                    let statement = & $($mutability)?
                        basic_block.statements[location.statement_index];
                    self.visit_statement(statement, location)
                }
            }
        }
    }
}

macro_rules! visit_place_fns {
    (mut) => (
        fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;

        fn super_place(
            &mut self,
            place: &mut Place<'tcx>,
            context: PlaceContext,
            location: Location,
        ) {
            self.visit_place_base(&mut place.base, context, location);

            if let Some(new_projection) = self.process_projection(&place.projection) {
                place.projection = self.tcx().intern_place_elems(&new_projection);
            }
        }

        fn process_projection(
            &mut self,
            projection: &'a [PlaceElem<'tcx>],
        ) -> Option<Vec<PlaceElem<'tcx>>> {
            let mut projection = Cow::Borrowed(projection);

            for i in 0..projection.len() {
                if let Some(elem) = projection.get(i) {
                    if let Some(elem) = self.process_projection_elem(elem) {
                        // This converts the borrowed projection into `Cow::Owned(_)` and returns a
                        // clone of the projection so we can mutate and reintern later.
                        let vec = projection.to_mut();
                        vec[i] = elem;
                    }
                }
            }

            match projection {
                Cow::Borrowed(_) => None,
                Cow::Owned(vec) => Some(vec),
            }
        }

        fn process_projection_elem(
            &mut self,
            _elem: &PlaceElem<'tcx>,
        ) -> Option<PlaceElem<'tcx>> {
            None
        }
    );

    () => (
        fn visit_projection(
            &mut self,
            base: &PlaceBase<'tcx>,
            projection: &[PlaceElem<'tcx>],
            context: PlaceContext,
            location: Location,
        ) {
            self.super_projection(base, projection, context, location);
        }

        fn visit_projection_elem(
            &mut self,
            base: &PlaceBase<'tcx>,
            proj_base: &[PlaceElem<'tcx>],
            elem: &PlaceElem<'tcx>,
            context: PlaceContext,
            location: Location,
        ) {
            self.super_projection_elem(base, proj_base, elem, context, location);
        }

        fn super_place(
            &mut self,
            place: &Place<'tcx>,
            context: PlaceContext,
            location: Location,
        ) {
            let mut context = context;

            if !place.projection.is_empty() {
                context = if context.is_mutating_use() {
                    PlaceContext::MutatingUse(MutatingUseContext::Projection)
                } else {
                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
                };
            }

            self.visit_place_base(&place.base, context, location);

            self.visit_projection(&place.base,
                                  &place.projection,
                                  context,
                                  location);
        }

        fn super_projection(
            &mut self,
            base: &PlaceBase<'tcx>,
            projection: &[PlaceElem<'tcx>],
            context: PlaceContext,
            location: Location,
        ) {
            let mut cursor = projection;
            while let [proj_base @ .., elem] = cursor {
                cursor = proj_base;
                self.visit_projection_elem(base, cursor, elem, context, location);
            }
        }

        fn super_projection_elem(
            &mut self,
            _base: &PlaceBase<'tcx>,
            _proj_base: &[PlaceElem<'tcx>],
            elem: &PlaceElem<'tcx>,
            _context: PlaceContext,
            location: Location,
        ) {
            match elem {
                ProjectionElem::Field(_field, ty) => {
                    self.visit_ty(ty, TyContext::Location(location));
                }
                ProjectionElem::Index(local) => {
                    self.visit_local(
                        local,
                        PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
                        location
                    );
                }
                ProjectionElem::Deref |
                ProjectionElem::Subslice { from: _, to: _ } |
                ProjectionElem::ConstantIndex { offset: _,
                                                min_length: _,
                                                from_end: _ } |
                ProjectionElem::Downcast(_, _) => {
                }
            }
        }
    );
}

make_mir_visitor!(Visitor,);
make_mir_visitor!(MutVisitor,mut);

pub trait MirVisitable<'tcx> {
    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>);
}

impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> {
    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
    {
        visitor.visit_statement(self, location)
    }
}

impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> {
    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
    {
        visitor.visit_terminator(self, location)
    }
}

impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> {
    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
    {
        visitor.visit_terminator(self.as_ref().unwrap(), location)
    }
}

/// Extra information passed to `visit_ty` and friends to give context
/// about where the type etc appears.
#[derive(Debug)]
pub enum TyContext {
    LocalDecl {
        /// The index of the local variable we are visiting.
        local: Local,

        /// The source location where this local variable was declared.
        source_info: SourceInfo,
    },

    /// The inferred type of a user type annotation.
    UserTy(Span),

    /// The return type of the function.
    ReturnTy(SourceInfo),

    YieldTy(SourceInfo),

    /// A type found at some location.
    Location(Location),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum NonMutatingUseContext {
    /// Being inspected in some way, like loading a len.
    Inspect,
    /// Consumed as part of an operand.
    Copy,
    /// Consumed as part of an operand.
    Move,
    /// Shared borrow.
    SharedBorrow,
    /// Shallow borrow.
    ShallowBorrow,
    /// Unique borrow.
    UniqueBorrow,
    /// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
    /// For example, the projection `x.y` is not marked as a mutation in these cases:
    ///
    ///     z = x.y;
    ///     f(&x.y);
    ///
    Projection,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MutatingUseContext {
    /// Appears as LHS of an assignment.
    Store,
    /// Can often be treated as a `Store`, but needs to be separate because
    /// ASM is allowed to read outputs as well, so a `Store`-`AsmOutput` sequence
    /// cannot be simplified the way a `Store`-`Store` can be.
    AsmOutput,
    /// Destination of a call.
    Call,
    /// Being dropped.
    Drop,
    /// Mutable borrow.
    Borrow,
    /// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
    /// For example, the projection `x.y` is marked as a mutation in these cases:
    ///
    ///     x.y = ...;
    ///     f(&mut x.y);
    ///
    Projection,
    /// Retagging, a "Stacked Borrows" shadow state operation
    Retag,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum NonUseContext {
    /// Starting a storage live range.
    StorageLive,
    /// Ending a storage live range.
    StorageDead,
    /// User type annotation assertions for NLL.
    AscribeUserTy,
    /// The data of an user variable, for debug info.
    VarDebugInfo,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PlaceContext {
    NonMutatingUse(NonMutatingUseContext),
    MutatingUse(MutatingUseContext),
    NonUse(NonUseContext),
}

impl PlaceContext {
    /// Returns `true` if this place context represents a drop.
    pub fn is_drop(&self) -> bool {
        match *self {
            PlaceContext::MutatingUse(MutatingUseContext::Drop) => true,
            _ => false,
        }
    }

    /// Returns `true` if this place context represents a borrow.
    pub fn is_borrow(&self) -> bool {
        match *self {
            PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
            PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
            PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |
            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => true,
            _ => false,
        }
    }

    /// Returns `true` if this place context represents a storage live or storage dead marker.
    pub fn is_storage_marker(&self) -> bool {
        match *self {
            PlaceContext::NonUse(NonUseContext::StorageLive) |
            PlaceContext::NonUse(NonUseContext::StorageDead) => true,
            _ => false,
        }
    }

    /// Returns `true` if this place context represents a storage live marker.
    pub fn is_storage_live_marker(&self) -> bool {
        match *self {
            PlaceContext::NonUse(NonUseContext::StorageLive) => true,
            _ => false,
        }
    }

    /// Returns `true` if this place context represents a storage dead marker.
    pub fn is_storage_dead_marker(&self) -> bool {
        match *self {
            PlaceContext::NonUse(NonUseContext::StorageDead) => true,
            _ => false,
        }
    }

    /// Returns `true` if this place context represents a use that potentially changes the value.
    pub fn is_mutating_use(&self) -> bool {
        match *self {
            PlaceContext::MutatingUse(..) => true,
            _ => false,
        }
    }

    /// Returns `true` if this place context represents a use that does not change the value.
    pub fn is_nonmutating_use(&self) -> bool {
        match *self {
            PlaceContext::NonMutatingUse(..) => true,
            _ => false,
        }
    }

    /// Returns `true` if this place context represents a use.
    pub fn is_use(&self) -> bool {
        match *self {
            PlaceContext::NonUse(..) => false,
            _ => true,
        }
    }

    /// Returns `true` if this place context represents an assignment statement.
    pub fn is_place_assignment(&self) -> bool {
        match *self {
            PlaceContext::MutatingUse(MutatingUseContext::Store) |
            PlaceContext::MutatingUse(MutatingUseContext::Call) |
            PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) => true,
            _ => false,
        }
    }
}
