From f386ccc956ce038d03113215493e27b957d586c4 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 3 Mar 2016 10:43:52 +0100 Subject: [PATCH] Avoid adding duplicate relations during inference This reduces the amount of redundant equivalence checks for programs which use associated types in combination with deeply nested types. As an example this brings down the compilation times of tests in `combine` from 9m32s to 6m44s. --- src/librustc/middle/infer/type_variable.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs index e4af098c2a42d..6924804c10eb4 100644 --- a/src/librustc/middle/infer/type_variable.rs +++ b/src/librustc/middle/infer/type_variable.rs @@ -104,9 +104,13 @@ impl<'tcx> TypeVariableTable<'tcx> { /// Precondition: neither `a` nor `b` are known. pub fn relate_vars(&mut self, a: ty::TyVid, dir: RelationDir, b: ty::TyVid) { if a != b { - self.relations(a).push((dir, b)); - self.relations(b).push((dir.opposite(), a)); - self.values.record(Relate(a, b)); + let new_rel = (dir, b); + // Don't add duplicate relations + if self.relations(a).iter().all(|rel| *rel != new_rel) { + self.relations(a).push(new_rel); + self.relations(b).push((dir.opposite(), a)); + self.values.record(Relate(a, b)); + } } } @@ -130,7 +134,8 @@ impl<'tcx> TypeVariableTable<'tcx> { already instantiated") }; - for &(dir, vid) in &relations { + // Variables which have already been proven to be `ty` does not need to be checked again + for &(dir, vid) in relations.iter().filter(|& &(_, vid)| self.probe(vid) != Some(ty)) { stack.push((ty, dir, vid)); }