//! This pass type-checks the MIR to ensure it is not broken.

use std::rc::Rc;
use std::{fmt, iter, mem};

use either::Either;

use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{
    InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin,
};
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::AssertKind;
use rustc_middle::mir::*;
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
use rustc_middle::ty::{
    self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef, Ty,
    TyCtxt, UserType, UserTypeAnnotationIndex,
};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::opaque_types::{GenerateMemberConstraints, InferCtxtExt};
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::query::type_op;
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligations};

use crate::dataflow::move_paths::MoveData;
use crate::dataflow::MaybeInitializedPlaces;
use crate::dataflow::ResultsCursor;
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;

use crate::borrow_check::{
    borrow_set::BorrowSet,
    constraints::{OutlivesConstraint, OutlivesConstraintSet},
    facts::AllFacts,
    location::LocationTable,
    member_constraints::MemberConstraintSet,
    nll::ToRegionVid,
    region_infer::values::{
        LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
    },
    region_infer::{ClosureRegionRequirementsExt, TypeTest},
    renumber,
    type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
    universal_regions::{DefiningTy, UniversalRegions},
};

macro_rules! span_mirbug {
    ($context:expr, $elem:expr, $($message:tt)*) => ({
        $crate::borrow_check::type_check::mirbug(
            $context.tcx(),
            $context.last_span,
            &format!(
                "broken MIR in {:?} ({:?}): {}",
                $context.mir_def_id,
                $elem,
                format_args!($($message)*),
            ),
        )
    })
}

macro_rules! span_mirbug_and_err {
    ($context:expr, $elem:expr, $($message:tt)*) => ({
        {
            span_mirbug!($context, $elem, $($message)*);
            $context.error()
        }
    })
}

mod constraint_conversion;
pub mod free_region_relations;
mod input_output;
crate mod liveness;
mod relate_tys;

/// Type checks the given `mir` in the context of the inference
/// context `infcx`. Returns any region constraints that have yet to
/// be proven. This result is includes liveness constraints that
/// ensure that regions appearing in the types of all local variables
/// are live at all points where that local variable may later be
/// used.
///
/// This phase of type-check ought to be infallible -- this is because
/// the original, HIR-based type-check succeeded. So if any errors
/// occur here, we will get a `bug!` reported.
///
/// # Parameters
///
/// - `infcx` -- inference context to use
/// - `param_env` -- parameter environment to use for trait solving
/// - `mir` -- MIR to type-check
/// - `mir_def_id` -- DefId from which the MIR is derived (must be local)
/// - `region_bound_pairs` -- the implied outlives obligations between type parameters
///   and lifetimes (e.g., `&'a T` implies `T: 'a`)
/// - `implicit_region_bound` -- a region which all generic parameters are assumed
///   to outlive; should represent the fn body
/// - `input_tys` -- fully liberated, but **not** normalized, expected types of the arguments;
///   the types of the input parameters found in the MIR itself will be equated with these
/// - `output_ty` -- fully liberated, but **not** normalized, expected return type;
///   the type for the RETURN_PLACE will be equated with this
/// - `liveness` -- results of a liveness computation on the MIR; used to create liveness
///   constraints for the regions in the types of variables
/// - `flow_inits` -- results of a maybe-init dataflow analysis
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
pub(crate) fn type_check<'mir, 'tcx>(
    infcx: &InferCtxt<'_, 'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    body: ReadOnlyBodyAndCache<'_, 'tcx>,
    promoted: &IndexVec<Promoted, ReadOnlyBodyAndCache<'_, 'tcx>>,
    mir_def_id: DefId,
    universal_regions: &Rc<UniversalRegions<'tcx>>,
    location_table: &LocationTable,
    borrow_set: &BorrowSet<'tcx>,
    all_facts: &mut Option<AllFacts>,
    flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
    move_data: &MoveData<'tcx>,
    elements: &Rc<RegionValueElements>,
) -> MirTypeckResults<'tcx> {
    let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
    let mut constraints = MirTypeckRegionConstraints {
        placeholder_indices: PlaceholderIndices::default(),
        placeholder_index_to_region: IndexVec::default(),
        liveness_constraints: LivenessValues::new(elements.clone()),
        outlives_constraints: OutlivesConstraintSet::default(),
        member_constraints: MemberConstraintSet::default(),
        closure_bounds_mapping: Default::default(),
        type_tests: Vec::default(),
    };

    let CreateResult {
        universal_region_relations,
        region_bound_pairs,
        normalized_inputs_and_output,
    } = free_region_relations::create(
        infcx,
        param_env,
        Some(implicit_region_bound),
        universal_regions,
        &mut constraints,
    );

    let mut borrowck_context = BorrowCheckContext {
        universal_regions,
        location_table,
        borrow_set,
        all_facts,
        constraints: &mut constraints,
    };

    let opaque_type_values = type_check_internal(
        infcx,
        mir_def_id,
        param_env,
        body,
        promoted,
        &region_bound_pairs,
        implicit_region_bound,
        &mut borrowck_context,
        &universal_region_relations,
        |mut cx| {
            cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
            liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);

            translate_outlives_facts(&mut cx);
            cx.opaque_type_values
        },
    );

    MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
}

fn type_check_internal<'a, 'tcx, R>(
    infcx: &'a InferCtxt<'a, 'tcx>,
    mir_def_id: DefId,
    param_env: ty::ParamEnv<'tcx>,
    body: ReadOnlyBodyAndCache<'a, 'tcx>,
    promoted: &'a IndexVec<Promoted, ReadOnlyBodyAndCache<'_, 'tcx>>,
    region_bound_pairs: &'a RegionBoundPairs<'tcx>,
    implicit_region_bound: ty::Region<'tcx>,
    borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
    universal_region_relations: &'a UniversalRegionRelations<'tcx>,
    extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R,
) -> R {
    let mut checker = TypeChecker::new(
        infcx,
        *body,
        mir_def_id,
        param_env,
        region_bound_pairs,
        implicit_region_bound,
        borrowck_context,
        universal_region_relations,
    );
    let errors_reported = {
        let mut verifier = TypeVerifier::new(&mut checker, *body, promoted);
        verifier.visit_body(&body);
        verifier.errors_reported
    };

    if !errors_reported {
        // if verifier failed, don't do further checks to avoid ICEs
        checker.typeck_mir(body);
    }

    extra(checker)
}

fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
    let cx = &mut typeck.borrowck_context;
    if let Some(facts) = cx.all_facts {
        let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation");
        let location_table = cx.location_table;
        facts.outlives.extend(cx.constraints.outlives_constraints.outlives().iter().flat_map(
            |constraint: &OutlivesConstraint| {
                if let Some(from_location) = constraint.locations.from_location() {
                    Either::Left(iter::once((
                        constraint.sup,
                        constraint.sub,
                        location_table.mid_index(from_location),
                    )))
                } else {
                    Either::Right(
                        location_table
                            .all_points()
                            .map(move |location| (constraint.sup, constraint.sub, location)),
                    )
                }
            },
        ));
    }
}

fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: &str) {
    // We sometimes see MIR failures (notably predicate failures) due to
    // the fact that we check rvalue sized predicates here. So use `delay_span_bug`
    // to avoid reporting bugs in those cases.
    tcx.sess.diagnostic().delay_span_bug(span, msg);
}

enum FieldAccessError {
    OutOfRange { field_count: usize },
}

/// Verifies that MIR types are sane to not crash further checks.
///
/// The sanitize_XYZ methods here take an MIR object and compute its
/// type, calling `span_mirbug` and returning an error type if there
/// is a problem.
struct TypeVerifier<'a, 'b, 'tcx> {
    cx: &'a mut TypeChecker<'b, 'tcx>,
    body: &'b Body<'tcx>,
    promoted: &'b IndexVec<Promoted, ReadOnlyBodyAndCache<'b, 'tcx>>,
    last_span: Span,
    mir_def_id: DefId,
    errors_reported: bool,
}

impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
    fn visit_span(&mut self, span: &Span) {
        if !span.is_dummy() {
            self.last_span = *span;
        }
    }

    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
        self.sanitize_place(place, location, context);
    }

    fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
        self.super_constant(constant, location);
        let ty = self.sanitize_type(constant, constant.literal.ty);

        self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
            let live_region_vid =
                self.cx.borrowck_context.universal_regions.to_region_vid(live_region);
            self.cx
                .borrowck_context
                .constraints
                .liveness_constraints
                .add_element(live_region_vid, location);
        });

        if let Some(annotation_index) = constant.user_ty {
            if let Err(terr) = self.cx.relate_type_and_user_type(
                constant.literal.ty,
                ty::Variance::Invariant,
                &UserTypeProjection { base: annotation_index, projs: vec![] },
                location.to_locations(),
                ConstraintCategory::Boring,
            ) {
                let annotation = &self.cx.user_type_annotations[annotation_index];
                span_mirbug!(
                    self,
                    constant,
                    "bad constant user type {:?} vs {:?}: {:?}",
                    annotation,
                    constant.literal.ty,
                    terr,
                );
            }
        } else {
            let tcx = self.tcx();
            if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.literal.val {
                if let Some(promoted) = promoted {
                    let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
                                     promoted: &ReadOnlyBodyAndCache<'_, 'tcx>,
                                     ty,
                                     san_ty| {
                        if let Err(terr) = verifier.cx.eq_types(
                            san_ty,
                            ty,
                            location.to_locations(),
                            ConstraintCategory::Boring,
                        ) {
                            span_mirbug!(
                                verifier,
                                promoted,
                                "bad promoted type ({:?}: {:?}): {:?}",
                                ty,
                                san_ty,
                                terr
                            );
                        };
                    };

                    if !self.errors_reported {
                        let promoted_body = self.promoted[promoted];
                        self.sanitize_promoted(promoted_body, location);

                        let promoted_ty = promoted_body.return_ty();
                        check_err(self, &promoted_body, ty, promoted_ty);
                    }
                } else {
                    if let Err(terr) = self.cx.fully_perform_op(
                        location.to_locations(),
                        ConstraintCategory::Boring,
                        self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
                            constant.literal.ty,
                            def_id,
                            UserSubsts { substs, user_self_ty: None },
                        )),
                    ) {
                        span_mirbug!(
                            self,
                            constant,
                            "bad constant type {:?} ({:?})",
                            constant,
                            terr
                        );
                    }
                }
            } else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
                let unnormalized_ty = tcx.type_of(static_def_id);
                let locations = location.to_locations();
                let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
                let literal_ty = constant.literal.ty.builtin_deref(true).unwrap().ty;

                if let Err(terr) = self.cx.eq_types(
                    normalized_ty,
                    literal_ty,
                    locations,
                    ConstraintCategory::Boring,
                ) {
                    span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
                }
            }

            if let ty::FnDef(def_id, substs) = constant.literal.ty.kind {
                let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
                self.cx.normalize_and_prove_instantiated_predicates(
                    instantiated_predicates,
                    location.to_locations(),
                );
            }
        }
    }

    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
        self.super_rvalue(rvalue, location);
        let rval_ty = rvalue.ty(self.body, self.tcx());
        self.sanitize_type(rvalue, rval_ty);
    }

    fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
        self.super_local_decl(local, local_decl);
        self.sanitize_type(local_decl, local_decl.ty);

        for (user_ty, span) in local_decl.user_ty.projections_and_spans() {
            let ty = if !local_decl.is_nonref_binding() {
                // If we have a binding of the form `let ref x: T = ..` then remove the outermost
                // reference so we can check the type annotation for the remaining type.
                if let ty::Ref(_, rty, _) = local_decl.ty.kind {
                    rty
                } else {
                    bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
                }
            } else {
                local_decl.ty
            };

            if let Err(terr) = self.cx.relate_type_and_user_type(
                ty,
                ty::Variance::Invariant,
                user_ty,
                Locations::All(*span),
                ConstraintCategory::TypeAnnotation,
            ) {
                span_mirbug!(
                    self,
                    local,
                    "bad user type on variable {:?}: {:?} != {:?} ({:?})",
                    local,
                    local_decl.ty,
                    local_decl.user_ty,
                    terr,
                );
            }
        }
    }

    fn visit_body(&mut self, body: &Body<'tcx>) {
        self.sanitize_type(&"return type", body.return_ty());
        for local_decl in &body.local_decls {
            self.sanitize_type(local_decl, local_decl.ty);
        }
        if self.errors_reported {
            return;
        }
        self.super_body(body);
    }
}

impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
    fn new(
        cx: &'a mut TypeChecker<'b, 'tcx>,
        body: &'b Body<'tcx>,
        promoted: &'b IndexVec<Promoted, ReadOnlyBodyAndCache<'b, 'tcx>>,
    ) -> Self {
        TypeVerifier {
            body,
            promoted,
            mir_def_id: cx.mir_def_id,
            cx,
            last_span: body.span,
            errors_reported: false,
        }
    }

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

    fn sanitize_type(&mut self, parent: &dyn fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> {
        if ty.has_escaping_bound_vars() || ty.references_error() {
            span_mirbug_and_err!(self, parent, "bad type {:?}", ty)
        } else {
            ty
        }
    }

    /// Checks that the types internal to the `place` match up with
    /// what would be expected.
    fn sanitize_place(
        &mut self,
        place: &Place<'tcx>,
        location: Location,
        context: PlaceContext,
    ) -> PlaceTy<'tcx> {
        debug!("sanitize_place: {:?}", place);

        let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty);

        for elem in place.projection.iter() {
            if place_ty.variant_index.is_none() {
                if place_ty.ty.references_error() {
                    assert!(self.errors_reported);
                    return PlaceTy::from_ty(self.tcx().types.err);
                }
            }
            place_ty = self.sanitize_projection(place_ty, elem, place, location)
        }

        if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
            let tcx = self.tcx();
            let trait_ref = ty::TraitRef {
                def_id: tcx.lang_items().copy_trait().unwrap(),
                substs: tcx.mk_substs_trait(place_ty.ty, &[]),
            };

            // To have a `Copy` operand, the type `T` of the
            // value must be `Copy`. Note that we prove that `T: Copy`,
            // rather than using the `is_copy_modulo_regions`
            // test. This is important because
            // `is_copy_modulo_regions` ignores the resulting region
            // obligations and assumes they pass. This can result in
            // bounds from `Copy` impls being unsoundly ignored (e.g.,
            // #29149). Note that we decide to use `Copy` before knowing
            // whether the bounds fully apply: in effect, the rule is
            // that if a value of some type could implement `Copy`, then
            // it must.
            self.cx.prove_trait_ref(
                trait_ref,
                location.to_locations(),
                ConstraintCategory::CopyBound,
            );
        }

        place_ty
    }

    fn sanitize_promoted(
        &mut self,
        promoted_body: ReadOnlyBodyAndCache<'b, 'tcx>,
        location: Location,
    ) {
        // Determine the constraints from the promoted MIR by running the type
        // checker on the promoted MIR, then transfer the constraints back to
        // the main MIR, changing the locations to the provided location.

        let parent_body = mem::replace(&mut self.body, *promoted_body);

        // Use new sets of constraints and closure bounds so that we can
        // modify their locations.
        let all_facts = &mut None;
        let mut constraints = Default::default();
        let mut closure_bounds = Default::default();
        let mut liveness_constraints =
            LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body)));
        // Don't try to add borrow_region facts for the promoted MIR

        let mut swap_constraints = |this: &mut Self| {
            mem::swap(this.cx.borrowck_context.all_facts, all_facts);
            mem::swap(
                &mut this.cx.borrowck_context.constraints.outlives_constraints,
                &mut constraints,
            );
            mem::swap(
                &mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
                &mut closure_bounds,
            );
            mem::swap(
                &mut this.cx.borrowck_context.constraints.liveness_constraints,
                &mut liveness_constraints,
            );
        };

        swap_constraints(self);

        self.visit_body(&promoted_body);

        if !self.errors_reported {
            // if verifier failed, don't do further checks to avoid ICEs
            self.cx.typeck_mir(promoted_body);
        }

        self.body = parent_body;
        // Merge the outlives constraints back in, at the given location.
        swap_constraints(self);

        let locations = location.to_locations();
        for constraint in constraints.outlives().iter() {
            let mut constraint = *constraint;
            constraint.locations = locations;
            if let ConstraintCategory::Return
            | ConstraintCategory::UseAsConst
            | ConstraintCategory::UseAsStatic = constraint.category
            {
                // "Returning" from a promoted is an assignment to a
                // temporary from the user's point of view.
                constraint.category = ConstraintCategory::Boring;
            }
            self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
        }
        for live_region in liveness_constraints.rows() {
            self.cx
                .borrowck_context
                .constraints
                .liveness_constraints
                .add_element(live_region, location);
        }

        if !closure_bounds.is_empty() {
            let combined_bounds_mapping =
                closure_bounds.into_iter().flat_map(|(_, value)| value).collect();
            let existing = self
                .cx
                .borrowck_context
                .constraints
                .closure_bounds_mapping
                .insert(location, combined_bounds_mapping);
            assert!(existing.is_none(), "Multiple promoteds/closures at the same location.");
        }
    }

    fn sanitize_projection(
        &mut self,
        base: PlaceTy<'tcx>,
        pi: &PlaceElem<'tcx>,
        place: &Place<'tcx>,
        location: Location,
    ) -> PlaceTy<'tcx> {
        debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, place);
        let tcx = self.tcx();
        let base_ty = base.ty;
        match *pi {
            ProjectionElem::Deref => {
                let deref_ty = base_ty.builtin_deref(true);
                PlaceTy::from_ty(deref_ty.map(|t| t.ty).unwrap_or_else(|| {
                    span_mirbug_and_err!(self, place, "deref of non-pointer {:?}", base_ty)
                }))
            }
            ProjectionElem::Index(i) => {
                let index_ty = Place::from(i).ty(self.body, tcx).ty;
                if index_ty != tcx.types.usize {
                    PlaceTy::from_ty(span_mirbug_and_err!(self, i, "index by non-usize {:?}", i))
                } else {
                    PlaceTy::from_ty(base_ty.builtin_index().unwrap_or_else(|| {
                        span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
                    }))
                }
            }
            ProjectionElem::ConstantIndex { .. } => {
                // consider verifying in-bounds
                PlaceTy::from_ty(base_ty.builtin_index().unwrap_or_else(|| {
                    span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
                }))
            }
            ProjectionElem::Subslice { from, to, from_end } => {
                PlaceTy::from_ty(match base_ty.kind {
                    ty::Array(inner, _) => {
                        assert!(!from_end, "array subslices should not use from_end");
                        tcx.mk_array(inner, (to - from) as u64)
                    }
                    ty::Slice(..) => {
                        assert!(from_end, "slice subslices should use from_end");
                        base_ty
                    }
                    _ => span_mirbug_and_err!(self, place, "slice of non-array {:?}", base_ty),
                })
            }
            ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind {
                ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
                    if index.as_usize() >= adt_def.variants.len() {
                        PlaceTy::from_ty(span_mirbug_and_err!(
                            self,
                            place,
                            "cast to variant #{:?} but enum only has {:?}",
                            index,
                            adt_def.variants.len()
                        ))
                    } else {
                        PlaceTy { ty: base_ty, variant_index: Some(index) }
                    }
                }
                // We do not need to handle generators here, because this runs
                // before the generator transform stage.
                _ => {
                    let ty = if let Some(name) = maybe_name {
                        span_mirbug_and_err!(
                            self,
                            place,
                            "can't downcast {:?} as {:?}",
                            base_ty,
                            name
                        )
                    } else {
                        span_mirbug_and_err!(self, place, "can't downcast {:?}", base_ty)
                    };
                    PlaceTy::from_ty(ty)
                }
            },
            ProjectionElem::Field(field, fty) => {
                let fty = self.sanitize_type(place, fty);
                match self.field_ty(place, base, field, location) {
                    Ok(ty) => {
                        if let Err(terr) = self.cx.eq_types(
                            ty,
                            fty,
                            location.to_locations(),
                            ConstraintCategory::Boring,
                        ) {
                            span_mirbug!(
                                self,
                                place,
                                "bad field access ({:?}: {:?}): {:?}",
                                ty,
                                fty,
                                terr
                            );
                        }
                    }
                    Err(FieldAccessError::OutOfRange { field_count }) => span_mirbug!(
                        self,
                        place,
                        "accessed field #{} but variant only has {}",
                        field.index(),
                        field_count
                    ),
                }
                PlaceTy::from_ty(fty)
            }
        }
    }

    fn error(&mut self) -> Ty<'tcx> {
        self.errors_reported = true;
        self.tcx().types.err
    }

    fn field_ty(
        &mut self,
        parent: &dyn fmt::Debug,
        base_ty: PlaceTy<'tcx>,
        field: Field,
        location: Location,
    ) -> Result<Ty<'tcx>, FieldAccessError> {
        let tcx = self.tcx();

        let (variant, substs) = match base_ty {
            PlaceTy { ty, variant_index: Some(variant_index) } => match ty.kind {
                ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
                ty::Generator(def_id, substs, _) => {
                    let mut variants = substs.as_generator().state_tys(def_id, tcx);
                    let mut variant = match variants.nth(variant_index.into()) {
                        Some(v) => v,
                        None => bug!(
                            "variant_index of generator out of range: {:?}/{:?}",
                            variant_index,
                            substs.as_generator().state_tys(def_id, tcx).count()
                        ),
                    };
                    return match variant.nth(field.index()) {
                        Some(ty) => Ok(ty),
                        None => Err(FieldAccessError::OutOfRange { field_count: variant.count() }),
                    };
                }
                _ => bug!("can't have downcast of non-adt non-generator type"),
            },
            PlaceTy { ty, variant_index: None } => match ty.kind {
                ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
                    (&adt_def.variants[VariantIdx::new(0)], substs)
                }
                ty::Closure(_, substs) => {
                    return match substs.as_closure().upvar_tys().nth(field.index()) {
                        Some(ty) => Ok(ty),
                        None => Err(FieldAccessError::OutOfRange {
                            field_count: substs.as_closure().upvar_tys().count(),
                        }),
                    };
                }
                ty::Generator(_, substs, _) => {
                    // Only prefix fields (upvars and current state) are
                    // accessible without a variant index.
                    return match substs.as_generator().prefix_tys().nth(field.index()) {
                        Some(ty) => Ok(ty),
                        None => Err(FieldAccessError::OutOfRange {
                            field_count: substs.as_generator().prefix_tys().count(),
                        }),
                    };
                }
                ty::Tuple(tys) => {
                    return match tys.get(field.index()) {
                        Some(&ty) => Ok(ty.expect_ty()),
                        None => Err(FieldAccessError::OutOfRange { field_count: tys.len() }),
                    };
                }
                _ => {
                    return Ok(span_mirbug_and_err!(
                        self,
                        parent,
                        "can't project out of {:?}",
                        base_ty
                    ));
                }
            },
        };

        if let Some(field) = variant.fields.get(field.index()) {
            Ok(self.cx.normalize(&field.ty(tcx, substs), location))
        } else {
            Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
        }
    }
}

