Rewrite fixTvSubstEnv so it iteratively applies its substition
authorIan Lynagh <igloo@earth.li>
Wed, 20 Feb 2008 15:37:52 +0000 (15:37 +0000)
committerIan Lynagh <igloo@earth.li>
Wed, 20 Feb 2008 15:37:52 +0000 (15:37 +0000)
This fixes a stack overflow when using strict UniqFMs. It might be
possible to rewrite it more efficiently, or to avoid needing it in the
first place.

compiler/typecheck/TcGadt.lhs

index b556e89..48b2b06 100644 (file)
@@ -237,11 +237,15 @@ fixTvCoEnv in_scope env
       -- then use transitivity with the original coercion
 
 -----------------------------
+-- XXX Can we do this more nicely, by exploiting laziness?
+-- Or avoid needing it in the first place?
 fixTvSubstEnv :: InScopeSet -> TvSubstEnv -> TvSubstEnv
-fixTvSubstEnv in_scope env
-  = fixpt 
+fixTvSubstEnv in_scope env = f env
   where
-    fixpt = mapVarEnv (substTy (mkTvSubst in_scope fixpt)) env
+    f e = let e' = mapUFM (substTy (mkTvSubst in_scope e)) e
+          in if and $ eltsUFM $ intersectUFM_C tcEqType e e'
+             then e
+             else f e'
 
 ----------------------------
 tryToBind :: TyVarSet -> TyVar -> BindFlag