//! 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::{Place, PlaceBase, PlaceRef, ProjectionElem, ReadOnlyBodyCache};

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: ReadOnlyBodyCache<'cx, '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."),
                    }
                }
            }
        }
    }
}
