//! # Categorization
//!
//! The job of the categorization module is to analyze an expression to
//! determine what kind of memory is used in evaluating it (for example,
//! where dereferences occur and what kind of pointer is dereferenced;
//! whether the memory is mutable, etc.).
//!
//! Categorization effectively transforms all of our expressions into
//! expressions of the following forms (the actual enum has many more
//! possibilities, naturally, but they are all variants of these base
//! forms):
//!
//!     E = rvalue    // some computed rvalue
//!       | x         // address of a local variable or argument
//!       | *E        // deref of a ptr
//!       | E.comp    // access to an interior component
//!
//! Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
//! address where the result is to be found. If Expr is a place, then this
//! is the address of the place. If `Expr` is an rvalue, this is the address of
//! some temporary spot in memory where the result is stored.
//!
//! Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)`
//! as follows:
//!
//! - `cat`: what kind of expression was this? This is a subset of the
//!   full expression forms which only includes those that we care about
//!   for the purpose of the analysis.
//! - `mutbl`: mutability of the address `A`.
//! - `ty`: the type of data found at the address `A`.
//!
//! The resulting categorization tree differs somewhat from the expressions
//! themselves. For example, auto-derefs are explicit. Also, an index a[b] is
//! decomposed into two operations: a dereference to reach the array data and
//! then an index to jump forward to the relevant item.
//!
//! ## By-reference upvars
//!
//! One part of the codegen which may be non-obvious is that we translate
//! closure upvars into the dereference of a borrowed pointer; this more closely
//! resembles the runtime codegen. So, for example, if we had:
//!
//!     let mut x = 3;
//!     let y = 5;
//!     let inc = || x += y;
//!
//! Then when we categorize `x` (*within* the closure) we would yield a
//! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
//! tied to `x`. The type of `x'` will be a borrowed pointer.

#![allow(non_camel_case_types)]

pub use self::PointerKind::*;
pub use self::InteriorKind::*;
pub use self::MutabilityCategory::*;
pub use self::AliasableReason::*;
pub use self::Note::*;

use self::Aliasability::*;

use crate::middle::region;
use crate::hir::def_id::{DefId, LocalDefId};
use crate::hir::Node;
use crate::infer::InferCtxt;
use crate::hir::def::{CtorOf, Res, DefKind, CtorKind};
use crate::ty::adjustment;
use crate::ty::{self, DefIdTree, Ty, TyCtxt};
use crate::ty::fold::TypeFoldable;
use crate::ty::layout::VariantIdx;

use crate::hir::{MutImmutable, MutMutable, PatKind};
use crate::hir::pat_util::EnumerateAndAdjustIterator;
use crate::hir;
use syntax::ast::{self, Name};
use syntax::symbol::sym;
use syntax_pos::Span;

use std::borrow::Cow;
use std::fmt;
use std::hash::{Hash, Hasher};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::indexed_vec::Idx;
use std::rc::Rc;
use crate::util::nodemap::ItemLocalSet;

#[derive(Clone, Debug, PartialEq)]
pub enum Categorization<'tcx> {
    Rvalue(ty::Region<'tcx>),            // temporary val, argument is its scope
    ThreadLocal(ty::Region<'tcx>),       // value that cannot move, but still restricted in scope
    StaticItem,
    Upvar(Upvar),                        // upvar referenced by closure env
    Local(hir::HirId),                   // local variable
    Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr
    Interior(cmt<'tcx>, InteriorKind),   // something interior: field, tuple, etc
    Downcast(cmt<'tcx>, DefId),          // selects a particular enum variant (*1)

    // (*1) downcast is only required if the enum has more than one variant
}

// Represents any kind of upvar
#[derive(Clone, Copy, PartialEq)]
pub struct Upvar {
    pub id: ty::UpvarId,
    pub kind: ty::ClosureKind
}

// different kinds of pointers:
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum PointerKind<'tcx> {
    /// `Box<T>`
    Unique,

    /// `&T`
    BorrowedPtr(ty::BorrowKind, ty::Region<'tcx>),

    /// `*T`
    UnsafePtr(hir::Mutability),
}

// We use the term "interior" to mean "something reachable from the
// base without a pointer dereference", e.g., a field
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum InteriorKind {
    InteriorField(FieldIndex),
    InteriorElement(InteriorOffsetKind),
}

// Contains index of a field that is actually used for loan path comparisons and
// string representation of the field that should be used only for diagnostics.
#[derive(Clone, Copy, Eq)]
pub struct FieldIndex(pub usize, pub Name);

impl PartialEq for FieldIndex {
    fn eq(&self, rhs: &Self) -> bool {
        self.0 == rhs.0
    }
}

impl Hash for FieldIndex {
    fn hash<H: Hasher>(&self, h: &mut H) {
        self.0.hash(h)
    }
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum InteriorOffsetKind {
    Index,   // e.g., `array_expr[index_expr]`
    Pattern, // e.g., `fn foo([_, a, _, _]: [A; 4]) { ... }`
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum MutabilityCategory {
    McImmutable, // Immutable.
    McDeclared,  // Directly declared as mutable.
    McInherited, // Inherited from the fact that owner is mutable.
}

// A note about the provenance of a `cmt`.  This is used for
// special-case handling of upvars such as mutability inference.
// Upvar categorization can generate a variable number of nested
// derefs.  The note allows detecting them without deep pattern
// matching on the categorization.
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Note {
    NoteClosureEnv(ty::UpvarId), // Deref through closure env
    NoteUpvarRef(ty::UpvarId),   // Deref through by-ref upvar
    NoteIndex,                   // Deref as part of desugaring `x[]` into its two components
    NoteNone                     // Nothing special
}

// `cmt`: "Category, Mutability, and Type".
//
// a complete categorization of a value indicating where it originated
// and how it is located, as well as the mutability of the memory in
// which the value is stored.
//
// *WARNING* The field `cmt.type` is NOT necessarily the same as the
// result of `node_type(cmt.id)`.
//
// (FIXME: rewrite the following comment given that `@x` managed
// pointers have been obsolete for quite some time.)
//
// This is because the `id` is always the `id` of the node producing the
// type; in an expression like `*x`, the type of this deref node is the
// deref'd type (`T`), but in a pattern like `@x`, the `@x` pattern is
// again a dereference, but its type is the type *before* the
// dereference (`@T`). So use `cmt.ty` to find the type of the value in
// a consistent fashion. For more details, see the method `cat_pattern`
#[derive(Clone, Debug, PartialEq)]
pub struct cmt_<'tcx> {
    pub hir_id: hir::HirId,        // HIR id of expr/pat producing this value
    pub span: Span,                // span of same expr/pat
    pub cat: Categorization<'tcx>, // categorization of expr
    pub mutbl: MutabilityCategory, // mutability of expr as place
    pub ty: Ty<'tcx>,              // type of the expr (*see WARNING above*)
    pub note: Note,                // Note about the provenance of this cmt
}

pub type cmt<'tcx> = Rc<cmt_<'tcx>>;

pub enum ImmutabilityBlame<'tcx> {
    ImmLocal(hir::HirId),
    ClosureEnv(LocalDefId),
    LocalDeref(hir::HirId),
    AdtFieldDeref(&'tcx ty::AdtDef, &'tcx ty::FieldDef)
}

impl<'tcx> cmt_<'tcx> {
    fn resolve_field(&self, field_index: usize) -> Option<(&'tcx ty::AdtDef, &'tcx ty::FieldDef)>
    {
        let adt_def = match self.ty.sty {
            ty::Adt(def, _) => def,
            ty::Tuple(..) => return None,
            // closures get `Categorization::Upvar` rather than `Categorization::Interior`
            _ =>  bug!("interior cmt {:?} is not an ADT", self)
        };
        let variant_def = match self.cat {
            Categorization::Downcast(_, variant_did) => {
                adt_def.variant_with_id(variant_did)
            }
            _ => {
                assert_eq!(adt_def.variants.len(), 1);
                &adt_def.variants[VariantIdx::new(0)]
            }
        };
        Some((adt_def, &variant_def.fields[field_index]))
    }

    pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
        match self.cat {
            Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) => {
                // try to figure out where the immutable reference came from
                match base_cmt.cat {
                    Categorization::Local(hir_id) =>
                        Some(ImmutabilityBlame::LocalDeref(hir_id)),
                    Categorization::Interior(ref base_cmt, InteriorField(field_index)) => {
                        base_cmt.resolve_field(field_index.0).map(|(adt_def, field_def)| {
                            ImmutabilityBlame::AdtFieldDeref(adt_def, field_def)
                        })
                    }
                    Categorization::Upvar(Upvar { id, .. }) => {
                        if let NoteClosureEnv(..) = self.note {
                            Some(ImmutabilityBlame::ClosureEnv(id.closure_expr_id))
                        } else {
                            None
                        }
                    }
                    _ => None
                }
            }
            Categorization::Local(hir_id) => {
                Some(ImmutabilityBlame::ImmLocal(hir_id))
            }
            Categorization::Rvalue(..) |
            Categorization::Upvar(..) |
            Categorization::Deref(_, UnsafePtr(..)) => {
                // This should not be reachable up to inference limitations.
                None
            }
            Categorization::Interior(ref base_cmt, _) |
            Categorization::Downcast(ref base_cmt, _) |
            Categorization::Deref(ref base_cmt, _) => {
                base_cmt.immutability_blame()
            }
            Categorization::ThreadLocal(..) |
            Categorization::StaticItem => {
                // Do we want to do something here?
                None
            }
        }
    }
}

pub trait HirNode {
    fn hir_id(&self) -> hir::HirId;
    fn span(&self) -> Span;
}

impl HirNode for hir::Expr {
    fn hir_id(&self) -> hir::HirId { self.hir_id }
    fn span(&self) -> Span { self.span }
}

impl HirNode for hir::Pat {
    fn hir_id(&self) -> hir::HirId { self.hir_id }
    fn span(&self) -> Span { self.span }
}

#[derive(Clone)]
pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
    pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
    pub body_owner: DefId,
    pub upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
    pub region_scope_tree: &'a region::ScopeTree,
    pub tables: &'a ty::TypeckTables<'tcx>,
    rvalue_promotable_map: Option<&'tcx ItemLocalSet>,
    infcx: Option<&'a InferCtxt<'a, 'gcx, 'tcx>>,
}

