]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_middle/src/ty/relate.rs
Optimize relate_substs by extracting match
[rust.git] / compiler / rustc_middle / src / ty / relate.rs
index 81ee7942c4d3452da10a4c0d61b61493e2837f4f..b1cfa3fa96433ef4a068ab959ae3acdc53599f42 100644 (file)
@@ -7,7 +7,7 @@
 use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar};
 use crate::ty::error::{ExpectedFound, TypeError};
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
-use crate::ty::{self, Term, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, ImplSubject, Term, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as ast;
 use rustc_hir::def_id::DefId;
 use rustc_span::DUMMY_SP;
@@ -142,11 +142,12 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
     b_subst: SubstsRef<'tcx>,
 ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
     let tcx = relation.tcx();
-    let mut cached_ty = None;
 
-    let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| {
-        let (variance, variance_info) = match variances {
-            Some((ty_def_id, variances)) => {
+    let zipped = iter::zip(a_subst, b_subst);
+    match variances {
+        Some((ty_def_id, variances)) => {
+            let mut cached_ty = None;
+            tcx.mk_substs(zipped.enumerate().map(|(i, (a, b))| {
                 let variance = variances[i];
                 let variance_info = if variance == ty::Invariant {
                     let ty = *cached_ty
@@ -155,14 +156,13 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
                 } else {
                     ty::VarianceDiagInfo::default()
                 };
-                (variance, variance_info)
-            }
-            None => (ty::Invariant, ty::VarianceDiagInfo::default()),
-        };
-        relation.relate_with_variance(variance, variance_info, a, b)
-    });
-
-    tcx.mk_substs(params)
+                relation.relate_with_variance(variance, variance_info, a, b)
+            }))
+        }
+        None => tcx.mk_substs(zipped.map(|(a, b)| {
+            relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
+        })),
+    }
 }
 
 impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
@@ -356,6 +356,30 @@ fn relate<R: TypeRelation<'tcx>>(
     }
 }
 
+impl<'tcx> Relate<'tcx> for ImplSubject<'tcx> {
+    #[inline]
+    fn relate<R: TypeRelation<'tcx>>(
+        relation: &mut R,
+        a: ImplSubject<'tcx>,
+        b: ImplSubject<'tcx>,
+    ) -> RelateResult<'tcx, ImplSubject<'tcx>> {
+        match (a, b) {
+            (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => {
+                let trait_ref = ty::TraitRef::relate(relation, trait_ref_a, trait_ref_b)?;
+                Ok(ImplSubject::Trait(trait_ref))
+            }
+            (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => {
+                let ty = Ty::relate(relation, ty_a, ty_b)?;
+                Ok(ImplSubject::Inherent(ty))
+            }
+            (ImplSubject::Trait(_), ImplSubject::Inherent(_))
+            | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => {
+                bug!("can not relate TraitRef and Ty");
+            }
+        }
+    }
+}
+
 impl<'tcx> Relate<'tcx> for Ty<'tcx> {
     #[inline]
     fn relate<R: TypeRelation<'tcx>>(
@@ -585,7 +609,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
         (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
             if tcx.features().generic_const_exprs =>
         {
-            tcx.try_unify_abstract_consts((au.shrink(), bu.shrink()))
+            tcx.try_unify_abstract_consts(relation.param_env().and((au.shrink(), bu.shrink())))
         }
 
         // While this is slightly incorrect, it shouldn't matter for `min_const_generics`