//! # 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.

use rustc::hir;
use rustc::hir::PatKind;
use rustc::hir::def_id::DefId;
use rustc::hir::def::{Res, DefKind};
use rustc::infer::InferCtxt;
use rustc::ty::adjustment;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::fold::TypeFoldable;

use syntax_pos::Span;

use rustc_data_structures::fx::FxIndexMap;

#[derive(Clone, Debug)]
pub enum PlaceBase {
    /// A temporary variable
    Rvalue,
    /// A named `static` item
    StaticItem,
    /// A named local variable
    Local(hir::HirId),
    /// An upvar referenced by closure env
    Upvar(ty::UpvarId),
}

#[derive(Clone, Debug)]
pub enum Projection<'tcx> {
    /// A dereference of a pointer, reference or `Box<T>` of the given type
    Deref(Ty<'tcx>),
    /// An index or a field
    Other,
}

/// A `Place` represents how a value is located in memory.
///
/// This is an HIR version of `mir::Place`
#[derive(Clone, Debug)]
pub struct Place<'tcx> {
    /// `HirId` of the expression or pattern producing this value.
    pub hir_id: hir::HirId,
    /// The `Span` of the expression or pattern producing this value.
    pub span: Span,
    /// The type of the `Place`
    pub ty: Ty<'tcx>,
    /// The "outermost" place that holds this value.
    pub base: PlaceBase,
    /// How this place is derived from the base place.
    pub projections: Vec<Projection<'tcx>>,
}

impl<'tcx> Place<'tcx> {
    /// Returns an iterator of the types that have to be dereferenced to access
    /// the `Place`.
    ///
    /// The types are in the reverse order that they are applied. So if
    /// `x: &*const u32` and the `Place` is `**x`, then the types returned are
    ///`*const u32` then `&*const u32`.
    crate fn deref_tys(&self) -> impl Iterator<Item=Ty<'tcx>> + '_ {
        self.projections.iter().rev().filter_map(|proj| if let Projection::Deref(deref_ty) = *proj {
            Some(deref_ty)
        } else {
            None
        })
    }
}

crate 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)]
crate struct MemCategorizationContext<'a, 'tcx> {
    crate tables: &'a ty::TypeckTables<'tcx>,
    infcx: &'a InferCtxt<'a, 'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    body_owner: DefId,
    upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
}

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

impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
    /// Creates a `MemCategorizationContext`.
    crate fn new(
        infcx: &'a InferCtxt<'a, 'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        body_owner: DefId,
        tables: &'a ty::TypeckTables<'tcx>,
    ) -> MemCategorizationContext<'a, 'tcx> {
        MemCategorizationContext {
            tables,
            infcx,
            param_env,
            body_owner,
            upvars: infcx.tcx.upvars(body_owner),
        }
    }

    crate fn tcx(&self) -> TyCtxt<'tcx> {
        self.infcx.tcx
    }

    crate fn type_is_copy_modulo_regions(
        &self,
        ty: Ty<'tcx>,
        span: Span,
    ) -> bool {
        self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span)
    }

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

    fn is_tainted_by_errors(&self) -> bool {
        self.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 => {
                bug!("no type for node {}: {} in mem_categorization",
                     id, self.tcx().hir().node_to_string(id));
            }
        }
    }

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

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

    crate 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>).
    crate 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.kind {
            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)
    }

    crate fn cat_expr(&self, expr: &hir::Expr) -> McResult<Place<'tcx>> {
        // This recursion helper avoids going through *too many*
        // adjustments, since *only* non-overloaded deref recurses.
        fn helper<'a, 'tcx>(
            mc: &MemCategorizationContext<'a, 'tcx>,
            expr: &hir::Expr,
            adjustments: &[adjustment::Adjustment<'tcx>],
        ) -> McResult<Place<'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))
    }

    crate fn cat_expr_adjusted(&self, expr: &hir::Expr,
                             previous: Place<'tcx>,
                             adjustment: &adjustment::Adjustment<'tcx>)
                             -> McResult<Place<'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<Place<'tcx>>
        where F: FnOnce() -> McResult<Place<'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 = if let Some(deref) = overloaded {
                    let ref_ty = self.tcx().mk_ref(deref.region, ty::TypeAndMut {
                        ty: target,
                        mutbl: deref.mutbl,
                    });
                    self.cat_rvalue(expr.hir_id, expr.span, ref_ty)
                } else {
                    previous()?
                };
                self.cat_deref(expr, base)
            }

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

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

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

            hir::ExprKind::Field(ref base, _) => {
                let base = self.cat_expr(&base)?;
                debug!("cat_expr(cat_field): id={} expr={:?} base={:?}",
                       expr.hir_id,
                       expr,
                       base);
                Ok(self.cat_projection(expr, base, 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)
                } else {
                    let base = self.cat_expr(&base)?;
                    Ok(self.cat_projection(expr, base, expr_ty))
                }
            }

            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::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(expr.hir_id, expr.span, expr_ty))
            }
        }
    }

    crate fn cat_res(&self,
                   hir_id: hir::HirId,
                   span: Span,
                   expr_ty: Ty<'tcx>,
                   res: Res)
                   -> McResult<Place<'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(hir_id, span, expr_ty))
            }

            Res::Def(DefKind::Static, _) => {
                Ok(Place {
                    hir_id,
                    span,
                    ty: expr_ty,
                    base: PlaceBase::StaticItem,
                    projections: Vec::new(),
                })
            }

            Res::Local(var_id) => {
                if self.upvars.map_or(false, |upvars| upvars.contains_key(&var_id)) {
                    self.cat_upvar(hir_id, span, var_id)
                } else {
                    Ok(Place {
                        hir_id,
                        span,
                        ty: expr_ty,
                        base: PlaceBase::Local(var_id),
                        projections: Vec::new(),
                    })
                }
            }

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

    /// Categorize an upvar.
    ///
    /// Note: the actual upvar access contains invisible derefs of closure
    /// environment and upvar reference as appropriate. Only regionck cares
    /// about these dereferences, so we let it compute them as needed.
    fn cat_upvar(
        &self,
        hir_id: hir::HirId,
        span: Span,
        var_id: hir::HirId,
    ) -> McResult<Place<'tcx>> {
        let closure_expr_def_id = self.body_owner;

        let upvar_id = ty::UpvarId {
            var_path: ty::UpvarPath { hir_id: var_id },
            closure_expr_id: closure_expr_def_id.to_local(),
        };
        let var_ty = self.node_ty(var_id)?;

        let ret = Place {
            hir_id,
            span,
            ty: var_ty,
            base: PlaceBase::Upvar(upvar_id),
            projections: Vec::new(),
        };

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

    crate fn cat_rvalue(&self, hir_id: hir::HirId, span: Span, expr_ty: Ty<'tcx>) -> Place<'tcx> {
        debug!("cat_rvalue hir_id={:?}, expr_ty={:?}, span={:?}", hir_id, expr_ty, span);
        let ret = Place {
            hir_id,
            span,
            base: PlaceBase::Rvalue,
            projections: Vec::new(),
            ty: expr_ty,
        };
        debug!("cat_rvalue ret={:?}", ret);
        ret
    }

    crate fn cat_projection<N: HirNode>(
        &self,
        node: &N,
        base_place: Place<'tcx>,
        ty: Ty<'tcx>,
    ) -> Place<'tcx> {
        let mut projections = base_place.projections;
        projections.push(Projection::Other);
        let ret = Place {
            hir_id: node.hir_id(),
            span: node.span(),
            ty,
            base: base_place.base,
            projections,
        };
        debug!("cat_field ret {:?}", ret);
        ret
    }

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

        // 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.kind {
            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 = self.cat_rvalue(expr.hir_id, expr.span, ref_ty);
        self.cat_deref(expr, base)
    }

    fn cat_deref(
        &self,
        node: &impl HirNode,
        base_place: Place<'tcx>,
    ) -> McResult<Place<'tcx>> {
        debug!("cat_deref: base_place={:?}", base_place);

        let base_ty = base_place.ty;
        let deref_ty = match base_ty.builtin_deref(true) {
            Some(mt) => mt.ty,
            None => {
                debug!("explicit deref of non-derefable type: {:?}", base_ty);
                return Err(());
            }
        };
        let mut projections = base_place.projections;
        projections.push(Projection::Deref(base_ty));

        let ret = Place {
            hir_id: node.hir_id(),
            span: node.span(),
            ty: deref_ty,
            base: base_place.base,
            projections,
        };
        debug!("cat_deref ret {:?}", ret);
        Ok(ret)
    }

    crate fn cat_pattern<F>(&self, place: Place<'tcx>, pat: &hir::Pat, mut op: F) -> McResult<()>
        where F: FnMut(&Place<'tcx>, &hir::Pat),
    {
        self.cat_pattern_(place, 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 place: Place<'tcx>, pat: &hir::Pat, op: &mut F) -> McResult<()>
        where F: FnMut(&Place<'tcx>, &hir::Pat)
    {
        // Here, `place` is the `Place` 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 `Place` that represents the path that will be taken
        // to reach the value being matched.

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

        // If (pattern) adjustments are active for this pattern, adjust the `Place` correspondingly.
        // `Place`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 `Place` we start with the `Place` for `foo`, and then, by traversing the
        // pattern, try to answer the question: given the address of `foo`, how is `x` reached?
        //
        // `&&Some(x,)` `place_foo`
        //  `&Some(x,)` `deref { place_foo}`
        //   `Some(x,)` `deref { deref { place_foo }}`
        //        (x,)` `field0 { deref { deref { place_foo }}}` <- resulting place
        //
        // 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 { place_foo }}` instead of `place_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 place={:?}", place);
            place = self.cat_deref(pat, place)?;
        }
        let place = place; // lose mutability
        debug!("cat_pattern: applied adjustment derefs to get place={:?}", place);

        // Invoke the callback, but only now, after the `place` has adjusted.
        //
        // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that
        // case, the initial `place` 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 place (that for `*&Some(3)`) and the pattern
        // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)`
        // result in the place `Downcast<Some>(*&Some(3)).0` associated to `x` and invoke `op` with
        // that (where the `ref` on `x` is implied).
        op(&place, pat);

        match pat.kind {
            PatKind::TupleStruct(_, ref subpats, _)
            | PatKind::Tuple(ref subpats, _) => {
                // S(p1, ..., pN) or (p1, ..., pN)
                for subpat in subpats.iter() {
                    let subpat_ty = self.pat_ty_adjusted(&subpat)?;
                    let sub_place = self.cat_projection(pat, place.clone(), subpat_ty);
                    self.cat_pattern_(sub_place, &subpat, op)?;
                }
            }

            PatKind::Struct(_, ref field_pats, _) => {
                // S { f1: p1, ..., fN: pN }
                for fp in field_pats {
                    let field_ty = self.pat_ty_adjusted(&fp.pat)?;
                    let field_place = self.cat_projection(pat, place.clone(), field_ty);
                    self.cat_pattern_(field_place, &fp.pat, op)?;
                }
            }

            PatKind::Or(ref pats) => {
                for pat in pats {
                    self.cat_pattern_(place.clone(), &pat, op)?;
                }
            }

            PatKind::Binding(.., Some(ref subpat)) => {
                self.cat_pattern_(place, &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 subplace = self.cat_deref(pat, place)?;
                self.cat_pattern_(subplace, &subpat, op)?;
            }

            PatKind::Slice(ref before, ref slice, ref after) => {
                let element_ty = match place.ty.builtin_index() {
                    Some(ty) => ty,
                    None => {
                        debug!("explicit index of non-indexable type {:?}", place);
                        return Err(());
                    }
                };
                let elt_place = self.cat_projection(pat, place.clone(), element_ty);
                for before_pat in before {
                    self.cat_pattern_(elt_place.clone(), &before_pat, op)?;
                }
                if let Some(ref slice_pat) = *slice {
                    let slice_pat_ty = self.pat_ty_adjusted(&slice_pat)?;
                    let slice_place = self.cat_projection(pat, place, slice_pat_ty);
                    self.cat_pattern_(slice_place, &slice_pat, op)?;
                }
                for after_pat in after {
                    self.cat_pattern_(elt_place.clone(), &after_pat, op)?;
                }
            }

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

        Ok(())
    }
}