pub type McResult<T> = Result<T, ()>;

impl MutabilityCategory {
    pub fn from_mutbl(m: hir::Mutability) -> MutabilityCategory {
        let ret = match m {
            MutImmutable => McImmutable,
            MutMutable => McDeclared
        };
        debug!("MutabilityCategory::{}({:?}) => {:?}",
               "from_mutbl", m, ret);
        ret
    }

    pub fn from_borrow_kind(borrow_kind: ty::BorrowKind) -> MutabilityCategory {
        let ret = match borrow_kind {
            ty::ImmBorrow => McImmutable,
            ty::UniqueImmBorrow => McImmutable,
            ty::MutBorrow => McDeclared,
        };
        debug!("MutabilityCategory::{}({:?}) => {:?}",
               "from_borrow_kind", borrow_kind, ret);
        ret
    }

    fn from_pointer_kind(base_mutbl: MutabilityCategory,
                         ptr: PointerKind<'_>) -> MutabilityCategory {
        let ret = match ptr {
            Unique => {
                base_mutbl.inherit()
            }
            BorrowedPtr(borrow_kind, _) => {
                MutabilityCategory::from_borrow_kind(borrow_kind)
            }
            UnsafePtr(m) => {
                MutabilityCategory::from_mutbl(m)
            }
        };
        debug!("MutabilityCategory::{}({:?}, {:?}) => {:?}",
               "from_pointer_kind", base_mutbl, ptr, ret);
        ret
    }

    fn from_local(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>,
                  id: ast::NodeId) -> MutabilityCategory {
        let ret = match tcx.hir().get(id) {
            Node::Binding(p) => match p.node {
                PatKind::Binding(..) => {
                    let bm = *tables.pat_binding_modes()
                                    .get(p.hir_id)
                                    .expect("missing binding mode");
                    if bm == ty::BindByValue(hir::MutMutable) {
                        McDeclared
                    } else {
                        McImmutable
                    }
                }
                _ => span_bug!(p.span, "expected identifier pattern")
            },
            _ => span_bug!(tcx.hir().span(id), "expected identifier pattern")
        };
        debug!("MutabilityCategory::{}(tcx, id={:?}) => {:?}",
               "from_local", id, ret);
        ret
    }

    pub fn inherit(&self) -> MutabilityCategory {
        let ret = match *self {
            McImmutable => McImmutable,
            McDeclared => McInherited,
            McInherited => McInherited,
        };
        debug!("{:?}.inherit() => {:?}", self, ret);
        ret
    }

    pub fn is_mutable(&self) -> bool {
        let ret = match *self {
            McImmutable => false,
            McInherited => true,
            McDeclared => true,
        };
        debug!("{:?}.is_mutable() => {:?}", self, ret);
        ret
    }

    pub fn is_immutable(&self) -> bool {
        let ret = match *self {
            McImmutable => true,
            McDeclared | McInherited => false
        };
        debug!("{:?}.is_immutable() => {:?}", self, ret);
        ret
    }

    pub fn to_user_str(&self) -> &'static str {
        match *self {
            McDeclared | McInherited => "mutable",
            McImmutable => "immutable",
        }
    }
}

impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx, 'tcx> {
    pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
               body_owner: DefId,
               region_scope_tree: &'a region::ScopeTree,
               tables: &'a ty::TypeckTables<'tcx>,
               rvalue_promotable_map: Option<&'tcx ItemLocalSet>)
               -> MemCategorizationContext<'a, 'tcx, 'tcx> {
        MemCategorizationContext {
            tcx,
            body_owner,
            upvars: tcx.upvars(body_owner),
            region_scope_tree,
            tables,
            rvalue_promotable_map,
            infcx: None
        }
    }
}

impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
    /// Creates a `MemCategorizationContext` during type inference.
    /// This is used during upvar analysis and a few other places.
    /// Because the typeck tables are not yet complete, the results
    /// from the analysis must be used with caution:
    ///
    /// - rvalue promotions are not known, so the lifetimes of
    ///   temporaries may be overly conservative;
    /// - similarly, as the results of upvar analysis are not yet
    ///   known, the results around upvar accesses may be incorrect.
    pub fn with_infer(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
                      body_owner: DefId,
                      region_scope_tree: &'a region::ScopeTree,
                      tables: &'a ty::TypeckTables<'tcx>)
                      -> MemCategorizationContext<'a, 'gcx, 'tcx> {
        let tcx = infcx.tcx;

        // Subtle: we can't do rvalue promotion analysis until the
        // typeck phase is complete, which means that you can't trust
        // the rvalue lifetimes that result, but that's ok, since we
        // don't need to know those during type inference.
        let rvalue_promotable_map = None;

        MemCategorizationContext {
            tcx,
            body_owner,
            upvars: tcx.upvars(body_owner),
            region_scope_tree,
            tables,
            rvalue_promotable_map,
            infcx: Some(infcx),
        }
    }

    pub fn type_is_copy_modulo_regions(
        &self,
        param_env: ty::ParamEnv<'tcx>,
        ty: Ty<'tcx>,
        span: Span,
    ) -> bool {
        self.infcx.map(|infcx| infcx.type_is_copy_modulo_regions(param_env, ty, span))
            .or_else(|| {
                self.tcx.lift_to_global(&(param_env, ty)).map(|(param_env, ty)| {
                    ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span)
                })
            })
            .unwrap_or(true)
    }

    fn resolve_vars_if_possible<T>(&self, value: &T) -> T
        where T: TypeFoldable<'tcx>
    {
        self.infcx.map(|infcx| infcx.resolve_vars_if_possible(value))
            .unwrap_or_else(|| value.clone())
    }

    fn is_tainted_by_errors(&self) -> bool {
        self.infcx.map_or(false, |infcx| infcx.is_tainted_by_errors())
    }

    fn resolve_type_vars_or_error(&self,
                                  id: hir::HirId,
                                  ty: Option<Ty<'tcx>>)
                                  -> McResult<Ty<'tcx>> {
        match ty {
            Some(ty) => {
                let ty = self.resolve_vars_if_possible(&ty);
                if ty.references_error() || ty.is_ty_var() {
                    debug!("resolve_type_vars_or_error: error from {:?}", ty);
                    Err(())
                } else {
                    Ok(ty)
                }
            }
            // FIXME
            None if self.is_tainted_by_errors() => Err(()),
            None => {
                let id = self.tcx.hir().hir_to_node_id(id);
                bug!("no type for node {}: {} in mem_categorization",
                     id, self.tcx.hir().node_to_string(id));
            }
        }
    }

    pub fn node_ty(&self,
                   hir_id: hir::HirId)
                   -> McResult<Ty<'tcx>> {
        self.resolve_type_vars_or_error(hir_id,
                                        self.tables.node_type_opt(hir_id))
    }

    pub fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
        self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_opt(expr))
    }

    pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
        self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr))
    }

    /// Returns the type of value that this pattern matches against.
    /// Some non-obvious cases:
    ///
    /// - a `ref x` binding matches against a value of type `T` and gives
    ///   `x` the type `&T`; we return `T`.
    /// - a pattern with implicit derefs (thanks to default binding
    ///   modes #42640) may look like `Some(x)` but in fact have
    ///   implicit deref patterns attached (e.g., it is really
    ///   `&Some(x)`). In that case, we return the "outermost" type
    ///   (e.g., `&Option<T>).
    pub fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
        // Check for implicit `&` types wrapping the pattern; note
        // that these are never attached to binding patterns, so
        // actually this is somewhat "disjoint" from the code below
        // that aims to account for `ref x`.
        if let Some(vec) = self.tables.pat_adjustments().get(pat.hir_id) {
            if let Some(first_ty) = vec.first() {
                debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty);
                return Ok(first_ty);
            }
        }

        self.pat_ty_unadjusted(pat)
    }


    /// Like `pat_ty`, but ignores implicit `&` patterns.
    fn pat_ty_unadjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
        let base_ty = self.node_ty(pat.hir_id)?;
        debug!("pat_ty(pat={:?}) base_ty={:?}", pat, base_ty);

        // This code detects whether we are looking at a `ref x`,
        // and if so, figures out what the type *being borrowed* is.
        let ret_ty = match pat.node {
            PatKind::Binding(..) => {
                let bm = *self.tables
                              .pat_binding_modes()
                              .get(pat.hir_id)
                              .expect("missing binding mode");

                if let ty::BindByReference(_) = bm {
                    // a bind-by-ref means that the base_ty will be the type of the ident itself,
                    // but what we want here is the type of the underlying value being borrowed.
                    // So peel off one-level, turning the &T into T.
                    match base_ty.builtin_deref(false) {
                        Some(t) => t.ty,
                        None => {
                            debug!("By-ref binding of non-derefable type {:?}", base_ty);
                            return Err(());
                        }
                    }
                } else {
                    base_ty
                }
            }
            _ => base_ty,
        };
        debug!("pat_ty(pat={:?}) ret_ty={:?}", pat, ret_ty);

        Ok(ret_ty)
    }

    pub fn cat_expr(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
        // This recursion helper avoids going through *too many*
        // adjustments, since *only* non-overloaded deref recurses.
        fn helper<'a, 'gcx, 'tcx>(mc: &MemCategorizationContext<'a, 'gcx, 'tcx>,
                                  expr: &hir::Expr,
                                  adjustments: &[adjustment::Adjustment<'tcx>])
                                  -> McResult<cmt_<'tcx>> {
            match adjustments.split_last() {
                None => mc.cat_expr_unadjusted(expr),
                Some((adjustment, previous)) => {
                    mc.cat_expr_adjusted_with(expr, || helper(mc, expr, previous), adjustment)
                }
            }
        }

        helper(self, expr, self.tables.expr_adjustments(expr))
    }

    pub fn cat_expr_adjusted(&self, expr: &hir::Expr,
                             previous: cmt_<'tcx>,
                             adjustment: &adjustment::Adjustment<'tcx>)
                             -> McResult<cmt_<'tcx>> {
        self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
    }

    fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
                                 previous: F,
                                 adjustment: &adjustment::Adjustment<'tcx>)
                                 -> McResult<cmt_<'tcx>>
        where F: FnOnce() -> McResult<cmt_<'tcx>>
    {
        debug!("cat_expr_adjusted_with({:?}): {:?}", adjustment, expr);
        let target = self.resolve_vars_if_possible(&adjustment.target);
        match adjustment.kind {
            adjustment::Adjust::Deref(overloaded) => {
                // Equivalent to *expr or something similar.
                let base = Rc::new(if let Some(deref) = overloaded {
                    let ref_ty = self.tcx.mk_ref(deref.region, ty::TypeAndMut {
                        ty: target,
                        mutbl: deref.mutbl,
                    });
                    self.cat_rvalue_node(expr.hir_id, expr.span, ref_ty)
                } else {
                    previous()?
                });
                self.cat_deref(expr, base, NoteNone)
            }

            adjustment::Adjust::NeverToAny |
            adjustment::Adjust::Pointer(_) |
            adjustment::Adjust::Borrow(_) => {
                // Result is an rvalue.
                Ok(self.cat_rvalue_node(expr.hir_id, expr.span, target))
            }
        }
    }

    pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
        debug!("cat_expr: id={} expr={:?}", expr.hir_id, expr);

        let expr_ty = self.expr_ty(expr)?;
        match expr.node {
            hir::ExprKind::Unary(hir::UnDeref, ref e_base) => {
                if self.tables.is_method_call(expr) {
                    self.cat_overloaded_place(expr, e_base, NoteNone)
                } else {
                    let base_cmt = Rc::new(self.cat_expr(&e_base)?);
                    self.cat_deref(expr, base_cmt, NoteNone)
                }
            }

            hir::ExprKind::Field(ref base, f_ident) => {
                let base_cmt = Rc::new(self.cat_expr(&base)?);
                debug!("cat_expr(cat_field): id={} expr={:?} base={:?}",
                       expr.hir_id,
                       expr,
                       base_cmt);
                let f_index = self.tcx.field_index(expr.hir_id, self.tables);
                Ok(self.cat_field(expr, base_cmt, f_index, f_ident, expr_ty))
            }

            hir::ExprKind::Index(ref base, _) => {
                if self.tables.is_method_call(expr) {
                    // If this is an index implemented by a method call, then it
                    // will include an implicit deref of the result.
                    // The call to index() returns a `&T` value, which
                    // is an rvalue. That is what we will be
                    // dereferencing.
                    self.cat_overloaded_place(expr, base, NoteIndex)
                } else {
                    let base_cmt = Rc::new(self.cat_expr(&base)?);
                    self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
                }
            }

            hir::ExprKind::Path(ref qpath) => {
                let res = self.tables.qpath_res(qpath, expr.hir_id);
                self.cat_res(expr.hir_id, expr.span, expr_ty, res)
            }

            hir::ExprKind::Type(ref e, _) => {
                self.cat_expr(&e)
            }

            hir::ExprKind::AddrOf(..) | hir::ExprKind::Call(..) |
            hir::ExprKind::Assign(..) | hir::ExprKind::AssignOp(..) |
            hir::ExprKind::Closure(..) | hir::ExprKind::Ret(..) |
            hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) |
            hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) |
            hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) |
            hir::ExprKind::Binary(..) | hir::ExprKind::While(..) |
            hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
            hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
            hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
            hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Err => {
                Ok(self.cat_rvalue_node(expr.hir_id, expr.span, expr_ty))
            }
        }
    }

    pub fn cat_res(&self,
                   hir_id: hir::HirId,
                   span: Span,
                   expr_ty: Ty<'tcx>,
                   res: Res)
                   -> McResult<cmt_<'tcx>> {
        debug!("cat_res: id={:?} expr={:?} def={:?}",
               hir_id, expr_ty, res);

        match res {
            Res::Def(DefKind::Ctor(..), _)
            | Res::Def(DefKind::Const, _)
            | Res::Def(DefKind::ConstParam, _)
            | Res::Def(DefKind::AssocConst, _)
            | Res::Def(DefKind::Fn, _)
            | Res::Def(DefKind::Method, _)
            | Res::SelfCtor(..) => {
                Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
            }

            Res::Def(DefKind::Static, def_id) => {
                // `#[thread_local]` statics may not outlive the current function, but
                // they also cannot be moved out of.
                let is_thread_local = self.tcx.get_attrs(def_id)[..]
                    .iter()
                    .any(|attr| attr.check_name(sym::thread_local));

                let cat = if is_thread_local {
                    let re = self.temporary_scope(hir_id.local_id);
                    Categorization::ThreadLocal(re)
                } else {
                    Categorization::StaticItem
                };

                Ok(cmt_ {
                    hir_id,
                    span,
                    cat,
                    mutbl: match self.tcx.static_mutability(def_id).unwrap() {
                        hir::MutImmutable => McImmutable,
                        hir::MutMutable => McDeclared,
                    },
                    ty:expr_ty,
                    note: NoteNone
                })
            }

            Res::Local(var_id) => {
                let var_nid = self.tcx.hir().hir_to_node_id(var_id);
                if self.upvars.map_or(false, |upvars| upvars.contains_key(&var_id)) {
                    self.cat_upvar(hir_id, span, var_nid)
                } else {
                    Ok(cmt_ {
                        hir_id,
                        span,
                        cat: Categorization::Local(var_id),
                        mutbl: MutabilityCategory::from_local(self.tcx, self.tables, var_nid),
                        ty: expr_ty,
                        note: NoteNone
                    })
                }
            }

            def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def)
        }
    }

    // Categorize an upvar, complete with invisible derefs of closure
    // environment and upvar reference as appropriate.
    fn cat_upvar(
        &self,
        hir_id: hir::HirId,
        span: Span,
        var_id: ast::NodeId,
    ) -> McResult<cmt_<'tcx>> {
        // An upvar can have up to 3 components. We translate first to a
        // `Categorization::Upvar`, which is itself a fiction -- it represents the reference to the
        // field from the environment.
        //
        // `Categorization::Upvar`.  Next, we add a deref through the implicit
        // environment pointer with an anonymous free region 'env and
        // appropriate borrow kind for closure kinds that take self by
        // reference.  Finally, if the upvar was captured
        // by-reference, we add a deref through that reference.  The
        // region of this reference is an inference variable 'up that
        // was previously generated and recorded in the upvar borrow
        // map.  The borrow kind bk is inferred by based on how the
        // upvar is used.
        //
        // This results in the following table for concrete closure
        // types:
        //
        //                | move                 | ref
        // ---------------+----------------------+-------------------------------
        // Fn             | copied -> &'env      | upvar -> &'env -> &'up bk
        // FnMut          | copied -> &'env mut  | upvar -> &'env mut -> &'up bk
        // FnOnce         | copied               | upvar -> &'up bk

        let closure_expr_def_id = self.body_owner;
        let fn_hir_id = self.tcx.hir().local_def_id_to_hir_id(
            LocalDefId::from_def_id(closure_expr_def_id),
        );
        let ty = self.node_ty(fn_hir_id)?;
        let kind = match ty.sty {
            ty::Generator(..) => ty::ClosureKind::FnOnce,
            ty::Closure(closure_def_id, closure_substs) => {
                match self.infcx {
                    // During upvar inference we may not know the
                    // closure kind, just use the LATTICE_BOTTOM value.
                    Some(infcx) =>
                        infcx.closure_kind(closure_def_id, closure_substs)
                             .unwrap_or(ty::ClosureKind::LATTICE_BOTTOM),

                    None =>
                        self.tcx.global_tcx()
                                .lift(&closure_substs)
                                .expect("no inference cx, but inference variables in closure ty")
                                .closure_kind(closure_def_id, self.tcx.global_tcx()),
                }
            }
            _ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty),
        };

        let var_hir_id = self.tcx.hir().node_to_hir_id(var_id);
        let upvar_id = ty::UpvarId {
            var_path: ty::UpvarPath { hir_id: var_hir_id },
            closure_expr_id: closure_expr_def_id.to_local(),
        };

        let var_ty = self.node_ty(var_hir_id)?;

        // Mutability of original variable itself
        let var_mutbl = MutabilityCategory::from_local(self.tcx, self.tables, var_id);

        // Construct the upvar. This represents access to the field
        // from the environment (perhaps we should eventually desugar
        // this field further, but it will do for now).
        let cmt_result = cmt_ {
            hir_id,
            span,
            cat: Categorization::Upvar(Upvar {id: upvar_id, kind: kind}),
            mutbl: var_mutbl,
            ty: var_ty,
            note: NoteNone
        };

        // If this is a `FnMut` or `Fn` closure, then the above is
        // conceptually a `&mut` or `&` reference, so we have to add a
        // deref.
        let cmt_result = match kind {
            ty::ClosureKind::FnOnce => {
                cmt_result
            }
            ty::ClosureKind::FnMut => {
                self.env_deref(hir_id, span, upvar_id, var_mutbl, ty::MutBorrow, cmt_result)
            }
            ty::ClosureKind::Fn => {
                self.env_deref(hir_id, span, upvar_id, var_mutbl, ty::ImmBorrow, cmt_result)
            }
        };

        // If this is a by-ref capture, then the upvar we loaded is
        // actually a reference, so we have to add an implicit deref
        // for that.
        let upvar_capture = self.tables.upvar_capture(upvar_id);
        let cmt_result = match upvar_capture {
            ty::UpvarCapture::ByValue => {
                cmt_result
            }
            ty::UpvarCapture::ByRef(upvar_borrow) => {
                let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region);
                cmt_ {
                    hir_id,
                    span,
                    cat: Categorization::Deref(Rc::new(cmt_result), ptr),
                    mutbl: MutabilityCategory::from_borrow_kind(upvar_borrow.kind),
                    ty: var_ty,
                    note: NoteUpvarRef(upvar_id)
                }
            }
        };

        let ret = cmt_result;
        debug!("cat_upvar ret={:?}", ret);
        Ok(ret)
    }

    fn env_deref(&self,
                 hir_id: hir::HirId,
                 span: Span,
                 upvar_id: ty::UpvarId,
                 upvar_mutbl: MutabilityCategory,
                 env_borrow_kind: ty::BorrowKind,
                 cmt_result: cmt_<'tcx>)
                 -> cmt_<'tcx>
    {
        // Region of environment pointer
        let env_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
            // The environment of a closure is guaranteed to
            // outlive any bindings introduced in the body of the
            // closure itself.
            scope: upvar_id.closure_expr_id.to_def_id(),
            bound_region: ty::BrEnv
        }));

        let env_ptr = BorrowedPtr(env_borrow_kind, env_region);

        let var_ty = cmt_result.ty;

        // We need to add the env deref.  This means
        // that the above is actually immutable and
        // has a ref type.  However, nothing should
        // actually look at the type, so we can get
        // away with stuffing a `Error` in there
        // instead of bothering to construct a proper
        // one.
        let cmt_result = cmt_ {
            mutbl: McImmutable,
            ty: self.tcx.types.err,
            ..cmt_result
        };

        let mut deref_mutbl = MutabilityCategory::from_borrow_kind(env_borrow_kind);

        // Issue #18335. If variable is declared as immutable, override the
        // mutability from the environment and substitute an `&T` anyway.
        match upvar_mutbl {
            McImmutable => { deref_mutbl = McImmutable; }
            McDeclared | McInherited => { }
        }

        let ret = cmt_ {
            hir_id,
            span,
            cat: Categorization::Deref(Rc::new(cmt_result), env_ptr),
            mutbl: deref_mutbl,
            ty: var_ty,
            note: NoteClosureEnv(upvar_id)
        };

        debug!("env_deref ret {:?}", ret);

        ret
    }

    /// Returns the lifetime of a temporary created by expr with id `id`.
    /// This could be `'static` if `id` is part of a constant expression.
    pub fn temporary_scope(&self, id: hir::ItemLocalId) -> ty::Region<'tcx> {
        let scope = self.region_scope_tree.temporary_scope(id);
        self.tcx.mk_region(match scope {
            Some(scope) => ty::ReScope(scope),
            None => ty::ReStatic
        })
    }

    pub fn cat_rvalue_node(&self,
                           hir_id: hir::HirId,
                           span: Span,
                           expr_ty: Ty<'tcx>)
                           -> cmt_<'tcx> {
        debug!("cat_rvalue_node(id={:?}, span={:?}, expr_ty={:?})",
               hir_id, span, expr_ty);

        let promotable = self.rvalue_promotable_map.as_ref().map(|m| m.contains(&hir_id.local_id))
                                                            .unwrap_or(false);

        debug!("cat_rvalue_node: promotable = {:?}", promotable);

        // Always promote `[T; 0]` (even when e.g., borrowed mutably).
        let promotable = match expr_ty.sty {
            ty::Array(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
            _ => promotable,
        };

        debug!("cat_rvalue_node: promotable = {:?} (2)", promotable);

        // Compute maximum lifetime of this rvalue. This is 'static if
        // we can promote to a constant, otherwise equal to enclosing temp
        // lifetime.
        let re = if promotable {
            self.tcx.lifetimes.re_static
        } else {
            self.temporary_scope(hir_id.local_id)
        };
        let ret = self.cat_rvalue(hir_id, span, re, expr_ty);
        debug!("cat_rvalue_node ret {:?}", ret);
        ret
    }

    pub fn cat_rvalue(&self,
                      cmt_hir_id: hir::HirId,
                      span: Span,
                      temp_scope: ty::Region<'tcx>,
                      expr_ty: Ty<'tcx>) -> cmt_<'tcx> {
        let ret = cmt_ {
            hir_id: cmt_hir_id,
            span:span,
            cat:Categorization::Rvalue(temp_scope),
            mutbl:McDeclared,
            ty:expr_ty,
            note: NoteNone
        };
        debug!("cat_rvalue ret {:?}", ret);
        ret
    }

    pub fn cat_field<N: HirNode>(&self,
                                 node: &N,
                                 base_cmt: cmt<'tcx>,
                                 f_index: usize,
                                 f_ident: ast::Ident,
                                 f_ty: Ty<'tcx>)
                                 -> cmt_<'tcx> {
        let ret = cmt_ {
            hir_id: node.hir_id(),
            span: node.span(),
            mutbl: base_cmt.mutbl.inherit(),
            cat: Categorization::Interior(base_cmt,
                                          InteriorField(FieldIndex(f_index, f_ident.name))),
            ty: f_ty,
            note: NoteNone
        };
        debug!("cat_field ret {:?}", ret);
        ret
    }

    fn cat_overloaded_place(
        &self,
        expr: &hir::Expr,
        base: &hir::Expr,
        note: Note,
    ) -> McResult<cmt_<'tcx>> {
        debug!("cat_overloaded_place(expr={:?}, base={:?}, note={:?})",
               expr,
               base,
               note);

        // Reconstruct the output assuming it's a reference with the
        // same region and mutability as the receiver. This holds for
        // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
        let place_ty = self.expr_ty(expr)?;
        let base_ty = self.expr_ty_adjusted(base)?;

        let (region, mutbl) = match base_ty.sty {
            ty::Ref(region, _, mutbl) => (region, mutbl),
            _ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
        };
        let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
            ty: place_ty,
            mutbl,
        });

        let base_cmt = Rc::new(self.cat_rvalue_node(expr.hir_id, expr.span, ref_ty));
        self.cat_deref(expr, base_cmt, note)
    }

    pub fn cat_deref(
        &self,
        node: &impl HirNode,
        base_cmt: cmt<'tcx>,
        note: Note,
    ) -> McResult<cmt_<'tcx>> {
        debug!("cat_deref: base_cmt={:?}", base_cmt);

        let base_cmt_ty = base_cmt.ty;
        let deref_ty = match base_cmt_ty.builtin_deref(true) {
            Some(mt) => mt.ty,
            None => {
                debug!("Explicit deref of non-derefable type: {:?}", base_cmt_ty);
                return Err(());
            }
        };

        let ptr = match base_cmt.ty.sty {
            ty::Adt(def, ..) if def.is_box() => Unique,
            ty::RawPtr(ref mt) => UnsafePtr(mt.mutbl),
            ty::Ref(r, _, mutbl) => {
                let bk = ty::BorrowKind::from_mutbl(mutbl);
                BorrowedPtr(bk, r)
            }
            _ => bug!("unexpected type in cat_deref: {:?}", base_cmt.ty)
        };
        let ret = cmt_ {
            hir_id: node.hir_id(),
            span: node.span(),
            // For unique ptrs, we inherit mutability from the owning reference.
            mutbl: MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr),
            cat: Categorization::Deref(base_cmt, ptr),
            ty: deref_ty,
            note: note,
        };
        debug!("cat_deref ret {:?}", ret);
        Ok(ret)
    }

    fn cat_index<N: HirNode>(&self,
                             elt: &N,
                             base_cmt: cmt<'tcx>,
                             element_ty: Ty<'tcx>,
                             context: InteriorOffsetKind)
                             -> McResult<cmt_<'tcx>> {
        //! Creates a cmt for an indexing operation (`[]`).
        //!
        //! One subtle aspect of indexing that may not be
        //! immediately obvious: for anything other than a fixed-length
        //! vector, an operation like `x[y]` actually consists of two
        //! disjoint (from the point of view of borrowck) operations.
        //! The first is a deref of `x` to create a pointer `p` that points
        //! at the first element in the array. The second operation is
        //! an index which adds `y*sizeof(T)` to `p` to obtain the
        //! pointer to `x[y]`. `cat_index` will produce a resulting
        //! cmt containing both this deref and the indexing,
        //! presuming that `base_cmt` is not of fixed-length type.
        //!
        //! # Parameters
        //! - `elt`: the HIR node being indexed
        //! - `base_cmt`: the cmt of `elt`

        let interior_elem = InteriorElement(context);
        let ret = self.cat_imm_interior(elt, base_cmt, element_ty, interior_elem);
        debug!("cat_index ret {:?}", ret);
        return Ok(ret);
    }

    pub fn cat_imm_interior<N:HirNode>(&self,
                                       node: &N,
                                       base_cmt: cmt<'tcx>,
                                       interior_ty: Ty<'tcx>,
                                       interior: InteriorKind)
                                       -> cmt_<'tcx> {
        let ret = cmt_ {
            hir_id: node.hir_id(),
            span: node.span(),
            mutbl: base_cmt.mutbl.inherit(),
            cat: Categorization::Interior(base_cmt, interior),
            ty: interior_ty,
            note: NoteNone
        };
        debug!("cat_imm_interior ret={:?}", ret);
        ret
    }

    pub fn cat_downcast_if_needed<N:HirNode>(&self,
                                             node: &N,
                                             base_cmt: cmt<'tcx>,
                                             variant_did: DefId)
                                             -> cmt<'tcx> {
        // univariant enums do not need downcasts
        let base_did = self.tcx.parent(variant_did).unwrap();
        if self.tcx.adt_def(base_did).variants.len() != 1 {
            let base_ty = base_cmt.ty;
            let ret = Rc::new(cmt_ {
                hir_id: node.hir_id(),
                span: node.span(),
                mutbl: base_cmt.mutbl.inherit(),
                cat: Categorization::Downcast(base_cmt, variant_did),
                ty: base_ty,
                note: NoteNone
            });
            debug!("cat_downcast ret={:?}", ret);
            ret
        } else {
            debug!("cat_downcast univariant={:?}", base_cmt);
            base_cmt
        }
    }

    pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, mut op: F) -> McResult<()>
        where F: FnMut(cmt<'tcx>, &hir::Pat),
    {
        self.cat_pattern_(cmt, pat, &mut op)
    }

    // FIXME(#19596) This is a workaround, but there should be a better way to do this
    fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResult<()>
        where F : FnMut(cmt<'tcx>, &hir::Pat)
    {
        // Here, `cmt` is the categorization for the value being
        // matched and pat is the pattern it is being matched against.
        //
        // In general, the way that this works is that we walk down
        // the pattern, constructing a cmt that represents the path
        // that will be taken to reach the value being matched.
        //
        // When we encounter named bindings, we take the cmt that has
        // been built up and pass it off to guarantee_valid() so that
        // we can be sure that the binding will remain valid for the
        // duration of the arm.
        //
        // (*2) There is subtlety concerning the correspondence between
        // pattern ids and types as compared to *expression* ids and
        // types. This is explained briefly. on the definition of the
        // type `cmt`, so go off and read what it says there, then
        // come back and I'll dive into a bit more detail here. :) OK,
        // back?
        //
        // In general, the id of the cmt should be the node that
        // "produces" the value---patterns aren't executable code
        // exactly, but I consider them to "execute" when they match a
        // value, and I consider them to produce the value that was
        // matched. So if you have something like:
        //
        // (FIXME: `@@3` is not legal code anymore!)
        //
        //     let x = @@3;
        //     match x {
        //       @@y { ... }
        //     }
        //
        // In this case, the cmt and the relevant ids would be:
        //
        //     CMT             Id                  Type of Id Type of cmt
        //
        //     local(x)->@->@
        //     ^~~~~~~^        `x` from discr      @@int      @@int
        //     ^~~~~~~~~~^     `@@y` pattern node  @@int      @int
        //     ^~~~~~~~~~~~~^  `@y` pattern node   @int       int
        //
        // You can see that the types of the id and the cmt are in
        // sync in the first line, because that id is actually the id
        // of an expression. But once we get to pattern ids, the types
        // step out of sync again. So you'll see below that we always
        // get the type of the *subpattern* and use that.

        debug!("cat_pattern(pat={:?}, cmt={:?})", pat, cmt);

        // If (pattern) adjustments are active for this pattern, adjust the `cmt` correspondingly.
        // `cmt`s are constructed differently from patterns. For example, in
        //
        // ```
        // match foo {
        //     &&Some(x, ) => { ... },
        //     _ => { ... },
        // }
        // ```
        //
        // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the
        // corresponding `cmt` we start with a `cmt` for `foo`, and then, by traversing the
        // pattern, try to answer the question: given the address of `foo`, how is `x` reached?
        //
        // `&&Some(x,)` `cmt_foo`
        //  `&Some(x,)` `deref { cmt_foo}`
        //   `Some(x,)` `deref { deref { cmt_foo }}`
        //        (x,)` `field0 { deref { deref { cmt_foo }}}` <- resulting cmt
        //
        // The above example has no adjustments. If the code were instead the (after adjustments,
        // equivalent) version
        //
        // ```
        // match foo {
        //     Some(x, ) => { ... },
        //     _ => { ... },
        // }
        // ```
        //
        // Then we see that to get the same result, we must start with `deref { deref { cmt_foo }}`
        // instead of `cmt_foo` since the pattern is now `Some(x,)` and not `&&Some(x,)`, even
        // though its assigned type is that of `&&Some(x,)`.
        for _ in 0..self.tables
                        .pat_adjustments()
                        .get(pat.hir_id)
                        .map(|v| v.len())
                        .unwrap_or(0)
        {
            debug!("cat_pattern: applying adjustment to cmt={:?}", cmt);
            cmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
        }
        let cmt = cmt; // lose mutability
        debug!("cat_pattern: applied adjustment derefs to get cmt={:?}", cmt);

        // Invoke the callback, but only now, after the `cmt` has adjusted.
        //
        // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that
        // case, the initial `cmt` will be that for `&Some(3)` and the pattern is `Some(x)`. We
        // don't want to call `op` with these incompatible values. As written, what happens instead
        // is that `op` is called with the adjusted cmt (that for `*&Some(3)`) and the pattern
        // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)`
        // result in the cmt `Downcast<Some>(*&Some(3)).0` associated to `x` and invoke `op` with
        // that (where the `ref` on `x` is implied).
        op(cmt.clone(), pat);

        match pat.node {
            PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
                let res = self.tables.qpath_res(qpath, pat.hir_id);
                let (cmt, expected_len) = match res {
                    Res::Err => {
                        debug!("access to unresolvable pattern {:?}", pat);
                        return Err(())
                    }
                    Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), variant_ctor_did) => {
                        let variant_did = self.tcx.parent(variant_ctor_did).unwrap();
                        let enum_did = self.tcx.parent(variant_did).unwrap();
                        (self.cat_downcast_if_needed(pat, cmt, variant_did),
                         self.tcx.adt_def(enum_did)
                             .variant_with_ctor_id(variant_ctor_did).fields.len())
                    }
                    Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _)
                    | Res::SelfCtor(..) => {
                        let ty = self.pat_ty_unadjusted(&pat)?;
                        match ty.sty {
                            ty::Adt(adt_def, _) => {
                                (cmt, adt_def.non_enum_variant().fields.len())
                            }
                            _ => {
                                span_bug!(pat.span,
                                          "tuple struct pattern unexpected type {:?}", ty);
                            }
                        }
                    }
                    def => {
                        debug!(
                            "tuple struct pattern didn't resolve to variant or struct {:?} at {:?}",
                            def,
                            pat.span,
                        );
                        self.tcx.sess.delay_span_bug(pat.span, &format!(
                            "tuple struct pattern didn't resolve to variant or struct {:?}",
                            def,
                        ));
                        return Err(());
                    }
                };

                for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
                    let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
                    let interior = InteriorField(FieldIndex(i, sym::integer(i)));
                    let subcmt = Rc::new(
                        self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                    self.cat_pattern_(subcmt, &subpat, op)?;
                }
            }

            PatKind::Struct(ref qpath, ref field_pats, _) => {
                // {f1: p1, ..., fN: pN}
                let res = self.tables.qpath_res(qpath, pat.hir_id);
                let cmt = match res {
                    Res::Err => {
                        debug!("access to unresolvable pattern {:?}", pat);
                        return Err(())
                    }
                    Res::Def(DefKind::Ctor(CtorOf::Variant, _), variant_ctor_did) => {
                        let variant_did = self.tcx.parent(variant_ctor_did).unwrap();
                        self.cat_downcast_if_needed(pat, cmt, variant_did)
                    }
                    Res::Def(DefKind::Variant, variant_did) => {
                        self.cat_downcast_if_needed(pat, cmt, variant_did)
                    }
                    _ => cmt,
                };

                for fp in field_pats {
                    let field_ty = self.pat_ty_adjusted(&fp.node.pat)?; // see (*2)
                    let f_index = self.tcx.field_index(fp.node.hir_id, self.tables);
                    let cmt_field = Rc::new(self.cat_field(pat, cmt.clone(), f_index,
                                                           fp.node.ident, field_ty));
                    self.cat_pattern_(cmt_field, &fp.node.pat, op)?;
                }
            }

            PatKind::Binding(.., Some(ref subpat)) => {
                self.cat_pattern_(cmt, &subpat, op)?;
            }

            PatKind::Tuple(ref subpats, ddpos) => {
                // (p1, ..., pN)
                let ty = self.pat_ty_unadjusted(&pat)?;
                let expected_len = match ty.sty {
                    ty::Tuple(ref tys) => tys.len(),
                    _ => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
                };
                for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
                    let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
                    let interior = InteriorField(FieldIndex(i, sym::integer(i)));
                    let subcmt = Rc::new(
                        self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                    self.cat_pattern_(subcmt, &subpat, op)?;
                }
            }

            PatKind::Box(ref subpat) | PatKind::Ref(ref subpat, _) => {
                // box p1, &p1, &mut p1.  we can ignore the mutability of
                // PatKind::Ref since that information is already contained
                // in the type.
                let subcmt = Rc::new(self.cat_deref(pat, cmt, NoteNone)?);
                self.cat_pattern_(subcmt, &subpat, op)?;
            }

            PatKind::Slice(ref before, ref slice, ref after) => {
                let element_ty = match cmt.ty.builtin_index() {
                    Some(ty) => ty,
                    None => {
                        debug!("Explicit index of non-indexable type {:?}", cmt);
                        return Err(());
                    }
                };
                let context = InteriorOffsetKind::Pattern;
                let elt_cmt = Rc::new(self.cat_index(pat, cmt, element_ty, context)?);
                for before_pat in before {
                    self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
                }
                if let Some(ref slice_pat) = *slice {
                    self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
                }
                for after_pat in after {
                    self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;
                }
            }

            PatKind::Path(_) | PatKind::Binding(.., None) |
            PatKind::Lit(..) | PatKind::Range(..) | PatKind::Wild => {
                // always ok
            }
        }

        Ok(())
    }
}

