//! This module contains `TyKind` and its major components.

#![allow(rustc::usage_of_ty_tykind)]

use self::InferTy::*;
use self::TyKind::*;

use crate::infer::canonical::Canonical;
use crate::mir::interpret::ConstValue;
use crate::mir::interpret::{LitToConstInput, Scalar};
use crate::mir::Promoted;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::{
    self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
};
use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS};
use polonius_engine::Atom;
use rustc_ast::ast;
use rustc_data_structures::captures::Captures;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_index::vec::Idx;
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_target::abi::{Size, VariantIdx};
use rustc_target::spec::abi;
use std::borrow::Cow;
use std::cmp::Ordering;
use std::marker::PhantomData;
use std::ops::Range;
use ty::util::IntTypeExt;

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable, Lift)]
pub struct TypeAndMut<'tcx> {
    pub ty: Ty<'tcx>,
    pub mutbl: hir::Mutability,
}

#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
#[derive(HashStable)]
/// A "free" region `fr` can be interpreted as "some region
/// at least as big as the scope `fr.scope`".
pub struct FreeRegion {
    pub scope: DefId,
    pub bound_region: BoundRegion,
}

#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
#[derive(HashStable)]
pub enum BoundRegion {
    /// An anonymous region parameter for a given fn (&T)
    BrAnon(u32),

    /// Named region parameters for functions (a in &'a T)
    ///
    /// The `DefId` is needed to distinguish free regions in
    /// the event of shadowing.
    BrNamed(DefId, Symbol),

    /// Anonymous region for the implicit env pointer parameter
    /// to a closure
    BrEnv,
}

impl BoundRegion {
    pub fn is_named(&self) -> bool {
        match *self {
            BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime,
            _ => false,
        }
    }

    /// When canonicalizing, we replace unbound inference variables and free
    /// regions with anonymous late bound regions. This method asserts that
    /// we have an anonymous late bound region, which hence may refer to
    /// a canonical variable.
    pub fn assert_bound_var(&self) -> BoundVar {
        match *self {
            BoundRegion::BrAnon(var) => BoundVar::from_u32(var),
            _ => bug!("bound region is not anonymous"),
        }
    }
}

/// N.B., if you change this, you'll probably want to change the corresponding
/// AST structure in `librustc_ast/ast.rs` as well.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
#[derive(HashStable)]
#[rustc_diagnostic_item = "TyKind"]
pub enum TyKind<'tcx> {
    /// The primitive boolean type. Written as `bool`.
    Bool,

    /// The primitive character type; holds a Unicode scalar value
    /// (a non-surrogate code point). Written as `char`.
    Char,

    /// A primitive signed integer type. For example, `i32`.
    Int(ast::IntTy),

    /// A primitive unsigned integer type. For example, `u32`.
    Uint(ast::UintTy),

    /// A primitive floating-point type. For example, `f64`.
    Float(ast::FloatTy),

    /// Structures, enumerations and unions.
    ///
    /// InternalSubsts here, possibly against intuition, *may* contain `Param`s.
    /// That is, even after substitution it is possible that there are type
    /// variables. This happens when the `Adt` corresponds to an ADT
    /// definition and not a concrete use of it.
    Adt(&'tcx AdtDef, SubstsRef<'tcx>),

    /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
    Foreign(DefId),

    /// The pointee of a string slice. Written as `str`.
    Str,

    /// An array with the given length. Written as `[T; n]`.
    Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),

    /// The pointee of an array slice. Written as `[T]`.
    Slice(Ty<'tcx>),

    /// A raw pointer. Written as `*mut T` or `*const T`
    RawPtr(TypeAndMut<'tcx>),

    /// A reference; a pointer with an associated lifetime. Written as
    /// `&'a mut T` or `&'a T`.
    Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability),

    /// The anonymous type of a function declaration/definition. Each
    /// function has a unique type, which is output (for a function
    /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
    ///
    /// For example the type of `bar` here:
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
    /// let bar = foo; // bar: fn() -> i32 {foo}
    /// ```
    FnDef(DefId, SubstsRef<'tcx>),

    /// A pointer to a function. Written as `fn() -> i32`.
    ///
    /// For example the type of `bar` here:
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
    /// let bar: fn() -> i32 = foo;
    /// ```
    FnPtr(PolyFnSig<'tcx>),

    /// A trait, defined with `trait`.
    Dynamic(Binder<&'tcx List<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),

    /// The anonymous type of a closure. Used to represent the type of
    /// `|a| a`.
    Closure(DefId, SubstsRef<'tcx>),

    /// The anonymous type of a generator. Used to represent the type of
    /// `|a| yield a`.
    Generator(DefId, SubstsRef<'tcx>, hir::Movability),

    /// A type representin the types stored inside a generator.
    /// This should only appear in GeneratorInteriors.
    GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>),

    /// The never type `!`
    Never,

    /// A tuple type. For example, `(i32, bool)`.
    /// Use `TyS::tuple_fields` to iterate over the field types.
    Tuple(SubstsRef<'tcx>),

    /// The projection of an associated type. For example,
    /// `<T as Trait<..>>::N`.
    Projection(ProjectionTy<'tcx>),

    /// Opaque (`impl Trait`) type found in a return type.
    /// The `DefId` comes either from
    /// * the `impl Trait` ast::Ty node,
    /// * or the `type Foo = impl Trait` declaration
    /// The substitutions are for the generics of the function in question.
    /// After typeck, the concrete type can be found in the `types` map.
    Opaque(DefId, SubstsRef<'tcx>),

    /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
    Param(ParamTy),

    /// Bound type variable, used only when preparing a trait query.
    Bound(ty::DebruijnIndex, BoundTy),

    /// A placeholder type - universally quantified higher-ranked type.
    Placeholder(ty::PlaceholderType),

    /// A type variable used during type checking.
    Infer(InferTy),

    /// A placeholder for a type which could not be computed; this is
    /// propagated to avoid useless error messages.
    Error(DelaySpanBugEmitted),
}

/// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
/// except through `tcx.err*()`.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
#[derive(RustcEncodable, RustcDecodable, HashStable)]
pub struct DelaySpanBugEmitted(pub(super) ());

// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(TyKind<'_>, 24);

/// A closure can be modeled as a struct that looks like:
///
///     struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U);
///
/// where:
///
/// - 'l0...'li and T0...Tj are the generic parameters
///   in scope on the function that defined the closure,
/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
///   is rather hackily encoded via a scalar type. See
///   `TyS::to_opt_closure_kind` for details.
/// - CS represents the *closure signature*, representing as a `fn()`
///   type. For example, `fn(u32, u32) -> u32` would mean that the closure
///   implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
///   specified above.
/// - U is a type parameter representing the types of its upvars, tupled up
///   (borrowed, if appropriate; that is, if an U field represents a by-ref upvar,
///    and the up-var has the type `Foo`, then that field of U will be `&Foo`).
///
/// So, for example, given this function:
///
///     fn foo<'a, T>(data: &'a mut T) {
///          do(|| data.count += 1)
///     }
///
/// the type of the closure would be something like:
///
///     struct Closure<'a, T, U>(...U);
///
/// Note that the type of the upvar is not specified in the struct.
/// You may wonder how the impl would then be able to use the upvar,
/// if it doesn't know it's type? The answer is that the impl is
/// (conceptually) not fully generic over Closure but rather tied to
/// instances with the expected upvar types:
///
///     impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> {
///         ...
///     }
///
/// You can see that the *impl* fully specified the type of the upvar
/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
/// (Here, I am assuming that `data` is mut-borrowed.)
///
/// Now, the last question you may ask is: Why include the upvar types
/// in an extra type parameter? The reason for this design is that the
/// upvar types can reference lifetimes that are internal to the
/// creating function. In my example above, for example, the lifetime
/// `'b` represents the scope of the closure itself; this is some
/// subset of `foo`, probably just the scope of the call to the to
/// `do()`. If we just had the lifetime/type parameters from the
/// enclosing function, we couldn't name this lifetime `'b`. Note that
/// there can also be lifetimes in the types of the upvars themselves,
/// if one of them happens to be a reference to something that the
/// creating fn owns.
///
/// OK, you say, so why not create a more minimal set of parameters
/// that just includes the extra lifetime parameters? The answer is
/// primarily that it would be hard --- we don't know at the time when
/// we create the closure type what the full types of the upvars are,
/// nor do we know which are borrowed and which are not. In this
/// design, we can just supply a fresh type parameter and figure that
/// out later.
///
/// All right, you say, but why include the type parameters from the
/// original function then? The answer is that codegen may need them
/// when monomorphizing, and they may not appear in the upvars. A
/// closure could capture no variables but still make use of some
/// in-scope type parameter with a bound (e.g., if our example above
/// had an extra `U: Default`, and the closure called `U::default()`).
///
/// There is another reason. This design (implicitly) prohibits
/// closures from capturing themselves (except via a trait
/// object). This simplifies closure inference considerably, since it
/// means that when we infer the kind of a closure or its upvars, we
/// don't have to handle cycles where the decisions we make for
/// closure C wind up influencing the decisions we ought to make for
/// closure C (which would then require fixed point iteration to
/// handle). Plus it fixes an ICE. :P
///
/// ## Generators
///
/// Generators are handled similarly in `GeneratorSubsts`.  The set of
/// type parameters is similar, but `CK` and `CS` are replaced by the
/// following type parameters:
///
/// * `GS`: The generator's "resume type", which is the type of the
///   argument passed to `resume`, and the type of `yield` expressions
///   inside the generator.
/// * `GY`: The "yield type", which is the type of values passed to
///   `yield` inside the generator.
/// * `GR`: The "return type", which is the type of value returned upon
///   completion of the generator.
/// * `GW`: The "generator witness".
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct ClosureSubsts<'tcx> {
    /// Lifetime and type parameters from the enclosing function,
    /// concatenated with a tuple containing the types of the upvars.
    ///
    /// These are separated out because codegen wants to pass them around
    /// when monomorphizing.
    pub substs: SubstsRef<'tcx>,
}

/// Struct returned by `split()`. Note that these are subslices of the
/// parent slice and not canonical substs themselves.
struct SplitClosureSubsts<'tcx> {
    closure_kind_ty: GenericArg<'tcx>,
    closure_sig_as_fn_ptr_ty: GenericArg<'tcx>,
    tupled_upvars_ty: GenericArg<'tcx>,
}

impl<'tcx> ClosureSubsts<'tcx> {
    /// Divides the closure substs into their respective
    /// components. Single source of truth with respect to the
    /// ordering.
    fn split(self) -> SplitClosureSubsts<'tcx> {
        match self.substs[..] {
            [.., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
                SplitClosureSubsts { closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty }
            }
            _ => bug!("closure substs missing synthetics"),
        }
    }

    /// Returns `true` only if enough of the synthetic types are known to
    /// allow using all of the methods on `ClosureSubsts` without panicking.
    ///
    /// Used primarily by `ty::print::pretty` to be able to handle closure
    /// types that haven't had their synthetic types substituted in.
    pub fn is_valid(self) -> bool {
        self.substs.len() >= 3 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_))
    }

    #[inline]
    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
        self.split().tupled_upvars_ty.expect_ty().tuple_fields()
    }

    /// Returns the closure kind for this closure; may return a type
    /// variable during inference. To get the closure kind during
    /// inference, use `infcx.closure_kind(substs)`.
    pub fn kind_ty(self) -> Ty<'tcx> {
        self.split().closure_kind_ty.expect_ty()
    }

    /// Returns the `fn` pointer type representing the closure signature for this
    /// closure.
    // FIXME(eddyb) this should be unnecessary, as the shallowly resolved
    // type is known at the time of the creation of `ClosureSubsts`,
    // see `rustc_typeck::check::closure`.
    pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> {
        self.split().closure_sig_as_fn_ptr_ty.expect_ty()
    }

    /// Returns the closure kind for this closure; only usable outside
    /// of an inference context, because in that context we know that
    /// there are no type variables.
    ///
    /// If you have an inference context, use `infcx.closure_kind()`.
    pub fn kind(self) -> ty::ClosureKind {
        self.kind_ty().to_opt_closure_kind().unwrap()
    }

    /// Extracts the signature from the closure.
    pub fn sig(self) -> ty::PolyFnSig<'tcx> {
        let ty = self.sig_as_fn_ptr_ty();
        match ty.kind {
            ty::FnPtr(sig) => sig,
            _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind),
        }
    }
}