/// The MIR type checker. Visits the MIR and enforces all the
/// constraints needed for it to be valid and well-typed. Along the
/// way, it accrues region constraints -- these can later be used by
/// NLL region checking.
struct TypeChecker<'a, 'tcx> {
    infcx: &'a InferCtxt<'a, 'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    last_span: Span,
    body: &'a Body<'tcx>,
    /// User type annotations are shared between the main MIR and the MIR of
    /// all of the promoted items.
    user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
    mir_def_id: DefId,
    region_bound_pairs: &'a RegionBoundPairs<'tcx>,
    implicit_region_bound: ty::Region<'tcx>,
    reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
    borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
    universal_region_relations: &'a UniversalRegionRelations<'tcx>,
    opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
}

struct BorrowCheckContext<'a, 'tcx> {
    universal_regions: &'a UniversalRegions<'tcx>,
    location_table: &'a LocationTable,
    all_facts: &'a mut Option<AllFacts>,
    borrow_set: &'a BorrowSet<'tcx>,
    constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
}

crate struct MirTypeckResults<'tcx> {
    crate constraints: MirTypeckRegionConstraints<'tcx>,
    pub(in crate::borrow_check) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
    crate opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
}

/// A collection of region constraints that must be satisfied for the
/// program to be considered well-typed.
crate struct MirTypeckRegionConstraints<'tcx> {
    /// Maps from a `ty::Placeholder` to the corresponding
    /// `PlaceholderIndex` bit that we will use for it.
    ///
    /// To keep everything in sync, do not insert this set
    /// directly. Instead, use the `placeholder_region` helper.
    crate placeholder_indices: PlaceholderIndices,

    /// Each time we add a placeholder to `placeholder_indices`, we
    /// also create a corresponding "representative" region vid for
    /// that wraps it. This vector tracks those. This way, when we
    /// convert the same `ty::RePlaceholder(p)` twice, we can map to
    /// the same underlying `RegionVid`.
    crate placeholder_index_to_region: IndexVec<PlaceholderIndex, ty::Region<'tcx>>,

    /// In general, the type-checker is not responsible for enforcing
    /// liveness constraints; this job falls to the region inferencer,
    /// which performs a liveness analysis. However, in some limited
    /// cases, the MIR type-checker creates temporary regions that do
    /// not otherwise appear in the MIR -- in particular, the
    /// late-bound regions that it instantiates at call-sites -- and
    /// hence it must report on their liveness constraints.
    crate liveness_constraints: LivenessValues<RegionVid>,

    crate outlives_constraints: OutlivesConstraintSet,

    crate member_constraints: MemberConstraintSet<'tcx, RegionVid>,

    crate closure_bounds_mapping:
        FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,

    crate type_tests: Vec<TypeTest<'tcx>>,
}

impl MirTypeckRegionConstraints<'tcx> {
    fn placeholder_region(
        &mut self,
        infcx: &InferCtxt<'_, 'tcx>,
        placeholder: ty::PlaceholderRegion,
    ) -> ty::Region<'tcx> {
        let placeholder_index = self.placeholder_indices.insert(placeholder);
        match self.placeholder_index_to_region.get(placeholder_index) {
            Some(&v) => v,
            None => {
                let origin = NLLRegionVariableOrigin::Placeholder(placeholder);
                let region = infcx.next_nll_region_var_in_universe(origin, placeholder.universe);
                self.placeholder_index_to_region.push(region);
                region
            }
        }
    }
}

/// The `Locations` type summarizes *where* region constraints are
/// required to hold. Normally, this is at a particular point which
/// created the obligation, but for constraints that the user gave, we
/// want the constraint to hold at all points.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Locations {
    /// Indicates that a type constraint should always be true. This
    /// is particularly important in the new borrowck analysis for
    /// things like the type of the return slot. Consider this
    /// example:
    ///
    /// ```
    /// fn foo<'a>(x: &'a u32) -> &'a u32 {
    ///     let y = 22;
    ///     return &y; // error
    /// }
    /// ```
    ///
    /// Here, we wind up with the signature from the return type being
    /// something like `&'1 u32` where `'1` is a universal region. But
    /// the type of the return slot `_0` is something like `&'2 u32`
    /// where `'2` is an existential region variable. The type checker
    /// requires that `&'2 u32 = &'1 u32` -- but at what point? In the
    /// older NLL analysis, we required this only at the entry point
    /// to the function. By the nature of the constraints, this wound
    /// up propagating to all points reachable from start (because
    /// `'1` -- as a universal region -- is live everywhere). In the
    /// newer analysis, though, this doesn't work: `_0` is considered
    /// dead at the start (it has no usable value) and hence this type
    /// equality is basically a no-op. Then, later on, when we do `_0
    /// = &'3 y`, that region `'3` never winds up related to the
    /// universal region `'1` and hence no error occurs. Therefore, we
    /// use Locations::All instead, which ensures that the `'1` and
    /// `'2` are equal everything. We also use this for other
    /// user-given type annotations; e.g., if the user wrote `let mut
    /// x: &'static u32 = ...`, we would ensure that all values
    /// assigned to `x` are of `'static` lifetime.
    ///
    /// The span points to the place the constraint arose. For example,
    /// it points to the type in a user-given type annotation. If
    /// there's no sensible span then it's DUMMY_SP.
    All(Span),

    /// An outlives constraint that only has to hold at a single location,
    /// usually it represents a point where references flow from one spot to
    /// another (e.g., `x = y`)
    Single(Location),
}

impl Locations {
    pub fn from_location(&self) -> Option<Location> {
        match self {
            Locations::All(_) => None,
            Locations::Single(from_location) => Some(*from_location),
        }
    }

    /// Gets a span representing the location.
    pub fn span(&self, body: &Body<'_>) -> Span {
        match self {
            Locations::All(span) => *span,
            Locations::Single(l) => body.source_info(*l).span,
        }
    }
}

impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
    fn new(
        infcx: &'a InferCtxt<'a, 'tcx>,
        body: &'a Body<'tcx>,
        mir_def_id: DefId,
        param_env: ty::ParamEnv<'tcx>,
        region_bound_pairs: &'a RegionBoundPairs<'tcx>,
        implicit_region_bound: ty::Region<'tcx>,
        borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
        universal_region_relations: &'a UniversalRegionRelations<'tcx>,
    ) -> Self {
        let mut checker = Self {
            infcx,
            last_span: DUMMY_SP,
            mir_def_id,
            body,
            user_type_annotations: &body.user_type_annotations,
            param_env,
            region_bound_pairs,
            implicit_region_bound,
            borrowck_context,
            reported_errors: Default::default(),
            universal_region_relations,
            opaque_type_values: FxHashMap::default(),
        };
        checker.check_user_type_annotations();
        checker
    }

    /// Equate the inferred type and the annotated type for user type annotations
    fn check_user_type_annotations(&mut self) {
        debug!(
            "check_user_type_annotations: user_type_annotations={:?}",
            self.user_type_annotations
        );
        for user_annotation in self.user_type_annotations {
            let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
            let (annotation, _) =
                self.infcx.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
            match annotation {
                UserType::Ty(mut ty) => {
                    ty = self.normalize(ty, Locations::All(span));

                    if let Err(terr) = self.eq_types(
                        ty,
                        inferred_ty,
                        Locations::All(span),
                        ConstraintCategory::BoringNoLocation,
                    ) {
                        span_mirbug!(
                            self,
                            user_annotation,
                            "bad user type ({:?} = {:?}): {:?}",
                            ty,
                            inferred_ty,
                            terr
                        );
                    }

                    self.prove_predicate(
                        ty::Predicate::WellFormed(inferred_ty),
                        Locations::All(span),
                        ConstraintCategory::TypeAnnotation,
                    );
                }
                UserType::TypeOf(def_id, user_substs) => {
                    if let Err(terr) = self.fully_perform_op(
                        Locations::All(span),
                        ConstraintCategory::BoringNoLocation,
                        self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
                            inferred_ty,
                            def_id,
                            user_substs,
                        )),
                    ) {
                        span_mirbug!(
                            self,
                            user_annotation,
                            "bad user type AscribeUserType({:?}, {:?} {:?}): {:?}",
                            inferred_ty,
                            def_id,
                            user_substs,
                            terr
                        );
                    }
                }
            }
        }
    }

    /// Given some operation `op` that manipulates types, proves
    /// predicates, or otherwise uses the inference context, executes
    /// `op` and then executes all the further obligations that `op`
    /// returns. This will yield a set of outlives constraints amongst
    /// regions which are extracted and stored as having occurred at
    /// `locations`.
    ///
    /// **Any `rustc_middle::infer` operations that might generate region
    /// constraints should occur within this method so that those
    /// constraints can be properly localized!**
    fn fully_perform_op<R>(
        &mut self,
        locations: Locations,
        category: ConstraintCategory,
        op: impl type_op::TypeOp<'tcx, Output = R>,
    ) -> Fallible<R> {
        let (r, opt_data) = op.fully_perform(self.infcx)?;

        if let Some(data) = &opt_data {
            self.push_region_constraints(locations, category, data);
        }

        Ok(r)
    }

    fn push_region_constraints(
        &mut self,
        locations: Locations,
        category: ConstraintCategory,
        data: &QueryRegionConstraints<'tcx>,
    ) {
        debug!("push_region_constraints: constraints generated at {:?} are {:#?}", locations, data);

        constraint_conversion::ConstraintConversion::new(
            self.infcx,
            self.borrowck_context.universal_regions,
            self.region_bound_pairs,
            Some(self.implicit_region_bound),
            self.param_env,
            locations,
            category,
            &mut self.borrowck_context.constraints,
        )
        .convert_all(data);
    }

    /// Convenient wrapper around `relate_tys::relate_types` -- see
    /// that fn for docs.
    fn relate_types(
        &mut self,
        a: Ty<'tcx>,
        v: ty::Variance,
        b: Ty<'tcx>,
        locations: Locations,
        category: ConstraintCategory,
    ) -> Fallible<()> {
        relate_tys::relate_types(
            self.infcx,
            a,
            v,
            b,
            locations,
            category,
            Some(self.borrowck_context),
        )
    }

    fn sub_types(
        &mut self,
        sub: Ty<'tcx>,
        sup: Ty<'tcx>,
        locations: Locations,
        category: ConstraintCategory,
    ) -> Fallible<()> {
        self.relate_types(sub, ty::Variance::Covariant, sup, locations, category)
    }

    /// Try to relate `sub <: sup`; if this fails, instantiate opaque
    /// variables in `sub` with their inferred definitions and try
    /// again. This is used for opaque types in places (e.g., `let x:
    /// impl Foo = ..`).
    fn sub_types_or_anon(
        &mut self,
        sub: Ty<'tcx>,
        sup: Ty<'tcx>,
        locations: Locations,
        category: ConstraintCategory,
    ) -> Fallible<()> {
        if let Err(terr) = self.sub_types(sub, sup, locations, category) {
            if let ty::Opaque(..) = sup.kind {
                // When you have `let x: impl Foo = ...` in a closure,
                // the resulting inferend values are stored with the
                // def-id of the base function.
                let parent_def_id = self.tcx().closure_base_def_id(self.mir_def_id);
                return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category);
            } else {
                return Err(terr);
            }
        }
        Ok(())
    }

    fn eq_types(
        &mut self,
        a: Ty<'tcx>,
        b: Ty<'tcx>,
        locations: Locations,
        category: ConstraintCategory,
    ) -> Fallible<()> {
        self.relate_types(a, ty::Variance::Invariant, b, locations, category)
    }

    fn relate_type_and_user_type(
        &mut self,
        a: Ty<'tcx>,
        v: ty::Variance,
        user_ty: &UserTypeProjection,
        locations: Locations,
        category: ConstraintCategory,
    ) -> Fallible<()> {
        debug!(
            "relate_type_and_user_type(a={:?}, v={:?}, user_ty={:?}, locations={:?})",
            a, v, user_ty, locations,
        );

        let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
        let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);

        let tcx = self.infcx.tcx;

        for proj in &user_ty.projs {
            let projected_ty = curr_projected_ty.projection_ty_core(
                tcx,
                self.param_env,
                proj,
                |this, field, &()| {
                    let ty = this.field_ty(tcx, field);
                    self.normalize(ty, locations)
                },
            );
            curr_projected_ty = projected_ty;
        }
        debug!(
            "user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
            user_ty.base, annotated_type, user_ty.projs, curr_projected_ty
        );

        let ty = curr_projected_ty.ty;
        self.relate_types(a, v, ty, locations, category)?;

        Ok(())
    }

    fn eq_opaque_type_and_type(
        &mut self,
        revealed_ty: Ty<'tcx>,
        anon_ty: Ty<'tcx>,
        anon_owner_def_id: DefId,
        locations: Locations,
        category: ConstraintCategory,
    ) -> Fallible<()> {
        debug!(
            "eq_opaque_type_and_type( \
             revealed_ty={:?}, \
             anon_ty={:?})",
            revealed_ty, anon_ty
        );

        // Fast path for the common case.
        if !anon_ty.has_opaque_types() {
            if let Err(terr) = self.eq_types(anon_ty, revealed_ty, locations, category) {
                span_mirbug!(
                    self,
                    locations,
                    "eq_opaque_type_and_type: `{:?}=={:?}` failed with `{:?}`",
                    revealed_ty,
                    anon_ty,
                    terr
                );
            }
            return Ok(());
        }

        let infcx = self.infcx;
        let tcx = infcx.tcx;
        let param_env = self.param_env;
        let body = self.body;
        let concrete_opaque_types = &tcx.typeck_tables_of(anon_owner_def_id).concrete_opaque_types;
        let mut opaque_type_values = Vec::new();

        debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id);
        let opaque_type_map = self.fully_perform_op(
            locations,
            category,
            CustomTypeOp::new(
                |infcx| {
                    let mut obligations = ObligationAccumulator::default();

                    let dummy_body_id = ObligationCause::dummy().body_id;
                    let (output_ty, opaque_type_map) =
                        obligations.add(infcx.instantiate_opaque_types(
                            anon_owner_def_id,
                            dummy_body_id,
                            param_env,
                            &anon_ty,
                            locations.span(body),
                        ));
                    debug!(
                        "eq_opaque_type_and_type: \
                         instantiated output_ty={:?} \
                         opaque_type_map={:#?} \
                         revealed_ty={:?}",
                        output_ty, opaque_type_map, revealed_ty
                    );
                    // Make sure that the inferred types are well-formed. I'm
                    // not entirely sure this is needed (the HIR type check
                    // didn't do this) but it seems sensible to prevent opaque
                    // types hiding ill-formed types.
                    obligations.obligations.push(traits::Obligation::new(
                        ObligationCause::dummy(),
                        param_env,
                        ty::Predicate::WellFormed(revealed_ty),
                    ));
                    obligations.add(
                        infcx
                            .at(&ObligationCause::dummy(), param_env)
                            .eq(output_ty, revealed_ty)?,
                    );

                    for (&opaque_def_id, opaque_decl) in &opaque_type_map {
                        let resolved_ty = infcx.resolve_vars_if_possible(&opaque_decl.concrete_ty);
                        let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind {
                            def_id == opaque_def_id
                        } else {
                            false
                        };
                        let opaque_defn_ty = match concrete_opaque_types.get(&opaque_def_id) {
                            None => {
                                if !concrete_is_opaque {
                                    tcx.sess.delay_span_bug(
                                        body.span,
                                        &format!(
                                            "Non-defining use of {:?} with revealed type",
                                            opaque_def_id,
                                        ),
                                    );
                                }
                                continue;
                            }
                            Some(opaque_defn_ty) => opaque_defn_ty,
                        };
                        debug!("opaque_defn_ty = {:?}", opaque_defn_ty);
                        let subst_opaque_defn_ty =
                            opaque_defn_ty.concrete_type.subst(tcx, opaque_decl.substs);
                        let renumbered_opaque_defn_ty =
                            renumber::renumber_regions(infcx, &subst_opaque_defn_ty);

                        debug!(
                            "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
                            opaque_decl.concrete_ty, resolved_ty, renumbered_opaque_defn_ty,
                        );

                        if !concrete_is_opaque {
                            // Equate concrete_ty (an inference variable) with
                            // the renumbered type from typeck.
                            obligations.add(
                                infcx
                                    .at(&ObligationCause::dummy(), param_env)
                                    .eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
                            );
                            opaque_type_values.push((
                                opaque_def_id,
                                ty::ResolvedOpaqueTy {
                                    concrete_type: renumbered_opaque_defn_ty,
                                    substs: opaque_decl.substs,
                                },
                            ));
                        } else {
                            // We're using an opaque `impl Trait` type without
                            // 'revealing' it. For example, code like this:
                            //
                            // type Foo = impl Debug;
                            // fn foo1() -> Foo { ... }
                            // fn foo2() -> Foo { foo1() }
                            //
                            // In `foo2`, we're not revealing the type of `Foo` - we're
                            // just treating it as the opaque type.
                            //
                            // When this occurs, we do *not* want to try to equate
                            // the concrete type with the underlying defining type
                            // of the opaque type - this will always fail, since
                            // the defining type of an opaque type is always
                            // some other type (e.g. not itself)
                            // Essentially, none of the normal obligations apply here -
                            // we're just passing around some unknown opaque type,
                            // without actually looking at the underlying type it
                            // gets 'revealed' into
                            debug!(
                                "eq_opaque_type_and_type: non-defining use of {:?}",
                                opaque_def_id,
                            );
                        }
                    }

                    debug!("eq_opaque_type_and_type: equated");

                    Ok(InferOk {
                        value: Some(opaque_type_map),
                        obligations: obligations.into_vec(),
                    })
                },
                || "input_output".to_string(),
            ),
        )?;

        self.opaque_type_values.extend(opaque_type_values);

        let universal_region_relations = self.universal_region_relations;

        // Finally, if we instantiated the anon types successfully, we
        // have to solve any bounds (e.g., `-> impl Iterator` needs to
        // prove that `T: Iterator` where `T` is the type we
        // instantiated it with).
        if let Some(opaque_type_map) = opaque_type_map {
            for (opaque_def_id, opaque_decl) in opaque_type_map {
                self.fully_perform_op(
                    locations,
                    ConstraintCategory::OpaqueType,
                    CustomTypeOp::new(
                        |_cx| {
                            infcx.constrain_opaque_type(
                                opaque_def_id,
                                &opaque_decl,
                                GenerateMemberConstraints::IfNoStaticBound,
                                universal_region_relations,
                            );
                            Ok(InferOk { value: (), obligations: vec![] })
                        },
                        || "opaque_type_map".to_string(),
                    ),
                )?;
            }
        }
        Ok(())
    }

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

    fn check_stmt(
        &mut self,
        body: ReadOnlyBodyAndCache<'_, 'tcx>,
        stmt: &Statement<'tcx>,
        location: Location,
    ) {
        debug!("check_stmt: {:?}", stmt);
        let tcx = self.tcx();
        match stmt.kind {
            StatementKind::Assign(box (ref place, ref rv)) => {
                // Assignments to temporaries are not "interesting";
                // they are not caused by the user, but rather artifacts
                // of lowering. Assignments to other sorts of places *are* interesting
                // though.
                let category = match place.as_local() {
                    Some(RETURN_PLACE) => {
                        if let BorrowCheckContext {
                            universal_regions:
                                UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
                            ..
                        } = self.borrowck_context
                        {
                            if tcx.is_static(*def_id) {
                                ConstraintCategory::UseAsStatic
                            } else {
                                ConstraintCategory::UseAsConst
                            }
                        } else {
                            ConstraintCategory::Return
                        }
                    }
                    Some(l) if !body.local_decls[l].is_user_variable() => {
                        ConstraintCategory::Boring
                    }
                    _ => ConstraintCategory::Assignment,
                };

                let place_ty = place.ty(*body, tcx).ty;
                let place_ty = self.normalize(place_ty, location);
                let rv_ty = rv.ty(*body, tcx);
                let rv_ty = self.normalize(rv_ty, location);
                if let Err(terr) =
                    self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
                {
                    span_mirbug!(
                        self,
                        stmt,
                        "bad assignment ({:?} = {:?}): {:?}",
                        place_ty,
                        rv_ty,
                        terr
                    );
                }

                if let Some(annotation_index) = self.rvalue_user_ty(rv) {
                    if let Err(terr) = self.relate_type_and_user_type(
                        rv_ty,
                        ty::Variance::Invariant,
                        &UserTypeProjection { base: annotation_index, projs: vec![] },
                        location.to_locations(),
                        ConstraintCategory::Boring,
                    ) {
                        let annotation = &self.user_type_annotations[annotation_index];
                        span_mirbug!(
                            self,
                            stmt,
                            "bad user type on rvalue ({:?} = {:?}): {:?}",
                            annotation,
                            rv_ty,
                            terr
                        );
                    }
                }

                self.check_rvalue(body, rv, location);
                if !self.tcx().features().unsized_locals {
                    let trait_ref = ty::TraitRef {
                        def_id: tcx.lang_items().sized_trait().unwrap(),
                        substs: tcx.mk_substs_trait(place_ty, &[]),
                    };
                    self.prove_trait_ref(
                        trait_ref,
                        location.to_locations(),
                        ConstraintCategory::SizedBound,
                    );
                }
            }
            StatementKind::SetDiscriminant { ref place, variant_index } => {
                let place_type = place.ty(*body, tcx).ty;
                let adt = match place_type.kind {
                    ty::Adt(adt, _) if adt.is_enum() => adt,
                    _ => {
                        span_bug!(
                            stmt.source_info.span,
                            "bad set discriminant ({:?} = {:?}): lhs is not an enum",
                            place,
                            variant_index
                        );
                    }
                };
                if variant_index.as_usize() >= adt.variants.len() {
                    span_bug!(
                        stmt.source_info.span,
                        "bad set discriminant ({:?} = {:?}): value of of range",
                        place,
                        variant_index
                    );
                };
            }
            StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
                let place_ty = place.ty(*body, tcx).ty;
                if let Err(terr) = self.relate_type_and_user_type(
                    place_ty,
                    variance,
                    projection,
                    Locations::All(stmt.source_info.span),
                    ConstraintCategory::TypeAnnotation,
                ) {
                    let annotation = &self.user_type_annotations[projection.base];
                    span_mirbug!(
                        self,
                        stmt,
                        "bad type assert ({:?} <: {:?} with projections {:?}): {:?}",
                        place_ty,
                        annotation,
                        projection.projs,
                        terr
                    );
                }
            }
            StatementKind::FakeRead(..)
            | StatementKind::StorageLive(..)
            | StatementKind::StorageDead(..)
            | StatementKind::LlvmInlineAsm { .. }
            | StatementKind::Retag { .. }
            | StatementKind::Nop => {}
        }
    }

    fn check_terminator(
        &mut self,
        body: &Body<'tcx>,
        term: &Terminator<'tcx>,
        term_location: Location,
    ) {
        debug!("check_terminator: {:?}", term);
        let tcx = self.tcx();
        match term.kind {
            TerminatorKind::Goto { .. }
            | TerminatorKind::Resume
            | TerminatorKind::Abort
            | TerminatorKind::Return
            | TerminatorKind::GeneratorDrop
            | TerminatorKind::Unreachable
            | TerminatorKind::Drop { .. }
            | TerminatorKind::FalseEdges { .. }
            | TerminatorKind::FalseUnwind { .. } => {
                // no checks needed for these
            }

            TerminatorKind::DropAndReplace { ref location, ref value, target: _, unwind: _ } => {
                let place_ty = location.ty(body, tcx).ty;
                let rv_ty = value.ty(body, tcx);

                let locations = term_location.to_locations();
                if let Err(terr) =
                    self.sub_types(rv_ty, place_ty, locations, ConstraintCategory::Assignment)
                {
                    span_mirbug!(
                        self,
                        term,
                        "bad DropAndReplace ({:?} = {:?}): {:?}",
                        place_ty,
                        rv_ty,
                        terr
                    );
                }
            }
            TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
                let discr_ty = discr.ty(body, tcx);
                if let Err(terr) = self.sub_types(
                    discr_ty,
                    switch_ty,
                    term_location.to_locations(),
                    ConstraintCategory::Assignment,
                ) {
                    span_mirbug!(
                        self,
                        term,
                        "bad SwitchInt ({:?} on {:?}): {:?}",
                        switch_ty,
                        discr_ty,
                        terr
                    );
                }
                if !switch_ty.is_integral() && !switch_ty.is_char() && !switch_ty.is_bool() {
                    span_mirbug!(self, term, "bad SwitchInt discr ty {:?}", switch_ty);
                }
                // FIXME: check the values
            }
            TerminatorKind::Call { ref func, ref args, ref destination, from_hir_call, .. } => {
                let func_ty = func.ty(body, tcx);
                debug!("check_terminator: call, func_ty={:?}", func_ty);
                let sig = match func_ty.kind {
                    ty::FnDef(..) | ty::FnPtr(_) => func_ty.fn_sig(tcx),
                    _ => {
                        span_mirbug!(self, term, "call to non-function {:?}", func_ty);
                        return;
                    }
                };
                let (sig, map) = self.infcx.replace_bound_vars_with_fresh_vars(
                    term.source_info.span,
                    LateBoundRegionConversionTime::FnCall,
                    &sig,
                );
                let sig = self.normalize(sig, term_location);
                self.check_call_dest(body, term, &sig, destination, term_location);

                self.prove_predicates(
                    sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
                    term_location.to_locations(),
                    ConstraintCategory::Boring,
                );

                // The ordinary liveness rules will ensure that all
                // regions in the type of the callee are live here. We
                // then further constrain the late-bound regions that
                // were instantiated at the call site to be live as
                // well. The resulting is that all the input (and
                // output) types in the signature must be live, since
                // all the inputs that fed into it were live.
                for &late_bound_region in map.values() {
                    let region_vid =
                        self.borrowck_context.universal_regions.to_region_vid(late_bound_region);
                    self.borrowck_context
                        .constraints
                        .liveness_constraints
                        .add_element(region_vid, term_location);
                }

                self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call);
            }
            TerminatorKind::Assert { ref cond, ref msg, .. } => {
                let cond_ty = cond.ty(body, tcx);
                if cond_ty != tcx.types.bool {
                    span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
                }

                if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
                    if len.ty(body, tcx) != tcx.types.usize {
                        span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
                    }
                    if index.ty(body, tcx) != tcx.types.usize {
                        span_mirbug!(self, index, "bounds-check index non-usize {:?}", index)
                    }
                }
            }
            TerminatorKind::Yield { ref value, .. } => {
                let value_ty = value.ty(body, tcx);
                match body.yield_ty {
                    None => span_mirbug!(self, term, "yield in non-generator"),
                    Some(ty) => {
                        if let Err(terr) = self.sub_types(
                            value_ty,
                            ty,
                            term_location.to_locations(),
                            ConstraintCategory::Yield,
                        ) {
                            span_mirbug!(
                                self,
                                term,
                                "type of yield value is {:?}, but the yield type is {:?}: {:?}",
                                value_ty,
                                ty,
                                terr
                            );
                        }
                    }
                }
            }
        }
    }

    fn check_call_dest(
        &mut self,
        body: &Body<'tcx>,
        term: &Terminator<'tcx>,
        sig: &ty::FnSig<'tcx>,
        destination: &Option<(Place<'tcx>, BasicBlock)>,
        term_location: Location,
    ) {
        let tcx = self.tcx();
        match *destination {
            Some((ref dest, _target_block)) => {
                let dest_ty = dest.ty(body, tcx).ty;
                let dest_ty = self.normalize(dest_ty, term_location);
                let category = match dest.as_local() {
                    Some(RETURN_PLACE) => {
                        if let BorrowCheckContext {
                            universal_regions:
                                UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
                            ..
                        } = self.borrowck_context
                        {
                            if tcx.is_static(*def_id) {
                                ConstraintCategory::UseAsStatic
                            } else {
                                ConstraintCategory::UseAsConst
                            }
                        } else {
                            ConstraintCategory::Return
                        }
                    }
                    Some(l) if !body.local_decls[l].is_user_variable() => {
                        ConstraintCategory::Boring
                    }
                    _ => ConstraintCategory::Assignment,
                };

                let locations = term_location.to_locations();

                if let Err(terr) =
                    self.sub_types_or_anon(sig.output(), dest_ty, locations, category)
                {
                    span_mirbug!(
                        self,
                        term,
                        "call dest mismatch ({:?} <- {:?}): {:?}",
                        dest_ty,
                        sig.output(),
                        terr
                    );
                }

                // When `#![feature(unsized_locals)]` is not enabled,
                // this check is done at `check_local`.
                if self.tcx().features().unsized_locals {
                    let span = term.source_info.span;
                    self.ensure_place_sized(dest_ty, span);
                }
            }
            None => {
                if !sig.output().conservative_is_privately_uninhabited(self.tcx()) {
                    span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
                }
            }
        }
    }

    fn check_call_inputs(
        &mut self,
        body: &Body<'tcx>,
        term: &Terminator<'tcx>,
        sig: &ty::FnSig<'tcx>,
        args: &[Operand<'tcx>],
        term_location: Location,
        from_hir_call: bool,
    ) {
        debug!("check_call_inputs({:?}, {:?})", sig, args);
        if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) {
            span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
        }
        for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() {
            let op_arg_ty = op_arg.ty(body, self.tcx());
            let category = if from_hir_call {
                ConstraintCategory::CallArgument
            } else {
                ConstraintCategory::Boring
            };
            if let Err(terr) =
                self.sub_types(op_arg_ty, fn_arg, term_location.to_locations(), category)
            {
                span_mirbug!(
                    self,
                    term,
                    "bad arg #{:?} ({:?} <- {:?}): {:?}",
                    n,
                    fn_arg,
                    op_arg_ty,
                    terr
                );
            }
        }
    }

    fn check_iscleanup(&mut self, body: &Body<'tcx>, block_data: &BasicBlockData<'tcx>) {
        let is_cleanup = block_data.is_cleanup;
        self.last_span = block_data.terminator().source_info.span;
        match block_data.terminator().kind {
            TerminatorKind::Goto { target } => {
                self.assert_iscleanup(body, block_data, target, is_cleanup)
            }
            TerminatorKind::SwitchInt { ref targets, .. } => {
                for target in targets {
                    self.assert_iscleanup(body, block_data, *target, is_cleanup);
                }
            }
            TerminatorKind::Resume => {
                if !is_cleanup {
                    span_mirbug!(self, block_data, "resume on non-cleanup block!")
                }
            }
            TerminatorKind::Abort => {
                if !is_cleanup {
                    span_mirbug!(self, block_data, "abort on non-cleanup block!")
                }
            }
            TerminatorKind::Return => {
                if is_cleanup {
                    span_mirbug!(self, block_data, "return on cleanup block")
                }
            }
            TerminatorKind::GeneratorDrop { .. } => {
                if is_cleanup {
                    span_mirbug!(self, block_data, "generator_drop in cleanup block")
                }
            }
            TerminatorKind::Yield { resume, drop, .. } => {
                if is_cleanup {
                    span_mirbug!(self, block_data, "yield in cleanup block")
                }
                self.assert_iscleanup(body, block_data, resume, is_cleanup);
                if let Some(drop) = drop {
                    self.assert_iscleanup(body, block_data, drop, is_cleanup);
                }
            }
            TerminatorKind::Unreachable => {}
            TerminatorKind::Drop { target, unwind, .. }
            | TerminatorKind::DropAndReplace { target, unwind, .. }
            | TerminatorKind::Assert { target, cleanup: unwind, .. } => {
                self.assert_iscleanup(body, block_data, target, is_cleanup);
                if let Some(unwind) = unwind {
                    if is_cleanup {
                        span_mirbug!(self, block_data, "unwind on cleanup block")
                    }
                    self.assert_iscleanup(body, block_data, unwind, true);
                }
            }
            TerminatorKind::Call { ref destination, cleanup, .. } => {
                if let &Some((_, target)) = destination {
                    self.assert_iscleanup(body, block_data, target, is_cleanup);
                }
                if let Some(cleanup) = cleanup {
                    if is_cleanup {
                        span_mirbug!(self, block_data, "cleanup on cleanup block")
                    }
                    self.assert_iscleanup(body, block_data, cleanup, true);
                }
            }
            TerminatorKind::FalseEdges { real_target, imaginary_target } => {
                self.assert_iscleanup(body, block_data, real_target, is_cleanup);
                self.assert_iscleanup(body, block_data, imaginary_target, is_cleanup);
            }
            TerminatorKind::FalseUnwind { real_target, unwind } => {
                self.assert_iscleanup(body, block_data, real_target, is_cleanup);
                if let Some(unwind) = unwind {
                    if is_cleanup {
                        span_mirbug!(self, block_data, "cleanup in cleanup block via false unwind");
                    }
                    self.assert_iscleanup(body, block_data, unwind, true);
                }
            }
        }
    }

    fn assert_iscleanup(
        &mut self,
        body: &Body<'tcx>,
        ctxt: &dyn fmt::Debug,
        bb: BasicBlock,
        iscleanuppad: bool,
    ) {
        if body[bb].is_cleanup != iscleanuppad {
            span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad);
        }
    }

    fn check_local(&mut self, body: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
        match body.local_kind(local) {
            LocalKind::ReturnPointer | LocalKind::Arg => {
                // return values of normal functions are required to be
                // sized by typeck, but return values of ADT constructors are
                // not because we don't include a `Self: Sized` bounds on them.
                //
                // Unbound parts of arguments were never required to be Sized
                // - maybe we should make that a warning.
                return;
            }
            LocalKind::Var | LocalKind::Temp => {}
        }

        // When `#![feature(unsized_locals)]` is enabled, only function calls
        // and nullary ops are checked in `check_call_dest`.
        if !self.tcx().features().unsized_locals {
            let span = local_decl.source_info.span;
            let ty = local_decl.ty;
            self.ensure_place_sized(ty, span);
        }
    }

    fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
        let tcx = self.tcx();

        // Erase the regions from `ty` to get a global type.  The
        // `Sized` bound in no way depends on precise regions, so this
        // shouldn't affect `is_sized`.
        let erased_ty = tcx.erase_regions(&ty);
        if !erased_ty.is_sized(tcx.at(span), self.param_env) {
            // in current MIR construction, all non-control-flow rvalue
            // expressions evaluate through `as_temp` or `into` a return
            // slot or local, so to find all unsized rvalues it is enough
            // to check all temps, return slots and locals.
            if self.reported_errors.replace((ty, span)).is_none() {
                let mut diag = struct_span_err!(
                    self.tcx().sess,
                    span,
                    E0161,
                    "cannot move a value of type {0}: the size of {0} \
                     cannot be statically determined",
                    ty
                );

                // While this is located in `nll::typeck` this error is not
                // an NLL error, it's a required check to prevent creation
                // of unsized rvalues in certain cases:
                // * operand of a box expression
                // * callee in a call expression
                diag.emit();
            }
        }
    }

    fn aggregate_field_ty(
        &mut self,
        ak: &AggregateKind<'tcx>,
        field_index: usize,
        location: Location,
    ) -> Result<Ty<'tcx>, FieldAccessError> {
        let tcx = self.tcx();

        match *ak {
            AggregateKind::Adt(def, variant_index, substs, _, active_field_index) => {
                let variant = &def.variants[variant_index];
                let adj_field_index = active_field_index.unwrap_or(field_index);
                if let Some(field) = variant.fields.get(adj_field_index) {
                    Ok(self.normalize(field.ty(tcx, substs), location))
                } else {
                    Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
                }
            }
            AggregateKind::Closure(_, substs) => {
                match substs.as_closure().upvar_tys().nth(field_index) {
                    Some(ty) => Ok(ty),
                    None => Err(FieldAccessError::OutOfRange {
                        field_count: substs.as_closure().upvar_tys().count(),
                    }),
                }
            }
            AggregateKind::Generator(_, substs, _) => {
                // It doesn't make sense to look at a field beyond the prefix;
                // these require a variant index, and are not initialized in
                // aggregate rvalues.
                match substs.as_generator().prefix_tys().nth(field_index) {
                    Some(ty) => Ok(ty),
                    None => Err(FieldAccessError::OutOfRange {
                        field_count: substs.as_generator().prefix_tys().count(),
                    }),
                }
            }
            AggregateKind::Array(ty) => Ok(ty),
            AggregateKind::Tuple => {
                unreachable!("This should have been covered in check_rvalues");
            }
        }
    }

    fn check_rvalue(
        &mut self,
        body: ReadOnlyBodyAndCache<'_, 'tcx>,
        rvalue: &Rvalue<'tcx>,
        location: Location,
    ) {
        let tcx = self.tcx();

        match rvalue {
            Rvalue::Aggregate(ak, ops) => {
                self.check_aggregate_rvalue(&body, rvalue, ak, ops, location)
            }

            Rvalue::Repeat(operand, len) => {
                // If the length cannot be evaluated we must assume that the length can be larger
                // than 1.
                // If the length is larger than 1, the repeat expression will need to copy the
                // element, so we require the `Copy` trait.
                if len.try_eval_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
                    if let Operand::Move(_) = operand {
                        // While this is located in `nll::typeck` this error is not an NLL error, it's
                        // a required check to make sure that repeated elements implement `Copy`.
                        let span = body.source_info(location).span;
                        let ty = operand.ty(*body, tcx);
                        if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
                            // To determine if `const_in_array_repeat_expressions` feature gate should
                            // be mentioned, need to check if the rvalue is promotable.
                            let should_suggest =
                                should_suggest_const_in_array_repeat_expressions_attribute(
                                    tcx,
                                    self.mir_def_id,
                                    body,
                                    operand,
                                );
                            debug!("check_rvalue: should_suggest={:?}", should_suggest);

                            self.infcx.report_selection_error(
                                &traits::Obligation::new(
                                    ObligationCause::new(
                                        span,
                                        self.tcx()
                                            .hir()
                                            .local_def_id_to_hir_id(self.mir_def_id.expect_local()),
                                        traits::ObligationCauseCode::RepeatVec(should_suggest),
                                    ),
                                    self.param_env,
                                    ty::Predicate::Trait(
                                        ty::Binder::bind(ty::TraitPredicate {
                                            trait_ref: ty::TraitRef::new(
                                                self.tcx().lang_items().copy_trait().unwrap(),
                                                tcx.mk_substs_trait(ty, &[]),
                                            ),
                                        }),
                                        hir::Constness::NotConst,
                                    ),
                                ),
                                &traits::SelectionError::Unimplemented,
                                false,
                                false,
                            );
                        }
                    }
                }
            }

            Rvalue::NullaryOp(_, ty) => {
                // Even with unsized locals cannot box an unsized value.
                if self.tcx().features().unsized_locals {
                    let span = body.source_info(location).span;
                    self.ensure_place_sized(ty, span);
                }

                let trait_ref = ty::TraitRef {
                    def_id: tcx.lang_items().sized_trait().unwrap(),
                    substs: tcx.mk_substs_trait(ty, &[]),
                };

                self.prove_trait_ref(
                    trait_ref,
                    location.to_locations(),
                    ConstraintCategory::SizedBound,
                );
            }

            Rvalue::Cast(cast_kind, op, ty) => {
                match cast_kind {
                    CastKind::Pointer(PointerCast::ReifyFnPointer) => {
                        let fn_sig = op.ty(*body, tcx).fn_sig(tcx);

                        // The type that we see in the fcx is like
                        // `foo::<'a, 'b>`, where `foo` is the path to a
                        // function definition. When we extract the
                        // signature, it comes from the `fn_sig` query,
                        // and hence may contain unnormalized results.
                        let fn_sig = self.normalize(fn_sig, location);

                        let ty_fn_ptr_from = tcx.mk_fn_ptr(fn_sig);

                        if let Err(terr) = self.eq_types(
                            ty_fn_ptr_from,
                            ty,
                            location.to_locations(),
                            ConstraintCategory::Cast,
                        ) {
                            span_mirbug!(
                                self,
                                rvalue,
                                "equating {:?} with {:?} yields {:?}",
                                ty_fn_ptr_from,
                                ty,
                                terr
                            );
                        }
                    }

                    CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
                        let sig = match op.ty(*body, tcx).kind {
                            ty::Closure(_, substs) => substs.as_closure().sig(),
                            _ => bug!(),
                        };
                        let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety);

                        if let Err(terr) = self.eq_types(
                            ty_fn_ptr_from,
                            ty,
                            location.to_locations(),
                            ConstraintCategory::Cast,
                        ) {
                            span_mirbug!(
                                self,
                                rvalue,
                                "equating {:?} with {:?} yields {:?}",
                                ty_fn_ptr_from,
                                ty,
                                terr
                            );
                        }
                    }

                    CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
                        let fn_sig = op.ty(*body, tcx).fn_sig(tcx);

                        // The type that we see in the fcx is like
                        // `foo::<'a, 'b>`, where `foo` is the path to a
                        // function definition. When we extract the
                        // signature, it comes from the `fn_sig` query,
                        // and hence may contain unnormalized results.
                        let fn_sig = self.normalize(fn_sig, location);

                        let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);

                        if let Err(terr) = self.eq_types(
                            ty_fn_ptr_from,
                            ty,
                            location.to_locations(),
                            ConstraintCategory::Cast,
                        ) {
                            span_mirbug!(
                                self,
                                rvalue,
                                "equating {:?} with {:?} yields {:?}",
                                ty_fn_ptr_from,
                                ty,
                                terr
                            );
                        }
                    }

                    CastKind::Pointer(PointerCast::Unsize) => {
                        let &ty = ty;
                        let trait_ref = ty::TraitRef {
                            def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
                            substs: tcx.mk_substs_trait(op.ty(*body, tcx), &[ty.into()]),
                        };

                        self.prove_trait_ref(
                            trait_ref,
                            location.to_locations(),
                            ConstraintCategory::Cast,
                        );
                    }

                    CastKind::Pointer(PointerCast::MutToConstPointer) => {
                        let ty_from = match op.ty(*body, tcx).kind {
                            ty::RawPtr(ty::TypeAndMut {
                                ty: ty_from,
                                mutbl: hir::Mutability::Mut,
                            }) => ty_from,
                            _ => {
                                span_mirbug!(
                                    self,
                                    rvalue,
                                    "unexpected base type for cast {:?}",
                                    ty,
                                );
                                return;
                            }
                        };
                        let ty_to = match ty.kind {
                            ty::RawPtr(ty::TypeAndMut {
                                ty: ty_to,
                                mutbl: hir::Mutability::Not,
                            }) => ty_to,
                            _ => {
                                span_mirbug!(
                                    self,
                                    rvalue,
                                    "unexpected target type for cast {:?}",
                                    ty,
                                );
                                return;
                            }
                        };
                        if let Err(terr) = self.sub_types(
                            ty_from,
                            ty_to,
                            location.to_locations(),
                            ConstraintCategory::Cast,
                        ) {
                            span_mirbug!(
                                self,
                                rvalue,
                                "relating {:?} with {:?} yields {:?}",
                                ty_from,
                                ty_to,
                                terr
                            );
                        }
                    }

                    CastKind::Pointer(PointerCast::ArrayToPointer) => {
                        let ty_from = op.ty(*body, tcx);

                        let opt_ty_elem = match ty_from.kind {
                            ty::RawPtr(ty::TypeAndMut {
                                mutbl: hir::Mutability::Not,
                                ty: array_ty,
                            }) => match array_ty.kind {
                                ty::Array(ty_elem, _) => Some(ty_elem),
                                _ => None,
                            },
                            _ => None,
                        };

                        let ty_elem = match opt_ty_elem {
                            Some(ty_elem) => ty_elem,
                            None => {
                                span_mirbug!(
                                    self,
                                    rvalue,
                                    "ArrayToPointer cast from unexpected type {:?}",
                                    ty_from,
                                );
                                return;
                            }
                        };

                        let ty_to = match ty.kind {
                            ty::RawPtr(ty::TypeAndMut {
                                mutbl: hir::Mutability::Not,
                                ty: ty_to,
                            }) => ty_to,
                            _ => {
                                span_mirbug!(
                                    self,
                                    rvalue,
                                    "ArrayToPointer cast to unexpected type {:?}",
                                    ty,
                                );
                                return;
                            }
                        };

                        if let Err(terr) = self.sub_types(
                            ty_elem,
                            ty_to,
                            location.to_locations(),
                            ConstraintCategory::Cast,
                        ) {
                            span_mirbug!(
                                self,
                                rvalue,
                                "relating {:?} with {:?} yields {:?}",
                                ty_elem,
                                ty_to,
                                terr
                            )
                        }
                    }

                    CastKind::Misc => {
                        let ty_from = op.ty(*body, tcx);
                        let cast_ty_from = CastTy::from_ty(ty_from);
                        let cast_ty_to = CastTy::from_ty(ty);
                        match (cast_ty_from, cast_ty_to) {
                            (None, _)
                            | (_, None)
                            | (_, Some(CastTy::FnPtr))
                            | (Some(CastTy::Float), Some(CastTy::Ptr(_)))
                            | (Some(CastTy::Ptr(_)), Some(CastTy::Float))
                            | (Some(CastTy::FnPtr), Some(CastTy::Float)) => {
                                span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty,)
                            }
                            (Some(CastTy::Int(_)), Some(CastTy::Int(_)))
                            | (Some(CastTy::Float), Some(CastTy::Int(_)))
                            | (Some(CastTy::Int(_)), Some(CastTy::Float))
                            | (Some(CastTy::Float), Some(CastTy::Float))
                            | (Some(CastTy::Ptr(_)), Some(CastTy::Int(_)))
                            | (Some(CastTy::FnPtr), Some(CastTy::Int(_)))
                            | (Some(CastTy::Int(_)), Some(CastTy::Ptr(_)))
                            | (Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_)))
                            | (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
                        }
                    }
                }
            }

            Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
                self.add_reborrow_constraint(&body, location, region, borrowed_place);
            }

            Rvalue::BinaryOp(BinOp::Eq, left, right)
            | Rvalue::BinaryOp(BinOp::Ne, left, right)
            | Rvalue::BinaryOp(BinOp::Lt, left, right)
            | Rvalue::BinaryOp(BinOp::Le, left, right)
            | Rvalue::BinaryOp(BinOp::Gt, left, right)
            | Rvalue::BinaryOp(BinOp::Ge, left, right) => {
                let ty_left = left.ty(*body, tcx);
                if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.kind {
                    let ty_right = right.ty(*body, tcx);
                    let common_ty = self.infcx.next_ty_var(TypeVariableOrigin {
                        kind: TypeVariableOriginKind::MiscVariable,
                        span: body.source_info(location).span,
                    });
                    self.sub_types(
                        common_ty,
                        ty_left,
                        location.to_locations(),
                        ConstraintCategory::Boring,
                    )
                    .unwrap_or_else(|err| {
                        bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
                    });
                    if let Err(terr) = self.sub_types(
                        common_ty,
                        ty_right,
                        location.to_locations(),
                        ConstraintCategory::Boring,
                    ) {
                        span_mirbug!(
                            self,
                            rvalue,
                            "unexpected comparison types {:?} and {:?} yields {:?}",
                            ty_left,
                            ty_right,
                            terr
                        )
                    }
                }
            }

            Rvalue::AddressOf(..)
            | Rvalue::Use(..)
            | Rvalue::Len(..)
            | Rvalue::BinaryOp(..)
            | Rvalue::CheckedBinaryOp(..)
            | Rvalue::UnaryOp(..)
            | Rvalue::Discriminant(..) => {}
        }
    }

    /// If this rvalue supports a user-given type annotation, then
    /// extract and return it. This represents the final type of the
    /// rvalue and will be unified with the inferred type.
    fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotationIndex> {
        match rvalue {
            Rvalue::Use(_)
            | Rvalue::Repeat(..)
            | Rvalue::Ref(..)
            | Rvalue::AddressOf(..)
            | Rvalue::Len(..)
            | Rvalue::Cast(..)
            | Rvalue::BinaryOp(..)
            | Rvalue::CheckedBinaryOp(..)
            | Rvalue::NullaryOp(..)
            | Rvalue::UnaryOp(..)
            | Rvalue::Discriminant(..) => None,

            Rvalue::Aggregate(aggregate, _) => match **aggregate {
                AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
                AggregateKind::Array(_) => None,
                AggregateKind::Tuple => None,
                AggregateKind::Closure(_, _) => None,
                AggregateKind::Generator(_, _, _) => None,
            },
        }
    }

    fn check_aggregate_rvalue(
        &mut self,
        body: &Body<'tcx>,
        rvalue: &Rvalue<'tcx>,
        aggregate_kind: &AggregateKind<'tcx>,
        operands: &[Operand<'tcx>],
        location: Location,
    ) {
        let tcx = self.tcx();

        self.prove_aggregate_predicates(aggregate_kind, location);

        if *aggregate_kind == AggregateKind::Tuple {
            // tuple rvalue field type is always the type of the op. Nothing to check here.
            return;
        }

        for (i, operand) in operands.iter().enumerate() {
            let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
                Ok(field_ty) => field_ty,
                Err(FieldAccessError::OutOfRange { field_count }) => {
                    span_mirbug!(
                        self,
                        rvalue,
                        "accessed field #{} but variant only has {}",
                        i,
                        field_count
                    );
                    continue;
                }
            };
            let operand_ty = operand.ty(body, tcx);

            if let Err(terr) = self.sub_types(
                operand_ty,
                field_ty,
                location.to_locations(),
                ConstraintCategory::Boring,
            ) {
                span_mirbug!(
                    self,
                    rvalue,
                    "{:?} is not a subtype of {:?}: {:?}",
                    operand_ty,
                    field_ty,
                    terr
                );
            }
        }
    }

    /// Adds the constraints that arise from a borrow expression `&'a P` at the location `L`.
    ///
    /// # Parameters
    ///
    /// - `location`: the location `L` where the borrow expression occurs
    /// - `borrow_region`: the region `'a` associated with the borrow
    /// - `borrowed_place`: the place `P` being borrowed
    fn add_reborrow_constraint(
        &mut self,
        body: &Body<'tcx>,
        location: Location,
        borrow_region: ty::Region<'tcx>,
        borrowed_place: &Place<'tcx>,
    ) {
        // These constraints are only meaningful during borrowck:
        let BorrowCheckContext { borrow_set, location_table, all_facts, constraints, .. } =
            self.borrowck_context;

        // In Polonius mode, we also push a `borrow_region` fact
        // linking the loan to the region (in some cases, though,
        // there is no loan associated with this borrow expression --
        // that occurs when we are borrowing an unsafe place, for
        // example).
        if let Some(all_facts) = all_facts {
            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
            if let Some(borrow_index) = borrow_set.location_map.get(&location) {
                let region_vid = borrow_region.to_region_vid();
                all_facts.borrow_region.push((
                    region_vid,
                    *borrow_index,
                    location_table.mid_index(location),
                ));
            }
        }

        // If we are reborrowing the referent of another reference, we
        // need to add outlives relationships. In a case like `&mut
        // *p`, where the `p` has type `&'b mut Foo`, for example, we
        // need to ensure that `'b: 'a`.

        debug!(
            "add_reborrow_constraint({:?}, {:?}, {:?})",
            location, borrow_region, borrowed_place
        );

        let mut cursor = borrowed_place.projection.as_ref();
        while let [proj_base @ .., elem] = cursor {
            cursor = proj_base;

            debug!("add_reborrow_constraint - iteration {:?}", elem);

            match elem {
                ProjectionElem::Deref => {
                    let tcx = self.infcx.tcx;
                    let base_ty = Place::ty_from(borrowed_place.local, proj_base, body, tcx).ty;

                    debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
                    match base_ty.kind {
                        ty::Ref(ref_region, _, mutbl) => {
                            constraints.outlives_constraints.push(OutlivesConstraint {
                                sup: ref_region.to_region_vid(),
                                sub: borrow_region.to_region_vid(),
                                locations: location.to_locations(),
                                category: ConstraintCategory::Boring,
                            });

                            match mutbl {
                                hir::Mutability::Not => {
                                    // Immutable reference. We don't need the base
                                    // to be valid for the entire lifetime of
                                    // the borrow.
                                    break;
                                }
                                hir::Mutability::Mut => {
                                    // Mutable reference. We *do* need the base
                                    // to be valid, because after the base becomes
                                    // invalid, someone else can use our mutable deref.

                                    // This is in order to make the following function
                                    // illegal:
                                    // ```
                                    // fn unsafe_deref<'a, 'b>(x: &'a &'b mut T) -> &'b mut T {
                                    //     &mut *x
                                    // }
                                    // ```
                                    //
                                    // As otherwise you could clone `&mut T` using the
                                    // following function:
                                    // ```
                                    // fn bad(x: &mut T) -> (&mut T, &mut T) {
                                    //     let my_clone = unsafe_deref(&'a x);
                                    //     ENDREGION 'a;
                                    //     (my_clone, x)
                                    // }
                                    // ```
                                }
                            }
                        }
                        ty::RawPtr(..) => {
                            // deref of raw pointer, guaranteed to be valid
                            break;
                        }
                        ty::Adt(def, _) if def.is_box() => {
                            // deref of `Box`, need the base to be valid - propagate
                        }
                        _ => bug!("unexpected deref ty {:?} in {:?}", base_ty, borrowed_place),
                    }
                }
                ProjectionElem::Field(..)
                | ProjectionElem::Downcast(..)
                | ProjectionElem::Index(..)
                | ProjectionElem::ConstantIndex { .. }
                | ProjectionElem::Subslice { .. } => {
                    // other field access
                }
            }
        }
    }

    fn prove_aggregate_predicates(
        &mut self,
        aggregate_kind: &AggregateKind<'tcx>,
        location: Location,
    ) {
        let tcx = self.tcx();

        debug!(
            "prove_aggregate_predicates(aggregate_kind={:?}, location={:?})",
            aggregate_kind, location
        );

        let instantiated_predicates = match aggregate_kind {
            AggregateKind::Adt(def, _, substs, _, _) => {
                tcx.predicates_of(def.did).instantiate(tcx, substs)
            }

            // For closures, we have some **extra requirements** we
            //
            // have to check. In particular, in their upvars and
            // signatures, closures often reference various regions
            // from the surrounding function -- we call those the
            // closure's free regions. When we borrow-check (and hence
            // region-check) closures, we may find that the closure
            // requires certain relationships between those free
            // regions. However, because those free regions refer to
            // portions of the CFG of their caller, the closure is not
            // in a position to verify those relationships. In that
            // case, the requirements get "propagated" to us, and so
            // we have to solve them here where we instantiate the
            // closure.
            //
            // Despite the opacity of the previous parapgrah, this is
            // actually relatively easy to understand in terms of the
            // desugaring. A closure gets desugared to a struct, and
            // these extra requirements are basically like where
            // clauses on the struct.
            AggregateKind::Closure(def_id, substs)
            | AggregateKind::Generator(def_id, substs, _) => {
                self.prove_closure_bounds(tcx, *def_id, substs, location)
            }

            AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
        };

        self.normalize_and_prove_instantiated_predicates(
            instantiated_predicates,
            location.to_locations(),
        );
    }

    fn prove_closure_bounds(
        &mut self,
        tcx: TyCtxt<'tcx>,
        def_id: DefId,
        substs: SubstsRef<'tcx>,
        location: Location,
    ) -> ty::InstantiatedPredicates<'tcx> {
        if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements
        {
            let closure_constraints = QueryRegionConstraints {
                outlives: closure_region_requirements.apply_requirements(tcx, def_id, substs),

                // Presently, closures never propagate member
                // constraints to their parents -- they are enforced
                // locally.  This is largely a non-issue as member
                // constraints only come from `-> impl Trait` and
                // friends which don't appear (thus far...) in
                // closures.
                member_constraints: vec![],
            };

            let bounds_mapping = closure_constraints
                .outlives
                .iter()
                .enumerate()
                .filter_map(|(idx, constraint)| {
                    let ty::OutlivesPredicate(k1, r2) =
                        constraint.no_bound_vars().unwrap_or_else(|| {
                            bug!("query_constraint {:?} contained bound vars", constraint,);
                        });

                    match k1.unpack() {
                        GenericArgKind::Lifetime(r1) => {
                            // constraint is r1: r2
                            let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1);
                            let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2);
                            let outlives_requirements =
                                &closure_region_requirements.outlives_requirements[idx];
                            Some((
                                (r1_vid, r2_vid),
                                (outlives_requirements.category, outlives_requirements.blame_span),
                            ))
                        }
                        GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
                    }
                })
                .collect();

            let existing = self
                .borrowck_context
                .constraints
                .closure_bounds_mapping
                .insert(location, bounds_mapping);
            assert!(existing.is_none(), "Multiple closures at the same location.");

            self.push_region_constraints(
                location.to_locations(),
                ConstraintCategory::ClosureBounds,
                &closure_constraints,
            );
        }

        tcx.predicates_of(def_id).instantiate(tcx, substs)
    }

    fn prove_trait_ref(
        &mut self,
        trait_ref: ty::TraitRef<'tcx>,
        locations: Locations,
        category: ConstraintCategory,
    ) {
        self.prove_predicates(
            Some(ty::Predicate::Trait(
                trait_ref.to_poly_trait_ref().to_poly_trait_predicate(),
                hir::Constness::NotConst,
            )),
            locations,
            category,
        );
    }

    fn normalize_and_prove_instantiated_predicates(
        &mut self,
        instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
        locations: Locations,
    ) {
        for predicate in instantiated_predicates.predicates {
            let predicate = self.normalize(predicate, locations);
            self.prove_predicate(predicate, locations, ConstraintCategory::Boring);
        }
    }

    fn prove_predicates(
        &mut self,
        predicates: impl IntoIterator<Item = ty::Predicate<'tcx>>,
        locations: Locations,
        category: ConstraintCategory,
    ) {
        for predicate in predicates {
            debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);

            self.prove_predicate(predicate, locations, category);
        }
    }

    fn prove_predicate(
        &mut self,
        predicate: ty::Predicate<'tcx>,
        locations: Locations,
        category: ConstraintCategory,
    ) {
        debug!("prove_predicate(predicate={:?}, location={:?})", predicate, locations,);

        let param_env = self.param_env;
        self.fully_perform_op(
            locations,
            category,
            param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)),
        )
        .unwrap_or_else(|NoSolution| {
            span_mirbug!(self, NoSolution, "could not prove {:?}", predicate);
        })
    }

    fn typeck_mir(&mut self, body: ReadOnlyBodyAndCache<'_, 'tcx>) {
        self.last_span = body.span;
        debug!("run_on_mir: {:?}", body.span);

        for (local, local_decl) in body.local_decls.iter_enumerated() {
            self.check_local(&body, local, local_decl);
        }

        for (block, block_data) in body.basic_blocks().iter_enumerated() {
            let mut location = Location { block, statement_index: 0 };
            for stmt in &block_data.statements {
                if !stmt.source_info.span.is_dummy() {
                    self.last_span = stmt.source_info.span;
                }
                self.check_stmt(body, stmt, location);
                location.statement_index += 1;
            }

            self.check_terminator(&body, block_data.terminator(), location);
            self.check_iscleanup(&body, block_data);
        }
    }

    fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
    where
        T: type_op::normalize::Normalizable<'tcx> + Copy + 'tcx,
    {
        debug!("normalize(value={:?}, location={:?})", value, location);
        let param_env = self.param_env;
        self.fully_perform_op(
            location.to_locations(),
            ConstraintCategory::Boring,
            param_env.and(type_op::normalize::Normalize::new(value)),
        )
        .unwrap_or_else(|NoSolution| {
            span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value);
            value
        })
    }
}

trait NormalizeLocation: fmt::Debug + Copy {
    fn to_locations(self) -> Locations;
}

impl NormalizeLocation for Locations {
    fn to_locations(self) -> Locations {
        self
    }
}

impl NormalizeLocation for Location {
    fn to_locations(self) -> Locations {
        Locations::Single(self)
    }
}

#[derive(Debug, Default)]
struct ObligationAccumulator<'tcx> {
    obligations: PredicateObligations<'tcx>,
}

impl<'tcx> ObligationAccumulator<'tcx> {
    fn add<T>(&mut self, value: InferOk<'tcx, T>) -> T {
        let InferOk { value, obligations } = value;
        self.obligations.extend(obligations);
        value
    }

    fn into_vec(self) -> PredicateObligations<'tcx> {
        self.obligations
    }
}
