//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
//! place are formed by stripping away fields and derefs, except that
//! we stop when we reach the deref of a shared reference. [...] "
//!
//! "Shallow prefixes are found by stripping away fields, but stop at
//! any dereference. So: writing a path like `a` is illegal if `a.b`
//! is borrowed. But: writing `a` is legal if `*a` is borrowed,
//! whether or not `a` is a shared or mutable reference. [...] "

use super::MirBorrowckCtxt;

use rustc::hir;
use rustc::ty::{self, TyCtxt};
use rustc::mir::{Body, Place, PlaceBase, PlaceRef, ProjectionElem};

pub trait IsPrefixOf<'cx, 'tcx> {
    fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool;
}

impl<'cx, 'tcx> IsPrefixOf<'cx, 'tcx> for PlaceRef<'cx, 'tcx> {
    fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool {
        self.base == other.base
            && self.projection.len() <= other.projection.len()
            && self.projection == &other.projection[..self.projection.len()]
    }
}

pub(super) struct Prefixes<'cx, 'tcx> {
    body: &'cx Body<'tcx>,
    tcx: TyCtxt<'tcx>,
    kind: PrefixSet,
    next: Option<PlaceRef<'cx, 'tcx>>,
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[allow(dead_code)]
pub(super) enum PrefixSet {
    /// Doesn't stop until it returns the base case (a Local or
    /// Static prefix).
    All,
    /// Stops at any dereference.
    Shallow,
    /// Stops at the deref of a shared reference.
    Supporting,
}

impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
    /// Returns an iterator over the prefixes of `place`
    /// (inclusive) from longest to smallest, potentially
    /// terminating the iteration early based on `kind`.
    pub(super) fn prefixes(
        &self,
        place_ref: PlaceRef<'cx, 'tcx>,
        kind: PrefixSet,
    ) -> Prefixes<'cx, 'tcx> {
        Prefixes {
            next: Some(place_ref),
            kind,
            body: self.body,
            tcx: self.infcx.tcx,
        }
    }
}

impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
    type Item = PlaceRef<'cx, 'tcx>;
    fn next(&mut self) -> Option<Self::Item> {
        let mut cursor = self.next?;

        // Post-processing `place`: Enqueue any remaining
        // work. Also, `place` may not be a prefix itself, but
        // may hold one further down (e.g., we never return
        // downcasts here, but may return a base of a downcast).

        'cursor: loop {
            match &cursor {
                PlaceRef {
                    base: PlaceBase::Local(_),
                    projection: [],
                }
                | // search yielded this leaf
                PlaceRef {
                    base: PlaceBase::Static(_),
                    projection: [],
                } => {
                    self.next = None;
                    return Some(cursor);
                }
                PlaceRef {
                    base: _,
                    projection: [proj_base @ .., elem],
                } => {
                    match elem {
                        ProjectionElem::Field(_ /*field*/, _ /*ty*/) => {
                            // FIXME: add union handling
                            self.next = Some(PlaceRef {
                                base: cursor.base,
                                projection: proj_base,
                            });
                            return Some(cursor);
                        }
                        ProjectionElem::Downcast(..) |
                        ProjectionElem::Subslice { .. } |
                        ProjectionElem::ConstantIndex { .. } |
                        ProjectionElem::Index(_) => {
                            cursor = PlaceRef {
                                base: cursor.base,
                                projection: proj_base,
                            };
                            continue 'cursor;
                        }
                        ProjectionElem::Deref => {
                            // (handled below)
                        }
                    }

                    assert_eq!(*elem, ProjectionElem::Deref);

                    match self.kind {
                        PrefixSet::Shallow => {
                            // Shallow prefixes are found by stripping away
                            // fields, but stop at *any* dereference.
                            // So we can just stop the traversal now.
                            self.next = None;
                            return Some(cursor);
                        }
                        PrefixSet::All => {
                            // All prefixes: just blindly enqueue the base
                            // of the projection.
                            self.next = Some(PlaceRef {
                                base: cursor.base,
                                projection: proj_base,
                            });
                            return Some(cursor);
                        }
                        PrefixSet::Supporting => {
                            // Fall through!
                        }
                    }

                    assert_eq!(self.kind, PrefixSet::Supporting);
                    // Supporting prefixes: strip away fields and
                    // derefs, except we stop at the deref of a shared
                    // reference.

                    let ty = Place::ty_from(cursor.base, proj_base, self.body, self.tcx).ty;
                    match ty.kind {
                        ty::RawPtr(_) |
                        ty::Ref(
                            _, /*rgn*/
                            _, /*ty*/
                            hir::Mutability::Immutable
                            ) => {
                            // don't continue traversing over derefs of raw pointers or shared
                            // borrows.
                            self.next = None;
                            return Some(cursor);
                        }

                        ty::Ref(
                            _, /*rgn*/
                            _, /*ty*/
                            hir::Mutability::Mutable,
                            ) => {
                            self.next = Some(PlaceRef {
                                base: cursor.base,
                                projection: proj_base,
                            });
                            return Some(cursor);
                        }

                        ty::Adt(..) if ty.is_box() => {
                            self.next = Some(PlaceRef {
                                base: cursor.base,
                                projection: proj_base,
                            });
                            return Some(cursor);
                        }

                        _ => panic!("unknown type fed to Projection Deref."),
                    }
                }
            }
        }
    }
}
