- tvs1 = tyVarsOfTypes tys1
- tvs2 = tyVarsOfTypes tys2
-
-----------------------------
--- 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 = f env
+ f e | not_fixpoint = f (mapVarEnv (substTy subst) e)
+ | otherwise = subst
+ where
+ range_tvs = foldVarEnv (unionVarSet . tyVarsOfType) emptyVarSet e
+ subst = mkTvSubst (mkInScopeSet range_tvs) e
+ not_fixpoint = foldVarSet ((||) . in_domain) False range_tvs
+ in_domain tv = tv `elemVarEnv` e
+
+niSubstTvSet :: TvSubstEnv -> TyVarSet -> TyVarSet
+-- Apply the non-idempotent substitution to a set of type variables,
+-- remembering that the substitution isn't necessarily idempotent
+-- This is used in the occurs check, before extending the substitution
+niSubstTvSet subst tvs
+ = foldVarSet (unionVarSet . get) emptyVarSet tvs