use rustc::hir;
use rustc::mir::ProjectionElem;
use rustc::mir::{Body, Place, PlaceBase, Mutability, Static, StaticKind};
use rustc::ty::{self, TyCtxt};
use crate::borrow_check::borrow_set::LocalsStateAtExit;

/// Extension methods for the `Place` type.
crate trait PlaceExt<'tcx> {
    /// Returns `true` if we can safely ignore borrows of this place.
    /// This is true whenever there is no action that the user can do
    /// to the place `self` that would invalidate the borrow. This is true
    /// for borrows of raw pointer dereferents as well as shared references.
    fn ignore_borrow(
        &self,
        tcx: TyCtxt<'tcx>,
        body: &Body<'tcx>,
        locals_state_at_exit: &LocalsStateAtExit,
    ) -> bool;
}

impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
    fn ignore_borrow(
        &self,
        tcx: TyCtxt<'tcx>,
        body: &Body<'tcx>,
        locals_state_at_exit: &LocalsStateAtExit,
    ) -> bool {
        self.iterate(|place_base, place_projection| {
            let ignore = match place_base {
                // If a local variable is immutable, then we only need to track borrows to guard
                // against two kinds of errors:
                // * The variable being dropped while still borrowed (e.g., because the fn returns
                //   a reference to a local variable)
                // * The variable being moved while still borrowed
                //
                // In particular, the variable cannot be mutated -- the "access checks" will fail --
                // so we don't have to worry about mutation while borrowed.
                PlaceBase::Local(index) => {
                    match locals_state_at_exit {
                        LocalsStateAtExit::AllAreInvalidated => false,
                        LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
                            let ignore = !has_storage_dead_or_moved.contains(*index) &&
                                body.local_decls[*index].mutability == Mutability::Not;
                            debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
                            ignore
                        }
                    }
                }
                PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) =>
                    false,
                PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => {
                    tcx.is_mutable_static(*def_id)
                }
            };

            for proj in place_projection {
                if proj.elem == ProjectionElem::Deref {
                    let ty = Place::ty_from(place_base, &proj.base, body, tcx).ty;
                    match ty.sty {
                        // For both derefs of raw pointers and `&T`
                        // references, the original path is `Copy` and
                        // therefore not significant.  In particular,
                        // there is nothing the user can do to the
                        // original path that would invalidate the
                        // newly created reference -- and if there
                        // were, then the user could have copied the
                        // original path into a new variable and
                        // borrowed *that* one, leaving the original
                        // path unborrowed.
                        ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
                        _ => {}
                    }
                }
            }

            ignore
        })
    }
}
