]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/ty/_match.rs
Run `rustfmt --file-lines ...` for changes from previous commits.
[rust.git] / src / librustc / ty / _match.rs
index 07fa441bb8076e3cce51f434ef33e1e98a2ce14a..213f556f9acac168244fa3d2c6b40ddcb23a59e0 100644 (file)
@@ -1,6 +1,7 @@
-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,
@@ -78,6 +79,31 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         }
     }
 
+    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>