/// Similar to `ClosureSubsts`; see the above documentation for more.
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct GeneratorSubsts<'tcx> {
    pub substs: SubstsRef<'tcx>,
}

struct SplitGeneratorSubsts<'tcx> {
    resume_ty: GenericArg<'tcx>,
    yield_ty: GenericArg<'tcx>,
    return_ty: GenericArg<'tcx>,
    witness: GenericArg<'tcx>,
    tupled_upvars_ty: GenericArg<'tcx>,
}

impl<'tcx> GeneratorSubsts<'tcx> {
    fn split(self) -> SplitGeneratorSubsts<'tcx> {
        match self.substs[..] {
            [.., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
                SplitGeneratorSubsts { resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty }
            }
            _ => bug!("generator substs missing synthetics"),
        }
    }

    /// Returns `true` only if enough of the synthetic types are known to
    /// allow using all of the methods on `GeneratorSubsts` without panicking.
    ///
    /// Used primarily by `ty::print::pretty` to be able to handle generator
    /// types that haven't had their synthetic types substituted in.
    pub fn is_valid(self) -> bool {
        self.substs.len() >= 5 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_))
    }

    /// This describes the types that can be contained in a generator.
    /// It will be a type variable initially and unified in the last stages of typeck of a body.
    /// It contains a tuple of all the types that could end up on a generator frame.
    /// The state transformation MIR pass may only produce layouts which mention types
    /// in this tuple. Upvars are not counted here.
    pub fn witness(self) -> Ty<'tcx> {
        self.split().witness.expect_ty()
    }

    #[inline]
    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
        self.split().tupled_upvars_ty.expect_ty().tuple_fields()
    }

    /// Returns the type representing the resume type of the generator.
    pub fn resume_ty(self) -> Ty<'tcx> {
        self.split().resume_ty.expect_ty()
    }

    /// Returns the type representing the yield type of the generator.
    pub fn yield_ty(self) -> Ty<'tcx> {
        self.split().yield_ty.expect_ty()
    }

    /// Returns the type representing the return type of the generator.
    pub fn return_ty(self) -> Ty<'tcx> {
        self.split().return_ty.expect_ty()
    }

    /// Returns the "generator signature", which consists of its yield
    /// and return types.
    ///
    /// N.B., some bits of the code prefers to see this wrapped in a
    /// binder, but it never contains bound regions. Probably this
    /// function should be removed.
    pub fn poly_sig(self) -> PolyGenSig<'tcx> {
        ty::Binder::dummy(self.sig())
    }

    /// Returns the "generator signature", which consists of its resume, yield
    /// and return types.
    pub fn sig(self) -> GenSig<'tcx> {
        ty::GenSig {
            resume_ty: self.resume_ty(),
            yield_ty: self.yield_ty(),
            return_ty: self.return_ty(),
        }
    }
}

impl<'tcx> GeneratorSubsts<'tcx> {
    /// Generator has not been resumed yet.
    pub const UNRESUMED: usize = 0;
    /// Generator has returned or is completed.
    pub const RETURNED: usize = 1;
    /// Generator has been poisoned.
    pub const POISONED: usize = 2;

    const UNRESUMED_NAME: &'static str = "Unresumed";
    const RETURNED_NAME: &'static str = "Returned";
    const POISONED_NAME: &'static str = "Panicked";

    /// The valid variant indices of this generator.
    #[inline]
    pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
        // FIXME requires optimized MIR
        let num_variants = tcx.generator_layout(def_id).variant_fields.len();
        VariantIdx::new(0)..VariantIdx::new(num_variants)
    }

    /// The discriminant for the given variant. Panics if the `variant_index` is
    /// out of range.
    #[inline]
    pub fn discriminant_for_variant(
        &self,
        def_id: DefId,
        tcx: TyCtxt<'tcx>,
        variant_index: VariantIdx,
    ) -> Discr<'tcx> {
        // Generators don't support explicit discriminant values, so they are
        // the same as the variant index.
        assert!(self.variant_range(def_id, tcx).contains(&variant_index));
        Discr { val: variant_index.as_usize() as u128, ty: self.discr_ty(tcx) }
    }

    /// The set of all discriminants for the generator, enumerated with their
    /// variant indices.
    #[inline]
    pub fn discriminants(
        self,
        def_id: DefId,
        tcx: TyCtxt<'tcx>,
    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
        self.variant_range(def_id, tcx).map(move |index| {
            (index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) })
        })
    }

    /// Calls `f` with a reference to the name of the enumerator for the given
    /// variant `v`.
    pub fn variant_name(v: VariantIdx) -> Cow<'static, str> {
        match v.as_usize() {
            Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),
            Self::RETURNED => Cow::from(Self::RETURNED_NAME),
            Self::POISONED => Cow::from(Self::POISONED_NAME),
            _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)),
        }
    }

    /// The type of the state discriminant used in the generator type.
    #[inline]
    pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
        tcx.types.u32
    }

    /// This returns the types of the MIR locals which had to be stored across suspension points.
    /// It is calculated in rustc_mir::transform::generator::StateTransform.
    /// All the types here must be in the tuple in GeneratorInterior.
    ///
    /// The locals are grouped by their variant number. Note that some locals may
    /// be repeated in multiple variants.
    #[inline]
    pub fn state_tys(
        self,
        def_id: DefId,
        tcx: TyCtxt<'tcx>,
    ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
        let layout = tcx.generator_layout(def_id);
        layout.variant_fields.iter().map(move |variant| {
            variant.iter().map(move |field| layout.field_tys[*field].subst(tcx, self.substs))
        })
    }

    /// This is the types of the fields of a generator which are not stored in a
    /// variant.
    #[inline]
    pub fn prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>> {
        self.upvar_tys()
    }
}

