//! A nice interface for working with the infcx. The basic idea is to
//! do `infcx.at(cause, param_env)`, which sets the "cause" of the
//! operation as well as the surrounding parameter environment. Then
//! you can do something like `.sub(a, b)` or `.eq(a, b)` to create a
//! subtype or equality relationship respectively. The first argument
//! is always the "expected" output from the POV of diagnostics.
//!
//! Examples:
//!
//!     infcx.at(cause, param_env).sub(a, b)
//!     // requires that `a <: b`, with `a` considered the "expected" type
//!
//!     infcx.at(cause, param_env).sup(a, b)
//!     // requires that `b <: a`, with `a` considered the "expected" type
//!
//!     infcx.at(cause, param_env).eq(a, b)
//!     // requires that `a == b`, with `a` considered the "expected" type
//!
//! For finer-grained control, you can also do use `trace`:
//!
//!     infcx.at(...).trace(a, b).sub(&c, &d)
//!
//! This will set `a` and `b` as the "root" values for
//! error-reporting, but actually operate on `c` and `d`. This is
//! sometimes useful when the types of `c` and `d` are not traceable
//! things. (That system should probably be refactored.)

use super::*;

use crate::ty::Const;
use crate::ty::relate::{Relate, TypeRelation};

pub struct At<'a, 'tcx: 'a> {
    pub infcx: &'a InferCtxt<'a, 'tcx>,
    pub cause: &'a ObligationCause<'tcx>,
    pub param_env: ty::ParamEnv<'tcx>,
}

pub struct Trace<'a, 'tcx: 'a> {
    at: At<'a, 'tcx>,
    a_is_expected: bool,
    trace: TypeTrace<'tcx>,
}

impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
    #[inline]
    pub fn at(
        &'a self,
        cause: &'a ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
    ) -> At<'a, 'tcx> {
        At { infcx: self, cause, param_env }
    }
}

pub trait ToTrace<'tcx>: Relate<'tcx> + Copy {
    fn to_trace(cause: &ObligationCause<'tcx>,
                a_is_expected: bool,
                a: Self,
                b: Self)
                -> TypeTrace<'tcx>;
}

impl<'a, 'tcx> At<'a, 'tcx> {
    /// Hacky routine for equating two impl headers in coherence.
    pub fn eq_impl_headers(self,
                           expected: &ty::ImplHeader<'tcx>,
                           actual: &ty::ImplHeader<'tcx>)
                           -> InferResult<'tcx, ()>
    {
        debug!("eq_impl_header({:?} = {:?})", expected, actual);
        match (expected.trait_ref, actual.trait_ref) {
            (Some(a_ref), Some(b_ref)) =>
                self.eq(a_ref, b_ref),
            (None, None) =>
                self.eq(expected.self_ty, actual.self_ty),
            _ =>
                bug!("mk_eq_impl_headers given mismatched impl kinds"),
        }
    }

    /// Makes `a <: b`, where `a` may or may not be expected.
    pub fn sub_exp<T>(self,
                      a_is_expected: bool,
                      a: T,
                      b: T)
                      -> InferResult<'tcx, ()>
        where T: ToTrace<'tcx>
    {
        self.trace_exp(a_is_expected, a, b).sub(&a, &b)
    }

    /// Makes `actual <: expected`. For example, if type-checking a
    /// call like `foo(x)`, where `foo: fn(i32)`, you might have
    /// `sup(i32, x)`, since the "expected" type is the type that
    /// appears in the signature.
    pub fn sup<T>(self,
                  expected: T,
                  actual: T)
                  -> InferResult<'tcx, ()>
        where T: ToTrace<'tcx>
    {
        self.sub_exp(false, actual, expected)
    }

    /// Makes `expected <: actual`.
    pub fn sub<T>(self,
                  expected: T,
                  actual: T)
                  -> InferResult<'tcx, ()>
        where T: ToTrace<'tcx>
    {
        self.sub_exp(true, expected, actual)
    }

    /// Makes `expected <: actual`.
    pub fn eq_exp<T>(self,
                     a_is_expected: bool,
                     a: T,
                     b: T)
                     -> InferResult<'tcx, ()>
        where T: ToTrace<'tcx>
    {
        self.trace_exp(a_is_expected, a, b).eq(&a, &b)
    }

    /// Makes `expected <: actual`.
    pub fn eq<T>(self,
                 expected: T,
                 actual: T)
                 -> InferResult<'tcx, ()>
        where T: ToTrace<'tcx>
    {
        self.trace(expected, actual).eq(&expected, &actual)
    }

    pub fn relate<T>(
        self,
        expected: T,
        variance: ty::Variance,
        actual: T,
    ) -> InferResult<'tcx, ()>
        where T: ToTrace<'tcx>
    {
        match variance {
            ty::Variance::Covariant => self.sub(expected, actual),
            ty::Variance::Invariant => self.eq(expected, actual),
            ty::Variance::Contravariant => self.sup(expected, actual),

            // We could make this make sense but it's not readily
            // exposed and I don't feel like dealing with it. Note
            // that bivariance in general does a bit more than just
            // *nothing*, it checks that the types are the same
            // "modulo variance" basically.
            ty::Variance::Bivariant => panic!("Bivariant given to `relate()`"),
        }
    }

    /// Computes the least-upper-bound, or mutual supertype, of two
    /// values. The order of the arguments doesn't matter, but since
    /// this can result in an error (e.g., if asked to compute LUB of
    /// u32 and i32), it is meaningful to call one of them the
    /// "expected type".
    pub fn lub<T>(self,
                  expected: T,
                  actual: T)
                  -> InferResult<'tcx, T>
        where T: ToTrace<'tcx>
    {
        self.trace(expected, actual).lub(&expected, &actual)
    }

    /// Computes the greatest-lower-bound, or mutual subtype, of two
    /// values. As with `lub` order doesn't matter, except for error
    /// cases.
    pub fn glb<T>(self,
                  expected: T,
                  actual: T)
                  -> InferResult<'tcx, T>
        where T: ToTrace<'tcx>
    {
        self.trace(expected, actual).glb(&expected, &actual)
    }

    /// Sets the "trace" values that will be used for
    /// error-reporting, but doesn't actually perform any operation
    /// yet (this is useful when you want to set the trace using
    /// distinct values from those you wish to operate upon).
    pub fn trace<T>(self, expected: T, actual: T) -> Trace<'a, 'tcx>
    where
        T: ToTrace<'tcx>,
    {
        self.trace_exp(true, expected, actual)
    }

    /// Like `trace`, but the expected value is determined by the
    /// boolean argument (if true, then the first argument `a` is the
    /// "expected" value).
    pub fn trace_exp<T>(self, a_is_expected: bool, a: T, b: T) -> Trace<'a, 'tcx>
    where
        T: ToTrace<'tcx>,
    {
        let trace = ToTrace::to_trace(self.cause, a_is_expected, a, b);
        Trace { at: self, trace: trace, a_is_expected }
    }
}

impl<'a, 'tcx> Trace<'a, 'tcx> {
    /// Makes `a <: b` where `a` may or may not be expected (if
    /// `a_is_expected` is true, then `a` is expected).
    /// Makes `expected <: actual`.
    pub fn sub<T>(self,
                  a: &T,
                  b: &T)
                  -> InferResult<'tcx, ()>
        where T: Relate<'tcx>
    {
        debug!("sub({:?} <: {:?})", a, b);
        let Trace { at, trace, a_is_expected } = self;
        at.infcx.commit_if_ok(|_| {
            let mut fields = at.infcx.combine_fields(trace, at.param_env);
            fields.sub(a_is_expected)
                  .relate(a, b)
                  .map(move |_| InferOk { value: (), obligations: fields.obligations })
        })
    }

