-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{self, Ty, TyCtxt, InferConst};
use crate::ty::error::TypeError;
use crate::ty::relate::{self, Relate, TypeRelation, RelateResult};
+use crate::mir::interpret::ConstValue;
/// A type "A" *matches* "B" if the fresh types in B could be
/// substituted with values so as to make it equal to A. Matching is
/// Like subtyping, matching is really a binary relation, so the only
/// important thing about the result is Ok/Err. Also, matching never
/// affects any type variables or unification state.
-pub struct Match<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
- tcx: TyCtxt<'a, 'gcx, 'tcx>
+pub struct Match<'gcx, 'tcx> {
+ tcx: TyCtxt<'gcx, 'tcx>,
}
-impl<'a, 'gcx, 'tcx> Match<'a, 'gcx, 'tcx> {
- pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Match<'a, 'gcx, 'tcx> {
+impl Match<'gcx, 'tcx> {
+ pub fn new(tcx: TyCtxt<'gcx, 'tcx>) -> Match<'gcx, 'tcx> {
Match { tcx }
}
}
-impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> {
+impl TypeRelation<'gcx, 'tcx> for Match<'gcx, 'tcx> {
fn tag(&self) -> &'static str { "Match" }
- fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.tcx }
+ fn tcx(&self) -> TyCtxt<'gcx, 'tcx> { self.tcx }
fn a_is_expected(&self) -> bool { true } // irrelevant
fn relate_with_variance<T: Relate<'tcx>>(&mut self,
}
}
+ fn consts(
+ &mut self,
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
+ debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
+ if a == b {
+ return Ok(a);
+ }
+
+ match (a.val, b.val) {
+ (_, ConstValue::Infer(InferConst::Fresh(_))) => {
+ return Ok(a);
+ }
+
+ (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
+ return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
+ }
+
+ _ => {}
+ }
+
+ relate::super_relate_consts(self, a, b)
+ }
+
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> RelateResult<'tcx, ty::Binder<T>>
where T: Relate<'tcx>