#[derive(Debug, Copy, Clone)]
pub enum UpvarSubsts<'tcx> {
    Closure(SubstsRef<'tcx>),
    Generator(SubstsRef<'tcx>),
}

impl<'tcx> UpvarSubsts<'tcx> {
    #[inline]
    pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
        let tupled_upvars_ty = match self {
            UpvarSubsts::Closure(substs) => substs.as_closure().split().tupled_upvars_ty,
            UpvarSubsts::Generator(substs) => substs.as_generator().split().tupled_upvars_ty,
        };
        tupled_upvars_ty.expect_ty().tuple_fields()
    }
}

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub enum ExistentialPredicate<'tcx> {
    /// E.g., `Iterator`.
    Trait(ExistentialTraitRef<'tcx>),
    /// E.g., `Iterator::Item = T`.
    Projection(ExistentialProjection<'tcx>),
    /// E.g., `Send`.
    AutoTrait(DefId),
}

impl<'tcx> ExistentialPredicate<'tcx> {
    /// Compares via an ordering that will not change if modules are reordered or other changes are
    /// made to the tree. In particular, this ordering is preserved across incremental compilations.
    pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
        use self::ExistentialPredicate::*;
        match (*self, *other) {
            (Trait(_), Trait(_)) => Ordering::Equal,
            (Projection(ref a), Projection(ref b)) => {
                tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id))
            }
            (AutoTrait(ref a), AutoTrait(ref b)) => {
                tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash)
            }
            (Trait(_), _) => Ordering::Less,
            (Projection(_), Trait(_)) => Ordering::Greater,
            (Projection(_), _) => Ordering::Less,
            (AutoTrait(_), _) => Ordering::Greater,
        }
    }
}

impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
        use crate::ty::ToPredicate;
        match self.skip_binder() {
            ExistentialPredicate::Trait(tr) => {
                Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
            }
            ExistentialPredicate::Projection(p) => {
                ty::PredicateKind::Projection(Binder(p.with_self_ty(tcx, self_ty)))
                    .to_predicate(tcx)
            }
            ExistentialPredicate::AutoTrait(did) => {
                let trait_ref =
                    Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) });
                trait_ref.without_const().to_predicate(tcx)
            }
        }
    }
}

impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}

impl<'tcx> List<ExistentialPredicate<'tcx>> {
    /// Returns the "principal `DefId`" of this set of existential predicates.
    ///
    /// A Rust trait object type consists (in addition to a lifetime bound)
    /// of a set of trait bounds, which are separated into any number
    /// of auto-trait bounds, and at most one non-auto-trait bound. The
    /// non-auto-trait bound is called the "principal" of the trait
    /// object.
    ///
    /// Only the principal can have methods or type parameters (because
    /// auto traits can have neither of them). This is important, because
    /// it means the auto traits can be treated as an unordered set (methods
    /// would force an order for the vtable, while relating traits with
    /// type parameters without knowing the order to relate them in is
    /// a rather non-trivial task).
    ///
    /// For example, in the trait object `dyn fmt::Debug + Sync`, the
    /// principal bound is `Some(fmt::Debug)`, while the auto-trait bounds
    /// are the set `{Sync}`.
    ///
    /// It is also possible to have a "trivial" trait object that
    /// consists only of auto traits, with no principal - for example,
    /// `dyn Send + Sync`. In that case, the set of auto-trait bounds
    /// is `{Send, Sync}`, while there is no principal. These trait objects
    /// have a "trivial" vtable consisting of just the size, alignment,
    /// and destructor.
    pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
        match self[0] {
            ExistentialPredicate::Trait(tr) => Some(tr),
            _ => None,
        }
    }

    pub fn principal_def_id(&self) -> Option<DefId> {
        self.principal().map(|trait_ref| trait_ref.def_id)
    }

    #[inline]
    pub fn projection_bounds<'a>(
        &'a self,
    ) -> impl Iterator<Item = ExistentialProjection<'tcx>> + 'a {
        self.iter().filter_map(|predicate| match predicate {
            ExistentialPredicate::Projection(projection) => Some(projection),
            _ => None,
        })
    }

    #[inline]
    pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
        self.iter().filter_map(|predicate| match predicate {
            ExistentialPredicate::AutoTrait(did) => Some(did),
            _ => None,
        })
    }
}

impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
    pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
        self.skip_binder().principal().map(Binder::bind)
    }

    pub fn principal_def_id(&self) -> Option<DefId> {
        self.skip_binder().principal_def_id()
    }

    #[inline]
    pub fn projection_bounds<'a>(
        &'a self,
    ) -> impl Iterator<Item = PolyExistentialProjection<'tcx>> + 'a {
        self.skip_binder().projection_bounds().map(Binder::bind)
    }

    #[inline]
    pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
        self.skip_binder().auto_traits()
    }

    pub fn iter<'a>(
        &'a self,
    ) -> impl DoubleEndedIterator<Item = Binder<ExistentialPredicate<'tcx>>> + 'tcx {
        self.skip_binder().iter().map(Binder::bind)
    }
}

/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where-clause:
///
///     T: Foo<U>
///
/// This would be represented by a trait-reference where the `DefId` is the
/// `DefId` for the trait `Foo` and the substs define `T` as parameter 0,
/// and `U` as parameter 1.
///
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions.
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct TraitRef<'tcx> {
    pub def_id: DefId,
    pub substs: SubstsRef<'tcx>,
}

impl<'tcx> TraitRef<'tcx> {
    pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> TraitRef<'tcx> {
        TraitRef { def_id, substs }
    }

    /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
    /// are the parameters defined on trait.
    pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
        TraitRef { def_id, substs: InternalSubsts::identity_for_item(tcx, def_id) }
    }

    #[inline]
    pub fn self_ty(&self) -> Ty<'tcx> {
        self.substs.type_at(0)
    }

    pub fn from_method(
        tcx: TyCtxt<'tcx>,
        trait_id: DefId,
        substs: SubstsRef<'tcx>,
    ) -> ty::TraitRef<'tcx> {
        let defs = tcx.generics_of(trait_id);

        ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) }
    }
}

pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;

impl<'tcx> PolyTraitRef<'tcx> {
    pub fn self_ty(&self) -> Binder<Ty<'tcx>> {
        self.map_bound_ref(|tr| tr.self_ty())
    }

    pub fn def_id(&self) -> DefId {
        self.skip_binder().def_id
    }

    pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
        // Note that we preserve binding levels
        Binder(ty::TraitPredicate { trait_ref: self.skip_binder() })
    }
}

/// An existential reference to a trait, where `Self` is erased.
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
///
///     exists T. T: Trait<'a, 'b, X, Y>
///
/// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct ExistentialTraitRef<'tcx> {
    pub def_id: DefId,
    pub substs: SubstsRef<'tcx>,
}

impl<'tcx> ExistentialTraitRef<'tcx> {
    pub fn erase_self_ty(
        tcx: TyCtxt<'tcx>,
        trait_ref: ty::TraitRef<'tcx>,
    ) -> ty::ExistentialTraitRef<'tcx> {
        // Assert there is a Self.
        trait_ref.substs.type_at(0);

        ty::ExistentialTraitRef {
            def_id: trait_ref.def_id,
            substs: tcx.intern_substs(&trait_ref.substs[1..]),
        }
    }

    /// Object types don't have a self type specified. Therefore, when
    /// we convert the principal trait-ref into a normal trait-ref,
    /// you must give *some* self type. A common choice is `mk_err()`
    /// or some placeholder type.
    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> {
        // otherwise the escaping vars would be captured by the binder
        // debug_assert!(!self_ty.has_escaping_bound_vars());

        ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) }
    }
}

pub type PolyExistentialTraitRef<'tcx> = Binder<ExistentialTraitRef<'tcx>>;

impl<'tcx> PolyExistentialTraitRef<'tcx> {
    pub fn def_id(&self) -> DefId {
        self.skip_binder().def_id
    }

    /// Object types don't have a self type specified. Therefore, when
    /// we convert the principal trait-ref into a normal trait-ref,
    /// you must give *some* self type. A common choice is `mk_err()`
    /// or some placeholder type.
    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> {
        self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
    }
}

/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
/// (which would be represented by the type `PolyTraitRef ==
/// Binder<TraitRef>`). Note that when we instantiate,
/// erase, or otherwise "discharge" these bound vars, we change the
/// type from `Binder<T>` to just `T` (see
/// e.g., `liberate_late_bound_regions`).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct Binder<T>(T);

