use crate::ty::subst::SubstsRef;
use crate::ty::{CanonicalUserTypeAnnotation, ClosureSubsts, GeneratorSubsts, 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! 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: & $($mutability)? Body<'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,
                                place_base: & $($mutability)? PlaceBase<'tcx>,
                                context: PlaceContext,
                                location: Location) {
                self.super_place_base(place_base, context, location);
            }

            fn visit_projection(&mut self,
                                place_base: & $($mutability)? PlaceBase<'tcx>,
                                place: & $($mutability)? Projection<'tcx>,
                                context: PlaceContext,
                                location: Location) {
                self.super_projection(place_base, place, context, location);
            }

            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_closure_substs(&mut self,
                                    substs: & $($mutability)? ClosureSubsts<'tcx>,
                                    _: Location) {
                self.super_closure_substs(substs);
            }

            fn visit_generator_substs(&mut self,
                                      substs: & $($mutability)? GeneratorSubsts<'tcx>,
                                    _: Location) {
                self.super_generator_substs(substs);
            }

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

            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,
                         body: & $($mutability)? Body<'tcx>) {
                if let Some(yield_ty) = &$($mutability)? body.yield_ty {
                    self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo {
                        span: body.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);
                }

                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
                    );
                }

                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,
                } = 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(place, 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(place, variance, user_ty) => {
                        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 |
                    GeneratorResumedAfterReturn | GeneratorResumedAfterPanic => {
                        // 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_closure_substs(closure_substs, location);
                            }
                            AggregateKind::Generator(
                                _,
                                generator_substs,
                                _movability,
                            ) => {
                                self.visit_generator_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(&mut self,
                            place: & $($mutability)? Place<'tcx>,
                            context: PlaceContext,
                            location: Location) {
                let mut context = context;

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

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

                if let Some(box proj) = & $($mutability)? place.projection {
                    self.visit_projection(& $($mutability)? place.base, proj, context, 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_projection(&mut self,
                                place_base: & $($mutability)? PlaceBase<'tcx>,
                                proj: & $($mutability)? Projection<'tcx>,
                                context: PlaceContext,
                                location: Location) {
                if let Some(box proj_base) = & $($mutability)? proj.base {
                    self.visit_projection(place_base, proj_base, context, location);
                }

                match & $($mutability)? proj.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(_, _) => {
                    }
                }
            }

            fn super_local_decl(&mut self,
                                local: Local,
                                local_decl: & $($mutability)? LocalDecl<'tcx>) {
                let LocalDecl {
                    mutability: _,
                    ty,
                    user_ty,
                    name: _,
                    source_info,
                    visibility_scope,
                    internal: _,
                    is_user_variable: _,
                    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);
                self.visit_source_scope(visibility_scope);
            }

            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>) {
            }

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

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

            // Convenience methods

            fn visit_location(&mut self, body: & $($mutability)? Body<'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)
                }
            }
        }
    }
}

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(Copy, Clone, Debug, PartialEq, Eq, Hash)]
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,
}

#[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,
        }
    }
}