#[derive(Clone, Debug)]
pub enum Aliasability {
    FreelyAliasable(AliasableReason),
    NonAliasable,
    ImmutableUnique(Box<Aliasability>),
}

#[derive(Copy, Clone, Debug)]
pub enum AliasableReason {
    AliasableBorrowed,
    AliasableStatic,
    AliasableStaticMut,
}

impl<'tcx> cmt_<'tcx> {
    pub fn guarantor(&self) -> cmt_<'tcx> {
        //! Returns `self` after stripping away any derefs or
        //! interior content. The return value is basically the `cmt` which
        //! determines how long the value in `self` remains live.

        match self.cat {
            Categorization::Rvalue(..) |
            Categorization::StaticItem |
            Categorization::ThreadLocal(..) |
            Categorization::Local(..) |
            Categorization::Deref(_, UnsafePtr(..)) |
            Categorization::Deref(_, BorrowedPtr(..)) |
            Categorization::Upvar(..) => {
                (*self).clone()
            }
            Categorization::Downcast(ref b, _) |
            Categorization::Interior(ref b, _) |
            Categorization::Deref(ref b, Unique) => {
                b.guarantor()
            }
        }
    }

    /// Returns `FreelyAliasable(_)` if this place represents a freely aliasable pointer type.
    pub fn freely_aliasable(&self) -> Aliasability {
        // Maybe non-obvious: copied upvars can only be considered
        // non-aliasable in once closures, since any other kind can be
        // aliased and eventually recused.

        match self.cat {
            Categorization::Deref(ref b, BorrowedPtr(ty::MutBorrow, _)) |
            Categorization::Deref(ref b, BorrowedPtr(ty::UniqueImmBorrow, _)) |
            Categorization::Deref(ref b, Unique) |
            Categorization::Downcast(ref b, _) |
            Categorization::Interior(ref b, _) => {
                // Aliasability depends on base cmt
                b.freely_aliasable()
            }

            Categorization::Rvalue(..) |
            Categorization::ThreadLocal(..) |
            Categorization::Local(..) |
            Categorization::Upvar(..) |
            Categorization::Deref(_, UnsafePtr(..)) => { // yes, it's aliasable, but...
                NonAliasable
            }

            Categorization::StaticItem => {
                if self.mutbl.is_mutable() {
                    FreelyAliasable(AliasableStaticMut)
                } else {
                    FreelyAliasable(AliasableStatic)
                }
            }

            Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) => {
                FreelyAliasable(AliasableBorrowed)
            }
        }
    }

    // Digs down through one or two layers of deref and grabs the
    // Categorization of the cmt for the upvar if a note indicates there is
    // one.
    pub fn upvar_cat(&self) -> Option<&Categorization<'tcx>> {
        match self.note {
            NoteClosureEnv(..) | NoteUpvarRef(..) => {
                Some(match self.cat {
                    Categorization::Deref(ref inner, _) => {
                        match inner.cat {
                            Categorization::Deref(ref inner, _) => &inner.cat,
                            Categorization::Upvar(..) => &inner.cat,
                            _ => bug!()
                        }
                    }
                    _ => bug!()
                })
            }
            NoteIndex | NoteNone => None
        }
    }

    pub fn descriptive_string(&self, tcx: TyCtxt<'_, '_, '_>) -> Cow<'static, str> {
        match self.cat {
            Categorization::StaticItem => {
                "static item".into()
            }
            Categorization::ThreadLocal(..) => {
                "thread-local static item".into()
            }
            Categorization::Rvalue(..) => {
                "non-place".into()
            }
            Categorization::Local(vid) => {
                if tcx.hir().is_argument(tcx.hir().hir_to_node_id(vid)) {
                    "argument"
                } else {
                    "local variable"
                }.into()
            }
            Categorization::Deref(_, pk) => {
                match self.upvar_cat() {
                    Some(&Categorization::Upvar(ref var)) => {
                        var.to_string().into()
                    }
                    Some(_) => bug!(),
                    None => {
                        match pk {
                            Unique => {
                                "`Box` content"
                            }
                            UnsafePtr(..) => {
                                "dereference of raw pointer"
                            }
                            BorrowedPtr(..) => {
                                match self.note {
                                    NoteIndex => "indexed content",
                                    _ => "borrowed content"
                                }
                            }
                        }.into()
                    }
                }
            }
            Categorization::Interior(_, InteriorField(..)) => {
                "field".into()
            }
            Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Index)) => {
                "indexed content".into()
            }
            Categorization::Interior(_, InteriorElement(InteriorOffsetKind::Pattern)) => {
                "pattern-bound indexed content".into()
            }
            Categorization::Upvar(ref var) => {
                var.to_string().into()
            }
            Categorization::Downcast(ref cmt, _) => {
                cmt.descriptive_string(tcx).into()
            }
        }
    }
}

pub fn ptr_sigil(ptr: PointerKind<'_>) -> &'static str {
    match ptr {
        Unique => "Box",
        BorrowedPtr(ty::ImmBorrow, _) => "&",
        BorrowedPtr(ty::MutBorrow, _) => "&mut",
        BorrowedPtr(ty::UniqueImmBorrow, _) => "&unique",
        UnsafePtr(_) => "*",
    }
}

impl fmt::Debug for InteriorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            InteriorField(FieldIndex(_, info)) => write!(f, "{}", info),
            InteriorElement(..) => write!(f, "[]"),
        }
    }
}

impl fmt::Debug for Upvar {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}/{:?}", self.id, self.kind)
    }
}

impl fmt::Display for Upvar {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let kind = match self.kind {
            ty::ClosureKind::Fn => "Fn",
            ty::ClosureKind::FnMut => "FnMut",
            ty::ClosureKind::FnOnce => "FnOnce",
        };
        write!(f, "captured outer variable in an `{}` closure", kind)
    }
}