impl<T> Binder<T> {
    /// Wraps `value` in a binder, asserting that `value` does not
    /// contain any bound vars that would be bound by the
    /// binder. This is commonly used to 'inject' a value T into a
    /// different binding level.
    pub fn dummy<'tcx>(value: T) -> Binder<T>
    where
        T: TypeFoldable<'tcx>,
    {
        debug_assert!(!value.has_escaping_bound_vars());
        Binder(value)
    }

    /// Wraps `value` in a binder, binding higher-ranked vars (if any).
    pub fn bind(value: T) -> Binder<T> {
        Binder(value)
    }

    /// Skips the binder and returns the "bound" value. This is a
    /// risky thing to do because it's easy to get confused about
    /// De Bruijn indices and the like. It is usually better to
    /// discharge the binder using `no_bound_vars` or
    /// `replace_late_bound_regions` or something like
    /// that. `skip_binder` is only valid when you are either
    /// extracting data that has nothing to do with bound vars, you
    /// are doing some sort of test that does not involve bound
    /// regions, or you are being very careful about your depth
    /// accounting.
    ///
    /// Some examples where `skip_binder` is reasonable:
    ///
    /// - extracting the `DefId` from a PolyTraitRef;
    /// - comparing the self type of a PolyTraitRef to see if it is equal to
    ///   a type parameter `X`, since the type `X` does not reference any regions
    pub fn skip_binder(self) -> T {
        self.0
    }

    pub fn as_ref(&self) -> Binder<&T> {
        Binder(&self.0)
    }

    pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
    where
        F: FnOnce(&T) -> U,
    {
        self.as_ref().map_bound(f)
    }

    pub fn map_bound<F, U>(self, f: F) -> Binder<U>
    where
        F: FnOnce(T) -> U,
    {
        Binder(f(self.0))
    }

    /// Unwraps and returns the value within, but only if it contains
    /// no bound vars at all. (In other words, if this binder --
    /// and indeed any enclosing binder -- doesn't bind anything at
    /// all.) Otherwise, returns `None`.
    ///
    /// (One could imagine having a method that just unwraps a single
    /// binder, but permits late-bound vars bound by enclosing
    /// binders, but that would require adjusting the debruijn
    /// indices, and given the shallow binding structure we often use,
    /// would not be that useful.)
    pub fn no_bound_vars<'tcx>(self) -> Option<T>
    where
        T: TypeFoldable<'tcx>,
    {
        if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
    }

    /// Given two things that have the same binder level,
    /// and an operation that wraps on their contents, executes the operation
    /// and then wraps its result.
    ///
    /// `f` should consider bound regions at depth 1 to be free, and
    /// anything it produces with bound regions at depth 1 will be
    /// bound in the resulting return value.
    pub fn fuse<U, F, R>(self, u: Binder<U>, f: F) -> Binder<R>
    where
        F: FnOnce(T, U) -> R,
    {
        Binder(f(self.0, u.0))
    }

    /// Splits the contents into two things that share the same binder
    /// level as the original, returning two distinct binders.
    ///
    /// `f` should consider bound regions at depth 1 to be free, and
    /// anything it produces with bound regions at depth 1 will be
    /// bound in the resulting return values.
    pub fn split<U, V, F>(self, f: F) -> (Binder<U>, Binder<V>)
    where
        F: FnOnce(T) -> (U, V),
    {
        let (u, v) = f(self.0);
        (Binder(u), Binder(v))
    }
}

/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct ProjectionTy<'tcx> {
    /// The parameters of the associated item.
    pub substs: SubstsRef<'tcx>,

    /// The `DefId` of the `TraitItem` for the associated type `N`.
    ///
    /// Note that this is not the `DefId` of the `TraitRef` containing this
    /// associated type, which is in `tcx.associated_item(item_def_id).container`.
    pub item_def_id: DefId,
}

impl<'tcx> ProjectionTy<'tcx> {
    /// Construct a `ProjectionTy` by searching the trait from `trait_ref` for the
    /// associated item named `item_name`.
    pub fn from_ref_and_name(
        tcx: TyCtxt<'_>,
        trait_ref: ty::TraitRef<'tcx>,
        item_name: Ident,
    ) -> ProjectionTy<'tcx> {
        let item_def_id = tcx
            .associated_items(trait_ref.def_id)
            .find_by_name_and_kind(tcx, item_name, ty::AssocKind::Type, trait_ref.def_id)
            .unwrap()
            .def_id;

        ProjectionTy { substs: trait_ref.substs, item_def_id }
    }

    /// Extracts the underlying trait reference from this projection.
    /// For example, if this is a projection of `<T as Iterator>::Item`,
    /// then this function would return a `T: Iterator` trait reference.
    pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
        let def_id = tcx.associated_item(self.item_def_id).container.id();
        ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) }
    }

    pub fn self_ty(&self) -> Ty<'tcx> {
        self.substs.type_at(0)
    }
}

#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct GenSig<'tcx> {
    pub resume_ty: Ty<'tcx>,
    pub yield_ty: Ty<'tcx>,
    pub return_ty: Ty<'tcx>,
}

pub type PolyGenSig<'tcx> = Binder<GenSig<'tcx>>;

impl<'tcx> PolyGenSig<'tcx> {
    pub fn resume_ty(&self) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|sig| sig.resume_ty)
    }
    pub fn yield_ty(&self) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|sig| sig.yield_ty)
    }
    pub fn return_ty(&self) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|sig| sig.return_ty)
    }
}

/// Signature of a function type, which we have arbitrarily
/// decided to use to refer to the input/output types.
///
/// - `inputs`: is the list of arguments and their modes.
/// - `output`: is the return type.
/// - `c_variadic`: indicates whether this is a C-variadic function.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct FnSig<'tcx> {
    pub inputs_and_output: &'tcx List<Ty<'tcx>>,
    pub c_variadic: bool,
    pub unsafety: hir::Unsafety,
    pub abi: abi::Abi,
}

impl<'tcx> FnSig<'tcx> {
    pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
        &self.inputs_and_output[..self.inputs_and_output.len() - 1]
    }

    pub fn output(&self) -> Ty<'tcx> {
        self.inputs_and_output[self.inputs_and_output.len() - 1]
    }

    // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
    // method.
    fn fake() -> FnSig<'tcx> {
        FnSig {
            inputs_and_output: List::empty(),
            c_variadic: false,
            unsafety: hir::Unsafety::Normal,
            abi: abi::Abi::Rust,
        }
    }
}

pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;

impl<'tcx> PolyFnSig<'tcx> {
    #[inline]
    pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
        self.map_bound_ref(|fn_sig| fn_sig.inputs())
    }
    #[inline]
    pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
    }
    pub fn inputs_and_output(&self) -> ty::Binder<&'tcx List<Ty<'tcx>>> {
        self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
    }
    #[inline]
    pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
        self.map_bound_ref(|fn_sig| fn_sig.output())
    }
    pub fn c_variadic(&self) -> bool {
        self.skip_binder().c_variadic
    }
    pub fn unsafety(&self) -> hir::Unsafety {
        self.skip_binder().unsafety
    }
    pub fn abi(&self) -> abi::Abi {
        self.skip_binder().abi
    }
}

pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable)]
pub struct ParamTy {
    pub index: u32,
    pub name: Symbol,
}

impl<'tcx> ParamTy {
    pub fn new(index: u32, name: Symbol) -> ParamTy {
        ParamTy { index, name }
    }

    pub fn for_self() -> ParamTy {
        ParamTy::new(0, kw::SelfUpper)
    }

    pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
        ParamTy::new(def.index, def.name)
    }

    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
        tcx.mk_ty_param(self.index, self.name)
    }
}

#[derive(Copy, Clone, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
#[derive(HashStable)]
pub struct ParamConst {
    pub index: u32,
    pub name: Symbol,
}

impl<'tcx> ParamConst {
    pub fn new(index: u32, name: Symbol) -> ParamConst {
        ParamConst { index, name }
    }

    pub fn for_def(def: &ty::GenericParamDef) -> ParamConst {
        ParamConst::new(def.index, def.name)
    }

    pub fn to_const(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
        tcx.mk_const_param(self.index, self.name, ty)
    }
}

