use ty::relate::{Relate, TypeRelation};
pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
- infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
- cause: &'a ObligationCause<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
+ pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+ pub cause: &'a ObligationCause<'tcx>,
+ pub param_env: ty::ParamEnv<'tcx>,
}
pub struct Trace<'a, 'gcx: 'tcx, 'tcx: 'a> {
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()`"),
+ }
+ }
+
/// Compute 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
}
/// Sets the "trace" values that will be used for
- /// error-repporting, but doesn't actually perform any operation
+ /// 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,
}
}
+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 ty::TraitRef<'tcx> {
fn to_trace(cause: &ObligationCause<'tcx>,
a_is_expected: bool,