    /// Makes `a == b`; the expectation is set by the call to
    /// `trace()`.
    pub fn eq<T>(self,
                 a: &T,
                 b: &T)
                 -> InferResult<'tcx, ()>
        where T: Relate<'tcx>
    {
        debug!("eq({:?} == {:?})", a, b);
        let Trace { at, trace, a_is_expected } = self;
        at.infcx.commit_if_ok(|_| {
            let mut fields = at.infcx.combine_fields(trace, at.param_env);
            fields.equate(a_is_expected)
                  .relate(a, b)
                  .map(move |_| InferOk { value: (), obligations: fields.obligations })
        })
    }

    pub fn lub<T>(self,
                  a: &T,
                  b: &T)
                  -> InferResult<'tcx, T>
        where T: Relate<'tcx>
    {
        debug!("lub({:?} \\/ {:?})", a, b);
        let Trace { at, trace, a_is_expected } = self;
        at.infcx.commit_if_ok(|_| {
            let mut fields = at.infcx.combine_fields(trace, at.param_env);
            fields.lub(a_is_expected)
                  .relate(a, b)
                  .map(move |t| InferOk { value: t, obligations: fields.obligations })
        })
    }

    pub fn glb<T>(self,
                  a: &T,
                  b: &T)
                  -> InferResult<'tcx, T>
        where T: Relate<'tcx>
    {
        debug!("glb({:?} /\\ {:?})", a, b);
        let Trace { at, trace, a_is_expected } = self;
        at.infcx.commit_if_ok(|_| {
            let mut fields = at.infcx.combine_fields(trace, at.param_env);
            fields.glb(a_is_expected)
                  .relate(a, b)
                  .map(move |t| InferOk { value: t, obligations: fields.obligations })
        })
    }
}

impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
    fn to_trace(cause: &ObligationCause<'tcx>,
                a_is_expected: bool,
                a: Self,
                b: Self)
                -> TypeTrace<'tcx>
    {
        TypeTrace {
            cause: cause.clone(),
            values: Types(ExpectedFound::new(a_is_expected, a, b))
        }
    }
}

impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
    fn to_trace(cause: &ObligationCause<'tcx>,
                a_is_expected: bool,
                a: Self,
                b: Self)
                -> TypeTrace<'tcx>
    {
        TypeTrace {
            cause: cause.clone(),
            values: Regions(ExpectedFound::new(a_is_expected, a, b))
        }
    }
}

impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
    fn to_trace(cause: &ObligationCause<'tcx>,
                a_is_expected: bool,
                a: Self,
                b: Self)
                -> TypeTrace<'tcx>
    {
        TypeTrace {
            cause: cause.clone(),
            values: Consts(ExpectedFound::new(a_is_expected, a, b))
        }
    }
}

impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
    fn to_trace(cause: &ObligationCause<'tcx>,
                a_is_expected: bool,
                a: Self,
                b: Self)
                -> TypeTrace<'tcx>
    {
        TypeTrace {
            cause: cause.clone(),
            values: TraitRefs(ExpectedFound::new(a_is_expected, a, b))
        }
    }
}

impl<'tcx> ToTrace<'tcx> for ty::PolyTraitRef<'tcx> {
    fn to_trace(cause: &ObligationCause<'tcx>,
                a_is_expected: bool,
                a: Self,
                b: Self)
                -> TypeTrace<'tcx>
    {
        TypeTrace {
            cause: cause.clone(),
            values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b))
        }
    }
}