rustc_index::newtype_index! {
    /// A [De Bruijn index][dbi] is a standard means of representing
    /// regions (and perhaps later types) in a higher-ranked setting. In
    /// particular, imagine a type like this:
    ///
    ///     for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
    ///     ^          ^            |        |         |
    ///     |          |            |        |         |
    ///     |          +------------+ 0      |         |
    ///     |                                |         |
    ///     +--------------------------------+ 1       |
    ///     |                                          |
    ///     +------------------------------------------+ 0
    ///
    /// In this type, there are two binders (the outer fn and the inner
    /// fn). We need to be able to determine, for any given region, which
    /// fn type it is bound by, the inner or the outer one. There are
    /// various ways you can do this, but a De Bruijn index is one of the
    /// more convenient and has some nice properties. The basic idea is to
    /// count the number of binders, inside out. Some examples should help
    /// clarify what I mean.
    ///
    /// Let's start with the reference type `&'b isize` that is the first
    /// argument to the inner function. This region `'b` is assigned a De
    /// Bruijn index of 0, meaning "the innermost binder" (in this case, a
    /// fn). The region `'a` that appears in the second argument type (`&'a
    /// isize`) would then be assigned a De Bruijn index of 1, meaning "the
    /// second-innermost binder". (These indices are written on the arrays
    /// in the diagram).
    ///
    /// What is interesting is that De Bruijn index attached to a particular
    /// variable will vary depending on where it appears. For example,
    /// the final type `&'a char` also refers to the region `'a` declared on
    /// the outermost fn. But this time, this reference is not nested within
    /// any other binders (i.e., it is not an argument to the inner fn, but
    /// rather the outer one). Therefore, in this case, it is assigned a
    /// De Bruijn index of 0, because the innermost binder in that location
    /// is the outer fn.
    ///
    /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
    #[derive(HashStable)]
    pub struct DebruijnIndex {
        DEBUG_FORMAT = "DebruijnIndex({})",
        const INNERMOST = 0,
    }
}

pub type Region<'tcx> = &'tcx RegionKind;

/// Representation of regions. Note that the NLL checker uses a distinct
/// representation of regions. For this reason, it internally replaces all the
/// regions with inference variables -- the index of the variable is then used
/// to index into internal NLL data structures. See `rustc_mir::borrow_check`
/// module for more information.
///
/// ## The Region lattice within a given function
///
/// In general, the region lattice looks like
///
/// ```
/// static ----------+-----...------+       (greatest)
/// |                |              |
/// early-bound and  |              |
/// free regions     |              |
/// |                |              |
/// |                |              |
/// empty(root)   placeholder(U1)   |
/// |            /                  |
/// |           /         placeholder(Un)
/// empty(U1) --         /
/// |                   /
/// ...                /
/// |                 /
/// empty(Un) --------                      (smallest)
/// ```
///
/// Early-bound/free regions are the named lifetimes in scope from the
/// function declaration. They have relationships to one another
/// determined based on the declared relationships from the
/// function.
///
/// Note that inference variables and bound regions are not included
/// in this diagram. In the case of inference variables, they should
/// be inferred to some other region from the diagram.  In the case of
/// bound regions, they are excluded because they don't make sense to
/// include -- the diagram indicates the relationship between free
/// regions.
///
/// ## Inference variables
///
/// During region inference, we sometimes create inference variables,
/// represented as `ReVar`. These will be inferred by the code in
/// `infer::lexical_region_resolve` to some free region from the
/// lattice above (the minimal region that meets the
/// constraints).
///
/// During NLL checking, where regions are defined differently, we
/// also use `ReVar` -- in that case, the index is used to index into
/// the NLL region checker's data structures. The variable may in fact
/// represent either a free region or an inference variable, in that
/// case.
///
/// ## Bound Regions
///
/// These are regions that are stored behind a binder and must be substituted
/// with some concrete region before being used. There are two kind of
/// bound regions: early-bound, which are bound in an item's `Generics`,
/// and are substituted by a `InternalSubsts`, and late-bound, which are part of
/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
/// the likes of `liberate_late_bound_regions`. The distinction exists
/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
///
/// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
/// outside their binder, e.g., in types passed to type inference, and
/// should first be substituted (by placeholder regions, free regions,
/// or region variables).
///
/// ## Placeholder and Free Regions
///
/// One often wants to work with bound regions without knowing their precise
/// identity. For example, when checking a function, the lifetime of a borrow
/// can end up being assigned to some region parameter. In these cases,
/// it must be ensured that bounds on the region can't be accidentally
/// assumed without being checked.
///
/// To do this, we replace the bound regions with placeholder markers,
/// which don't satisfy any relation not explicitly provided.
///
/// There are two kinds of placeholder regions in rustc: `ReFree` and
/// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
/// to be used. These also support explicit bounds: both the internally-stored
/// *scope*, which the region is assumed to outlive, as well as other
/// relations stored in the `FreeRegionMap`. Note that these relations
/// aren't checked when you `make_subregion` (or `eq_types`), only by
/// `resolve_regions_and_report_errors`.
///
/// When working with higher-ranked types, some region relations aren't
/// yet known, so you can't just call `resolve_regions_and_report_errors`.
/// `RePlaceholder` is designed for this purpose. In these contexts,
/// there's also the risk that some inference variable laying around will
/// get unified with your placeholder region: if you want to check whether
/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
/// with a placeholder region `'%a`, the variable `'_` would just be
/// instantiated to the placeholder region `'%a`, which is wrong because
/// the inference variable is supposed to satisfy the relation
/// *for every value of the placeholder region*. To ensure that doesn't
/// happen, you can use `leak_check`. This is more clearly explained
/// by the [rustc dev guide].
///
/// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
/// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
pub enum RegionKind {
    /// Region bound in a type or fn declaration which will be
    /// substituted 'early' -- that is, at the same time when type
    /// parameters are substituted.
    ReEarlyBound(EarlyBoundRegion),

    /// Region bound in a function scope, which will be substituted when the
    /// function is called.
    ReLateBound(DebruijnIndex, BoundRegion),

    /// When checking a function body, the types of all arguments and so forth
    /// that refer to bound region parameters are modified to refer to free
    /// region parameters.
    ReFree(FreeRegion),

    /// Static data that has an "infinite" lifetime. Top in the region lattice.
    ReStatic,

    /// A region variable. Should not exist after typeck.
    ReVar(RegionVid),

    /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
    /// Should not exist after typeck.
    RePlaceholder(ty::PlaceholderRegion),

    /// Empty lifetime is for data that is never accessed.  We tag the
    /// empty lifetime with a universe -- the idea is that we don't
    /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
    /// Therefore, the `'empty` in a universe `U` is less than all
    /// regions visible from `U`, but not less than regions not visible
    /// from `U`.
    ReEmpty(ty::UniverseIndex),

    /// Erased region, used by trait selection, in MIR and during codegen.
    ReErased,
}

impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {}

#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, PartialOrd, Ord)]
pub struct EarlyBoundRegion {
    pub def_id: DefId,
    pub index: u32,
    pub name: Symbol,
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct TyVid {
    pub index: u32,
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct ConstVid<'tcx> {
    pub index: u32,
    pub phantom: PhantomData<&'tcx ()>,
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct IntVid {
    pub index: u32,
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct FloatVid {
    pub index: u32,
}

rustc_index::newtype_index! {
    pub struct RegionVid {
        DEBUG_FORMAT = custom,
    }
}

impl Atom for RegionVid {
    fn index(self) -> usize {
        Idx::index(self)
    }
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable)]
pub enum InferTy {
    TyVar(TyVid),
    IntVar(IntVid),
    FloatVar(FloatVid),

    /// A `FreshTy` is one that is generated as a replacement for an
    /// unbound type variable. This is convenient for caching etc. See
    /// `infer::freshen` for more details.
    FreshTy(u32),
    FreshIntTy(u32),
    FreshFloatTy(u32),
}

rustc_index::newtype_index! {
    pub struct BoundVar { .. }
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable)]
pub struct BoundTy {
    pub var: BoundVar,
    pub kind: BoundTyKind,
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable)]
pub enum BoundTyKind {
    Anon,
    Param(Symbol),
}

impl From<BoundVar> for BoundTy {
    fn from(var: BoundVar) -> Self {
        BoundTy { var, kind: BoundTyKind::Anon }
    }
}

/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct ExistentialProjection<'tcx> {
    pub item_def_id: DefId,
    pub substs: SubstsRef<'tcx>,
    pub ty: Ty<'tcx>,
}

pub type PolyExistentialProjection<'tcx> = Binder<ExistentialProjection<'tcx>>;

impl<'tcx> ExistentialProjection<'tcx> {
    /// Extracts the underlying existential trait reference from this projection.
    /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
    /// then this function would return a `exists T. T: Iterator` existential trait
    /// reference.
    pub fn trait_ref(&self, tcx: TyCtxt<'_>) -> ty::ExistentialTraitRef<'tcx> {
        let def_id = tcx.associated_item(self.item_def_id).container.id();
        ty::ExistentialTraitRef { def_id, substs: self.substs }
    }

    pub fn with_self_ty(
        &self,
        tcx: TyCtxt<'tcx>,
        self_ty: Ty<'tcx>,
    ) -> ty::ProjectionPredicate<'tcx> {
        // otherwise the escaping regions would be captured by the binders
        debug_assert!(!self_ty.has_escaping_bound_vars());

        ty::ProjectionPredicate {
            projection_ty: ty::ProjectionTy {
                item_def_id: self.item_def_id,
                substs: tcx.mk_substs_trait(self_ty, self.substs),
            },
            ty: self.ty,
        }
    }
}

impl<'tcx> PolyExistentialProjection<'tcx> {
    pub fn with_self_ty(
        &self,
        tcx: TyCtxt<'tcx>,
        self_ty: Ty<'tcx>,
    ) -> ty::PolyProjectionPredicate<'tcx> {
        self.map_bound(|p| p.with_self_ty(tcx, self_ty))
    }

    pub fn item_def_id(&self) -> DefId {
        self.skip_binder().item_def_id
    }
}

impl DebruijnIndex {
    /// Returns the resulting index when this value is moved into
    /// `amount` number of new binders. So, e.g., if you had
    ///
    ///    for<'a> fn(&'a x)
    ///
    /// and you wanted to change it to
    ///
    ///    for<'a> fn(for<'b> fn(&'a x))
    ///
    /// you would need to shift the index for `'a` into a new binder.
    #[must_use]
    pub fn shifted_in(self, amount: u32) -> DebruijnIndex {
        DebruijnIndex::from_u32(self.as_u32() + amount)
    }

    /// Update this index in place by shifting it "in" through
    /// `amount` number of binders.
    pub fn shift_in(&mut self, amount: u32) {
        *self = self.shifted_in(amount);
    }

    /// Returns the resulting index when this value is moved out from
    /// `amount` number of new binders.
    #[must_use]
    pub fn shifted_out(self, amount: u32) -> DebruijnIndex {
        DebruijnIndex::from_u32(self.as_u32() - amount)
    }

    /// Update in place by shifting out from `amount` binders.
    pub fn shift_out(&mut self, amount: u32) {
        *self = self.shifted_out(amount);
    }

    /// Adjusts any De Bruijn indices so as to make `to_binder` the
    /// innermost binder. That is, if we have something bound at `to_binder`,
    /// it will now be bound at INNERMOST. This is an appropriate thing to do
    /// when moving a region out from inside binders:
    ///
    /// ```
    ///             for<'a>   fn(for<'b>   for<'c>   fn(&'a u32), _)
    /// // Binder:  D3           D2        D1            ^^
    /// ```
    ///
    /// Here, the region `'a` would have the De Bruijn index D3,
    /// because it is the bound 3 binders out. However, if we wanted
    /// to refer to that region `'a` in the second argument (the `_`),
    /// those two binders would not be in scope. In that case, we
    /// might invoke `shift_out_to_binder(D3)`. This would adjust the
    /// De Bruijn index of `'a` to D1 (the innermost binder).
    ///
    /// If we invoke `shift_out_to_binder` and the region is in fact
    /// bound by one of the binders we are shifting out of, that is an
    /// error (and should fail an assertion failure).
    pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
        self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32())
    }
}

/// Region utilities
impl RegionKind {
    /// Is this region named by the user?
    pub fn has_name(&self) -> bool {
        match *self {
            RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
            RegionKind::ReLateBound(_, br) => br.is_named(),
            RegionKind::ReFree(fr) => fr.bound_region.is_named(),
            RegionKind::ReStatic => true,
            RegionKind::ReVar(..) => false,
            RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(),
            RegionKind::ReEmpty(_) => false,
            RegionKind::ReErased => false,
        }
    }

    pub fn is_late_bound(&self) -> bool {
        match *self {
            ty::ReLateBound(..) => true,
            _ => false,
        }
    }

    pub fn is_placeholder(&self) -> bool {
        match *self {
            ty::RePlaceholder(..) => true,
            _ => false,
        }
    }

    pub fn bound_at_or_above_binder(&self, index: DebruijnIndex) -> bool {
        match *self {
            ty::ReLateBound(debruijn, _) => debruijn >= index,
            _ => false,
        }
    }

    /// Adjusts any De Bruijn indices so as to make `to_binder` the
    /// innermost binder. That is, if we have something bound at `to_binder`,
    /// it will now be bound at INNERMOST. This is an appropriate thing to do
    /// when moving a region out from inside binders:
    ///
    /// ```
    ///             for<'a>   fn(for<'b>   for<'c>   fn(&'a u32), _)
    /// // Binder:  D3           D2        D1            ^^
    /// ```
    ///
    /// Here, the region `'a` would have the De Bruijn index D3,
    /// because it is the bound 3 binders out. However, if we wanted
    /// to refer to that region `'a` in the second argument (the `_`),
    /// those two binders would not be in scope. In that case, we
    /// might invoke `shift_out_to_binder(D3)`. This would adjust the
    /// De Bruijn index of `'a` to D1 (the innermost binder).
    ///
    /// If we invoke `shift_out_to_binder` and the region is in fact
    /// bound by one of the binders we are shifting out of, that is an
    /// error (and should fail an assertion failure).
    pub fn shifted_out_to_binder(&self, to_binder: ty::DebruijnIndex) -> RegionKind {
        match *self {
            ty::ReLateBound(debruijn, r) => {
                ty::ReLateBound(debruijn.shifted_out_to_binder(to_binder), r)
            }
            r => r,
        }
    }

    pub fn type_flags(&self) -> TypeFlags {
        let mut flags = TypeFlags::empty();

        match *self {
            ty::ReVar(..) => {
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
                flags = flags | TypeFlags::HAS_RE_INFER;
            }
            ty::RePlaceholder(..) => {
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
                flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
            }
            ty::ReEarlyBound(..) => {
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
                flags = flags | TypeFlags::HAS_RE_PARAM;
            }
            ty::ReFree { .. } => {
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
                flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
            }
            ty::ReEmpty(_) | ty::ReStatic => {
                flags = flags | TypeFlags::HAS_FREE_REGIONS;
            }
            ty::ReLateBound(..) => {
                flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
            }
            ty::ReErased => {
                flags = flags | TypeFlags::HAS_RE_ERASED;
            }
        }

        debug!("type_flags({:?}) = {:?}", self, flags);

        flags
    }

    /// Given an early-bound or free region, returns the `DefId` where it was bound.
    /// For example, consider the regions in this snippet of code:
    ///
    /// ```
    /// impl<'a> Foo {
    ///      ^^ -- early bound, declared on an impl
    ///
    ///     fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
    ///            ^^  ^^     ^ anonymous, late-bound
    ///            |   early-bound, appears in where-clauses
    ///            late-bound, appears only in fn args
    ///     {..}
    /// }
    /// ```
    ///
    /// Here, `free_region_binding_scope('a)` would return the `DefId`
    /// of the impl, and for all the other highlighted regions, it
    /// would return the `DefId` of the function. In other cases (not shown), this
    /// function might return the `DefId` of a closure.
    pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_>) -> DefId {
        match self {
            ty::ReEarlyBound(br) => tcx.parent(br.def_id).unwrap(),
            ty::ReFree(fr) => fr.scope,
            _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
        }
    }
}

/// Type utilities
impl<'tcx> TyS<'tcx> {
    #[inline]
    pub fn is_unit(&self) -> bool {
        match self.kind {
            Tuple(ref tys) => tys.is_empty(),
            _ => false,
        }
    }

    #[inline]
    pub fn is_never(&self) -> bool {
        match self.kind {
            Never => true,
            _ => false,
        }
    }

    /// Checks whether a type is definitely uninhabited. This is
    /// conservative: for some types that are uninhabited we return `false`,
    /// but we only return `true` for types that are definitely uninhabited.
    /// `ty.conservative_is_privately_uninhabited` implies that any value of type `ty`
    /// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
    /// size, to account for partial initialisation. See #49298 for details.)
    pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
        // FIXME(varkor): we can make this less conversative by substituting concrete
        // type arguments.
        match self.kind {
            ty::Never => true,
            ty::Adt(def, _) if def.is_union() => {
                // For now, `union`s are never considered uninhabited.
                false
            }
            ty::Adt(def, _) => {
                // Any ADT is uninhabited if either:
                // (a) It has no variants (i.e. an empty `enum`);
                // (b) Each of its variants (a single one in the case of a `struct`) has at least
                //     one uninhabited field.
                def.variants.iter().all(|var| {
                    var.fields.iter().any(|field| {
                        tcx.type_of(field.did).conservative_is_privately_uninhabited(tcx)
                    })
                })
            }
            ty::Tuple(..) => {
                self.tuple_fields().any(|ty| ty.conservative_is_privately_uninhabited(tcx))
            }
            ty::Array(ty, len) => {
                match len.try_eval_usize(tcx, ParamEnv::empty()) {
                    // If the array is definitely non-empty, it's uninhabited if
                    // the type of its elements is uninhabited.
                    Some(n) if n != 0 => ty.conservative_is_privately_uninhabited(tcx),
                    _ => false,
                }
            }
            ty::Ref(..) => {
                // References to uninitialised memory is valid for any type, including
                // uninhabited types, in unsafe code, so we treat all references as
                // inhabited.
                false
            }
            _ => false,
        }
    }

    #[inline]
    pub fn is_primitive(&self) -> bool {
        match self.kind {
            Bool | Char | Int(_) | Uint(_) | Float(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_ty_var(&self) -> bool {
        match self.kind {
            Infer(TyVar(_)) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_ty_infer(&self) -> bool {
        match self.kind {
            Infer(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_phantom_data(&self) -> bool {
        if let Adt(def, _) = self.kind { def.is_phantom_data() } else { false }
    }

    #[inline]
    pub fn is_bool(&self) -> bool {
        self.kind == Bool
    }

    /// Returns `true` if this type is a `str`.
    #[inline]
    pub fn is_str(&self) -> bool {
        self.kind == Str
    }

    #[inline]
    pub fn is_param(&self, index: u32) -> bool {
        match self.kind {
            ty::Param(ref data) => data.index == index,
            _ => false,
        }
    }

    #[inline]
    pub fn is_slice(&self) -> bool {
        match self.kind {
            RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => match ty.kind {
                Slice(_) | Str => true,
                _ => false,
            },
            _ => false,
        }
    }

    #[inline]
    pub fn is_simd(&self) -> bool {
        match self.kind {
            Adt(def, _) => def.repr.simd(),
            _ => false,
        }
    }

    pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
        match self.kind {
            Array(ty, _) | Slice(ty) => ty,
            Str => tcx.mk_mach_uint(ast::UintTy::U8),
            _ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
        }
    }

    pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
        match self.kind {
            Adt(def, substs) => def.non_enum_variant().fields[0].ty(tcx, substs),
            _ => bug!("`simd_type` called on invalid type"),
        }
    }

    pub fn simd_size(&self, _tcx: TyCtxt<'tcx>) -> u64 {
        // Parameter currently unused, but probably needed in the future to
        // allow `#[repr(simd)] struct Simd<T, const N: usize>([T; N]);`.
        match self.kind {
            Adt(def, _) => def.non_enum_variant().fields.len() as u64,
            _ => bug!("`simd_size` called on invalid type"),
        }
    }

    pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
        match self.kind {
            Adt(def, substs) => {
                let variant = def.non_enum_variant();
                (variant.fields.len() as u64, variant.fields[0].ty(tcx, substs))
            }
            _ => bug!("`simd_size_and_type` called on invalid type"),
        }
    }

    #[inline]
    pub fn is_region_ptr(&self) -> bool {
        match self.kind {
            Ref(..) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_mutable_ptr(&self) -> bool {
        match self.kind {
            RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. })
            | Ref(_, _, hir::Mutability::Mut) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_unsafe_ptr(&self) -> bool {
        match self.kind {
            RawPtr(_) => true,
            _ => false,
        }
    }

    /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
    #[inline]
    pub fn is_any_ptr(&self) -> bool {
        self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr()
    }

    #[inline]
    pub fn is_box(&self) -> bool {
        match self.kind {
            Adt(def, _) => def.is_box(),
            _ => false,
        }
    }

    /// Panics if called on any type other than `Box<T>`.
    pub fn boxed_ty(&self) -> Ty<'tcx> {
        match self.kind {
            Adt(def, substs) if def.is_box() => substs.type_at(0),
            _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
        }
    }

    /// A scalar type is one that denotes an atomic datum, with no sub-components.
    /// (A RawPtr is scalar because it represents a non-managed pointer, so its
    /// contents are abstract to rustc.)
    #[inline]
    pub fn is_scalar(&self) -> bool {
        match self.kind {
            Bool
            | Char
            | Int(_)
            | Float(_)
            | Uint(_)
            | Infer(IntVar(_) | FloatVar(_))
            | FnDef(..)
            | FnPtr(_)
            | RawPtr(_) => true,
            _ => false,
        }
    }

    /// Returns `true` if this type is a floating point type.
    #[inline]
    pub fn is_floating_point(&self) -> bool {
        match self.kind {
            Float(_) | Infer(FloatVar(_)) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_trait(&self) -> bool {
        match self.kind {
            Dynamic(..) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_enum(&self) -> bool {
        match self.kind {
            Adt(adt_def, _) => adt_def.is_enum(),
            _ => false,
        }
    }

    #[inline]
    pub fn is_closure(&self) -> bool {
        match self.kind {
            Closure(..) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_generator(&self) -> bool {
        match self.kind {
            Generator(..) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_integral(&self) -> bool {
        match self.kind {
            Infer(IntVar(_)) | Int(_) | Uint(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_fresh_ty(&self) -> bool {
        match self.kind {
            Infer(FreshTy(_)) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_fresh(&self) -> bool {
        match self.kind {
            Infer(FreshTy(_)) => true,
            Infer(FreshIntTy(_)) => true,
            Infer(FreshFloatTy(_)) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_char(&self) -> bool {
        match self.kind {
            Char => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_numeric(&self) -> bool {
        self.is_integral() || self.is_floating_point()
    }

    #[inline]
    pub fn is_signed(&self) -> bool {
        match self.kind {
            Int(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_ptr_sized_integral(&self) -> bool {
        match self.kind {
            Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_machine(&self) -> bool {
        match self.kind {
            Int(..) | Uint(..) | Float(..) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn has_concrete_skeleton(&self) -> bool {
        match self.kind {
            Param(_) | Infer(_) | Error(_) => false,
            _ => true,
        }
    }

    /// Returns the type and mutability of `*ty`.
    ///
    /// The parameter `explicit` indicates if this is an *explicit* dereference.
    /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
    pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
        match self.kind {
            Adt(def, _) if def.is_box() => {
                Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not })
            }
            Ref(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl }),
            RawPtr(mt) if explicit => Some(mt),
            _ => None,
        }
    }

    /// Returns the type of `ty[i]`.
    pub fn builtin_index(&self) -> Option<Ty<'tcx>> {
        match self.kind {
            Array(ty, _) | Slice(ty) => Some(ty),
            _ => None,
        }
    }

    pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
        match self.kind {
            FnDef(def_id, substs) => tcx.fn_sig(def_id).subst(tcx, substs),
            FnPtr(f) => f,
            Error(_) => {
                // ignore errors (#54954)
                ty::Binder::dummy(FnSig::fake())
            }
            Closure(..) => bug!(
                "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
            ),
            _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
        }
    }

    #[inline]
    pub fn is_fn(&self) -> bool {
        match self.kind {
            FnDef(..) | FnPtr(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_fn_ptr(&self) -> bool {
        match self.kind {
            FnPtr(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn is_impl_trait(&self) -> bool {
        match self.kind {
            Opaque(..) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
        match self.kind {
            Adt(adt, _) => Some(adt),
            _ => None,
        }
    }

    /// Iterates over tuple fields.
    /// Panics when called on anything but a tuple.
    pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
        match self.kind {
            Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
            _ => bug!("tuple_fields called on non-tuple"),
        }
    }

    /// If the type contains variants, returns the valid range of variant indices.
    //
    // FIXME: This requires the optimized MIR in the case of generators.
    #[inline]
    pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
        match self.kind {
            TyKind::Adt(adt, _) => Some(adt.variant_range()),
            TyKind::Generator(def_id, substs, _) => {
                Some(substs.as_generator().variant_range(def_id, tcx))
            }
            _ => None,
        }
    }

    /// If the type contains variants, returns the variant for `variant_index`.
    /// Panics if `variant_index` is out of range.
    //
    // FIXME: This requires the optimized MIR in the case of generators.
    #[inline]
    pub fn discriminant_for_variant(
        &self,
        tcx: TyCtxt<'tcx>,
        variant_index: VariantIdx,
    ) -> Option<Discr<'tcx>> {
        match self.kind {
            TyKind::Adt(adt, _) if adt.variants.is_empty() => {
                bug!("discriminant_for_variant called on zero variant enum");
            }
            TyKind::Adt(adt, _) if adt.is_enum() => {
                Some(adt.discriminant_for_variant(tcx, variant_index))
            }
            TyKind::Generator(def_id, substs, _) => {
                Some(substs.as_generator().discriminant_for_variant(def_id, tcx, variant_index))
            }
            _ => None,
        }
    }

    /// Returns the type of the discriminant of this type.
    pub fn discriminant_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
        match self.kind {
            ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx),
            ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
            _ => {
                // This can only be `0`, for now, so `u8` will suffice.
                tcx.types.u8
            }
        }
    }

    /// When we create a closure, we record its kind (i.e., what trait
    /// it implements) into its `ClosureSubsts` using a type
    /// parameter. This is kind of a phantom type, except that the
    /// most convenient thing for us to are the integral types. This
    /// function converts such a special type into the closure
    /// kind. To go the other way, use
    /// `tcx.closure_kind_ty(closure_kind)`.
    ///
    /// Note that during type checking, we use an inference variable
    /// to represent the closure kind, because it has not yet been
    /// inferred. Once upvar inference (in `src/librustc_typeck/check/upvar.rs`)
    /// is complete, that type variable will be unified.
    pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
        match self.kind {
            Int(int_ty) => match int_ty {
                ast::IntTy::I8 => Some(ty::ClosureKind::Fn),
                ast::IntTy::I16 => Some(ty::ClosureKind::FnMut),
                ast::IntTy::I32 => Some(ty::ClosureKind::FnOnce),
                _ => bug!("cannot convert type `{:?}` to a closure kind", self),
            },

            // "Bound" types appear in canonical queries when the
            // closure type is not yet known
            Bound(..) | Infer(_) => None,

            Error(_) => Some(ty::ClosureKind::Fn),

            _ => bug!("cannot convert type `{:?}` to a closure kind", self),
        }
    }

    /// Fast path helper for testing if a type is `Sized`.
    ///
    /// Returning true means the type is known to be sized. Returning
    /// `false` means nothing -- could be sized, might not be.
    pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
        match self.kind {
            ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
            | ty::Uint(_)
            | ty::Int(_)
            | ty::Bool
            | ty::Float(_)
            | ty::FnDef(..)
            | ty::FnPtr(_)
            | ty::RawPtr(..)
            | ty::Char
            | ty::Ref(..)
            | ty::Generator(..)
            | ty::GeneratorWitness(..)
            | ty::Array(..)
            | ty::Closure(..)
            | ty::Never
            | ty::Error(_) => true,

            ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false,

            ty::Tuple(tys) => tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx)),

            ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(),

            ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false,

            ty::Infer(ty::TyVar(_)) => false,

            ty::Bound(..)
            | ty::Placeholder(..)
            | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
                bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
            }
        }
    }

    /// Is this a zero-sized type?
    pub fn is_zst(&'tcx self, tcx: TyCtxt<'tcx>, did: DefId) -> bool {
        tcx.layout_of(tcx.param_env(did).and(self)).map(|layout| layout.is_zst()).unwrap_or(false)
    }
}

/// Typed constant value.
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
#[derive(HashStable)]
pub struct Const<'tcx> {
    pub ty: Ty<'tcx>,

    pub val: ConstKind<'tcx>,
}

#[cfg(target_arch = "x86_64")]
static_assert_size!(Const<'_>, 48);

impl<'tcx> Const<'tcx> {
    /// Literals and const generic parameters are eagerly converted to a constant, everything else
    /// becomes `Unevaluated`.
    pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
        debug!("Const::from_anon_const(id={:?})", def_id);

        let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);

        let body_id = match tcx.hir().get(hir_id) {
            hir::Node::AnonConst(ac) => ac.body,
            _ => span_bug!(
                tcx.def_span(def_id.to_def_id()),
                "from_anon_const can only process anonymous constants"
            ),
        };

        let expr = &tcx.hir().body(body_id).value;

        let ty = tcx.type_of(def_id.to_def_id());

        let lit_input = match expr.kind {
            hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
            hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind {
                hir::ExprKind::Lit(ref lit) => {
                    Some(LitToConstInput { lit: &lit.node, ty, neg: true })
                }
                _ => None,
            },
            _ => None,
        };

        if let Some(lit_input) = lit_input {
            // If an error occurred, ignore that it's a literal and leave reporting the error up to
            // mir.
            if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
                return c;
            } else {
                tcx.sess.delay_span_bug(expr.span, "Const::from_anon_const: couldn't lit_to_const");
            }
        }

        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
        let expr = match &expr.kind {
            hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
                block.expr.as_ref().unwrap()
            }
            _ => expr,
        };

        use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
        let val = match expr.kind {
            ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
                // Find the name and index of the const parameter by indexing the generics of
                // the parent item and construct a `ParamConst`.
                let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
                let item_id = tcx.hir().get_parent_node(hir_id);
                let item_def_id = tcx.hir().local_def_id(item_id);
                let generics = tcx.generics_of(item_def_id.to_def_id());
                let index =
                    generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id).to_def_id()];
                let name = tcx.hir().name(hir_id);
                ty::ConstKind::Param(ty::ParamConst::new(index, name))
            }
            _ => ty::ConstKind::Unevaluated(
                def_id.to_def_id(),
                InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
                None,
            ),
        };

        tcx.mk_const(ty::Const { val, ty })
    }

    #[inline]
    /// Interns the given value as a constant.
    pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
        tcx.mk_const(Self { val: ConstKind::Value(val), ty })
    }

    #[inline]
    /// Interns the given scalar as a constant.
    pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
        Self::from_value(tcx, ConstValue::Scalar(val), ty)
    }

    #[inline]
    /// Creates a constant with the given integer value and interns it.
    pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx Self {
        let size = tcx
            .layout_of(ty)
            .unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
            .size;
        Self::from_scalar(tcx, Scalar::from_uint(bits, size), ty.value)
    }

    #[inline]
    /// Creates an interned zst constant.
    pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
        Self::from_scalar(tcx, Scalar::zst(), ty)
    }

    #[inline]
    /// Creates an interned bool constant.
    pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> &'tcx Self {
        Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
    }

    #[inline]
    /// Creates an interned usize constant.
    pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> &'tcx Self {
        Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
    }

    #[inline]
    /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
    /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
    /// contains const generic parameters or pointers).
    pub fn try_eval_bits(
        &self,
        tcx: TyCtxt<'tcx>,
        param_env: ParamEnv<'tcx>,
        ty: Ty<'tcx>,
    ) -> Option<u128> {
        assert_eq!(self.ty, ty);
        let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
        // if `ty` does not depend on generic parameters, use an empty param_env
        self.eval(tcx, param_env).val.try_to_bits(size)
    }

    #[inline]
    /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
    /// unevaluated constant.
    pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
        if let ConstKind::Unevaluated(did, substs, promoted) = self.val {
            use crate::mir::interpret::ErrorHandled;

            let param_env_and_substs = param_env.with_reveal_all().and(substs);

            // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
            // also does later, but we want to do it before checking for
            // inference variables.
            let param_env_and_substs = tcx.erase_regions(&param_env_and_substs);

            // HACK(eddyb) when the query key would contain inference variables,
            // attempt using identity substs and `ParamEnv` instead, that will succeed
            // when the expression doesn't depend on any parameters.
            // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
            // we can call `infcx.const_eval_resolve` which handles inference variables.
            let param_env_and_substs = if param_env_and_substs.needs_infer() {
                tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did))
            } else {
                param_env_and_substs
            };

            // FIXME(eddyb) maybe the `const_eval_*` methods should take
            // `ty::ParamEnvAnd<SubstsRef>` instead of having them separate.
            let (param_env, substs) = param_env_and_substs.into_parts();
            // try to resolve e.g. associated constants to their definition on an impl, and then
            // evaluate the const.
            match tcx.const_eval_resolve(param_env, did, substs, promoted, None) {
                // NOTE(eddyb) `val` contains no lifetimes/types/consts,
                // and we use the original type, so nothing from `substs`
                // (which may be identity substs, see above),
                // can leak through `val` into the const we return.
                Ok(val) => Const::from_value(tcx, val, self.ty),
                Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self,
                Err(ErrorHandled::Reported(ErrorReported)) => tcx.const_error(self.ty),
            }
        } else {
            self
        }
    }

    #[inline]
    pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
        self.try_eval_bits(tcx, param_env, tcx.types.bool).and_then(|v| match v {
            0 => Some(false),
            1 => Some(true),
            _ => None,
        })
    }

    #[inline]
    pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
        self.try_eval_bits(tcx, param_env, tcx.types.usize).map(|v| v as u64)
    }

    #[inline]
    /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
    pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
        self.try_eval_bits(tcx, param_env, ty)
            .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
    }

    #[inline]
    /// Panics if the value cannot be evaluated or doesn't contain a valid `usize`.
    pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
        self.eval_bits(tcx, param_env, tcx.types.usize) as u64
    }
}

/// Represents a constant in Rust.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
#[derive(HashStable)]
pub enum ConstKind<'tcx> {
    /// A const generic parameter.
    Param(ParamConst),

    /// Infer the value of the const.
    Infer(InferConst<'tcx>),

    /// Bound const variable, used only when preparing a trait query.
    Bound(DebruijnIndex, BoundVar),

    /// A placeholder const - universally quantified higher-ranked const.
    Placeholder(ty::PlaceholderConst),

    /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
    /// variants when the code is monomorphic enough for that.
    Unevaluated(DefId, SubstsRef<'tcx>, Option<Promoted>),

    /// Used to hold computed value.
    Value(ConstValue<'tcx>),

    /// A placeholder for a const which could not be computed; this is
    /// propagated to avoid useless error messages.
    Error(DelaySpanBugEmitted),
}

#[cfg(target_arch = "x86_64")]
static_assert_size!(ConstKind<'_>, 40);

impl<'tcx> ConstKind<'tcx> {
    #[inline]
    pub fn try_to_scalar(&self) -> Option<Scalar> {
        if let ConstKind::Value(val) = self { val.try_to_scalar() } else { None }
    }

    #[inline]
    pub fn try_to_bits(&self, size: Size) -> Option<u128> {
        if let ConstKind::Value(val) = self { val.try_to_bits(size) } else { None }
    }
}

/// An inference variable for a const, for use in const generics.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
#[derive(HashStable)]
pub enum InferConst<'tcx> {
    /// Infer the value of the const.
    Var(ConstVid<'tcx>),
    /// A fresh const variable. See `infer::freshen` for more details.
    Fresh(u32),
}
