module TyCoFVs
(
tyCoVarsOfType, tyCoVarsOfTypeDSet, tyCoVarsOfTypes, tyCoVarsOfTypesDSet,
exactTyCoVarsOfType, exactTyCoVarsOfTypes,
tyCoFVsBndr, tyCoFVsVarBndr, tyCoFVsVarBndrs,
tyCoFVsOfType, tyCoVarsOfTypeList,
tyCoFVsOfTypes, tyCoVarsOfTypesList,
tyCoVarsOfTypesSet, tyCoVarsOfCosSet,
coVarsOfType, coVarsOfTypes,
coVarsOfCo, coVarsOfCos,
tyCoVarsOfCo, tyCoVarsOfCos,
tyCoVarsOfCoDSet,
tyCoFVsOfCo, tyCoFVsOfCos,
tyCoVarsOfCoList, tyCoVarsOfProv,
almostDevoidCoVarOfCo,
injectiveVarsOfType, injectiveVarsOfTypes,
invisibleVarsOfType, invisibleVarsOfTypes,
noFreeVarsOfType, noFreeVarsOfTypes, noFreeVarsOfCo,
mkTyCoInScopeSet,
scopedSort, tyCoVarsOfTypeWellScoped,
tyCoVarsOfTypesWellScoped,
) where
import GhcPrelude
import Type (coreView, tcView, partitionInvisibleTypes)
import TyCoRep
import TyCon
import Var
import FV
import UniqFM
import VarSet
import VarEnv
import Util
import Panic
tyCoVarsOfType :: Type -> TyCoVarSet
tyCoVarsOfType ty = ty_co_vars_of_type ty emptyVarSet emptyVarSet
tyCoVarsOfTypes :: [Type] -> TyCoVarSet
tyCoVarsOfTypes tys = ty_co_vars_of_types tys emptyVarSet emptyVarSet
ty_co_vars_of_type :: Type -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_type (TyVarTy v) is acc
| v `elemVarSet` is = acc
| v `elemVarSet` acc = acc
| otherwise = ty_co_vars_of_type (tyVarKind v)
emptyVarSet
(extendVarSet acc v)
ty_co_vars_of_type (TyConApp _ tys) is acc = ty_co_vars_of_types tys is acc
ty_co_vars_of_type (LitTy {}) _ acc = acc
ty_co_vars_of_type (AppTy fun arg) is acc = ty_co_vars_of_type fun is (ty_co_vars_of_type arg is acc)
ty_co_vars_of_type (FunTy _ arg res) is acc = ty_co_vars_of_type arg is (ty_co_vars_of_type res is acc)
ty_co_vars_of_type (ForAllTy (Bndr tv _) ty) is acc = ty_co_vars_of_type (varType tv) is $
ty_co_vars_of_type ty (extendVarSet is tv) acc
ty_co_vars_of_type (CastTy ty co) is acc = ty_co_vars_of_type ty is (ty_co_vars_of_co co is acc)
ty_co_vars_of_type (CoercionTy co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_types :: [Type] -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_types [] _ acc = acc
ty_co_vars_of_types (ty:tys) is acc = ty_co_vars_of_type ty is (ty_co_vars_of_types tys is acc)
tyCoVarsOfCo :: Coercion -> TyCoVarSet
tyCoVarsOfCo co = ty_co_vars_of_co co emptyVarSet emptyVarSet
tyCoVarsOfCos :: [Coercion] -> TyCoVarSet
tyCoVarsOfCos cos = ty_co_vars_of_cos cos emptyVarSet emptyVarSet
ty_co_vars_of_co :: Coercion -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_co (Refl ty) is acc = ty_co_vars_of_type ty is acc
ty_co_vars_of_co (GRefl _ ty mco) is acc = ty_co_vars_of_type ty is $
ty_co_vars_of_mco mco is acc
ty_co_vars_of_co (TyConAppCo _ _ cos) is acc = ty_co_vars_of_cos cos is acc
ty_co_vars_of_co (AppCo co arg) is acc = ty_co_vars_of_co co is $
ty_co_vars_of_co arg is acc
ty_co_vars_of_co (ForAllCo tv kind_co co) is acc = ty_co_vars_of_co kind_co is $
ty_co_vars_of_co co (extendVarSet is tv) acc
ty_co_vars_of_co (FunCo _ co1 co2) is acc = ty_co_vars_of_co co1 is $
ty_co_vars_of_co co2 is acc
ty_co_vars_of_co (CoVarCo v) is acc = ty_co_vars_of_co_var v is acc
ty_co_vars_of_co (HoleCo h) is acc = ty_co_vars_of_co_var (coHoleCoVar h) is acc
ty_co_vars_of_co (AxiomInstCo _ _ cos) is acc = ty_co_vars_of_cos cos is acc
ty_co_vars_of_co (UnivCo p _ t1 t2) is acc = ty_co_vars_of_prov p is $
ty_co_vars_of_type t1 is $
ty_co_vars_of_type t2 is acc
ty_co_vars_of_co (SymCo co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_co (TransCo co1 co2) is acc = ty_co_vars_of_co co1 is $
ty_co_vars_of_co co2 is acc
ty_co_vars_of_co (NthCo _ _ co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_co (LRCo _ co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_co (InstCo co arg) is acc = ty_co_vars_of_co co is $
ty_co_vars_of_co arg is acc
ty_co_vars_of_co (KindCo co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_co (SubCo co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_co (AxiomRuleCo _ cs) is acc = ty_co_vars_of_cos cs is acc
ty_co_vars_of_mco :: MCoercion -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_mco MRefl _is acc = acc
ty_co_vars_of_mco (MCo co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_co_var :: CoVar -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_co_var v is acc
| v `elemVarSet` is = acc
| v `elemVarSet` acc = acc
| otherwise = ty_co_vars_of_type (varType v)
emptyVarSet
(extendVarSet acc v)
ty_co_vars_of_cos :: [Coercion] -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_cos [] _ acc = acc
ty_co_vars_of_cos (co:cos) is acc = ty_co_vars_of_co co is (ty_co_vars_of_cos cos is acc)
tyCoVarsOfProv :: UnivCoProvenance -> TyCoVarSet
tyCoVarsOfProv prov = ty_co_vars_of_prov prov emptyVarSet emptyVarSet
ty_co_vars_of_prov :: UnivCoProvenance -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_prov (PhantomProv co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_prov (ProofIrrelProv co) is acc = ty_co_vars_of_co co is acc
ty_co_vars_of_prov UnsafeCoerceProv _ acc = acc
ty_co_vars_of_prov (PluginProv _) _ acc = acc
mkTyCoInScopeSet :: [Type] -> [Coercion] -> InScopeSet
mkTyCoInScopeSet tys cos
= mkInScopeSet (ty_co_vars_of_types tys emptyVarSet $
ty_co_vars_of_cos cos emptyVarSet emptyVarSet)
tyCoVarsOfTypeDSet :: Type -> DTyCoVarSet
tyCoVarsOfTypeDSet ty = fvDVarSet $ tyCoFVsOfType ty
tyCoVarsOfTypeList :: Type -> [TyCoVar]
tyCoVarsOfTypeList ty = fvVarList $ tyCoFVsOfType ty
tyCoVarsOfTypesSet :: TyVarEnv Type -> TyCoVarSet
tyCoVarsOfTypesSet tys = tyCoVarsOfTypes $ nonDetEltsUFM tys
tyCoVarsOfTypesDSet :: [Type] -> DTyCoVarSet
tyCoVarsOfTypesDSet tys = fvDVarSet $ tyCoFVsOfTypes tys
tyCoVarsOfTypesList :: [Type] -> [TyCoVar]
tyCoVarsOfTypesList tys = fvVarList $ tyCoFVsOfTypes tys
exactTyCoVarsOfType :: Type -> TyCoVarSet
exactTyCoVarsOfType ty
= go ty
where
go ty | Just ty' <- tcView ty = go ty'
go (TyVarTy tv) = goVar tv
go (TyConApp _ tys) = exactTyCoVarsOfTypes tys
go (LitTy {}) = emptyVarSet
go (AppTy fun arg) = go fun `unionVarSet` go arg
go (FunTy _ arg res) = go arg `unionVarSet` go res
go (ForAllTy bndr ty) = delBinderVar (go ty) bndr `unionVarSet` go (binderType bndr)
go (CastTy ty co) = go ty `unionVarSet` goCo co
go (CoercionTy co) = goCo co
goMCo MRefl = emptyVarSet
goMCo (MCo co) = goCo co
goCo (Refl ty) = go ty
goCo (GRefl _ ty mco) = go ty `unionVarSet` goMCo mco
goCo (TyConAppCo _ _ args)= goCos args
goCo (AppCo co arg) = goCo co `unionVarSet` goCo arg
goCo (ForAllCo tv k_co co)
= goCo co `delVarSet` tv `unionVarSet` goCo k_co
goCo (FunCo _ co1 co2) = goCo co1 `unionVarSet` goCo co2
goCo (CoVarCo v) = goVar v
goCo (HoleCo h) = goVar (coHoleCoVar h)
goCo (AxiomInstCo _ _ args) = goCos args
goCo (UnivCo p _ t1 t2) = goProv p `unionVarSet` go t1 `unionVarSet` go t2
goCo (SymCo co) = goCo co
goCo (TransCo co1 co2) = goCo co1 `unionVarSet` goCo co2
goCo (NthCo _ _ co) = goCo co
goCo (LRCo _ co) = goCo co
goCo (InstCo co arg) = goCo co `unionVarSet` goCo arg
goCo (KindCo co) = goCo co
goCo (SubCo co) = goCo co
goCo (AxiomRuleCo _ c) = goCos c
goCos cos = foldr (unionVarSet . goCo) emptyVarSet cos
goProv UnsafeCoerceProv = emptyVarSet
goProv (PhantomProv kco) = goCo kco
goProv (ProofIrrelProv kco) = goCo kco
goProv (PluginProv _) = emptyVarSet
goVar v = unitVarSet v `unionVarSet` go (varType v)
exactTyCoVarsOfTypes :: [Type] -> TyVarSet
exactTyCoVarsOfTypes tys = mapUnionVarSet exactTyCoVarsOfType tys
tyCoFVsOfType :: Type -> FV
tyCoFVsOfType (TyVarTy v) f bound_vars (acc_list, acc_set)
| not (f v) = (acc_list, acc_set)
| v `elemVarSet` bound_vars = (acc_list, acc_set)
| v `elemVarSet` acc_set = (acc_list, acc_set)
| otherwise = tyCoFVsOfType (tyVarKind v) f
emptyVarSet
(v:acc_list, extendVarSet acc_set v)
tyCoFVsOfType (TyConApp _ tys) f bound_vars acc = tyCoFVsOfTypes tys f bound_vars acc
tyCoFVsOfType (LitTy {}) f bound_vars acc = emptyFV f bound_vars acc
tyCoFVsOfType (AppTy fun arg) f bound_vars acc = (tyCoFVsOfType fun `unionFV` tyCoFVsOfType arg) f bound_vars acc
tyCoFVsOfType (FunTy _ arg res) f bound_vars acc = (tyCoFVsOfType arg `unionFV` tyCoFVsOfType res) f bound_vars acc
tyCoFVsOfType (ForAllTy bndr ty) f bound_vars acc = tyCoFVsBndr bndr (tyCoFVsOfType ty) f bound_vars acc
tyCoFVsOfType (CastTy ty co) f bound_vars acc = (tyCoFVsOfType ty `unionFV` tyCoFVsOfCo co) f bound_vars acc
tyCoFVsOfType (CoercionTy co) f bound_vars acc = tyCoFVsOfCo co f bound_vars acc
tyCoFVsBndr :: TyCoVarBinder -> FV -> FV
tyCoFVsBndr (Bndr tv _) fvs = tyCoFVsVarBndr tv fvs
tyCoFVsVarBndrs :: [Var] -> FV -> FV
tyCoFVsVarBndrs vars fvs = foldr tyCoFVsVarBndr fvs vars
tyCoFVsVarBndr :: Var -> FV -> FV
tyCoFVsVarBndr var fvs
= tyCoFVsOfType (varType var)
`unionFV` delFV var fvs
tyCoFVsOfTypes :: [Type] -> FV
tyCoFVsOfTypes (ty:tys) fv_cand in_scope acc = (tyCoFVsOfType ty `unionFV` tyCoFVsOfTypes tys) fv_cand in_scope acc
tyCoFVsOfTypes [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc
tyCoVarsOfCoDSet :: Coercion -> DTyCoVarSet
tyCoVarsOfCoDSet co = fvDVarSet $ tyCoFVsOfCo co
tyCoVarsOfCoList :: Coercion -> [TyCoVar]
tyCoVarsOfCoList co = fvVarList $ tyCoFVsOfCo co
tyCoFVsOfMCo :: MCoercion -> FV
tyCoFVsOfMCo MRefl = emptyFV
tyCoFVsOfMCo (MCo co) = tyCoFVsOfCo co
tyCoVarsOfCosSet :: CoVarEnv Coercion -> TyCoVarSet
tyCoVarsOfCosSet cos = tyCoVarsOfCos $ nonDetEltsUFM cos
tyCoFVsOfCo :: Coercion -> FV
tyCoFVsOfCo (Refl ty) fv_cand in_scope acc
= tyCoFVsOfType ty fv_cand in_scope acc
tyCoFVsOfCo (GRefl _ ty mco) fv_cand in_scope acc
= (tyCoFVsOfType ty `unionFV` tyCoFVsOfMCo mco) fv_cand in_scope acc
tyCoFVsOfCo (TyConAppCo _ _ cos) fv_cand in_scope acc = tyCoFVsOfCos cos fv_cand in_scope acc
tyCoFVsOfCo (AppCo co arg) fv_cand in_scope acc
= (tyCoFVsOfCo co `unionFV` tyCoFVsOfCo arg) fv_cand in_scope acc
tyCoFVsOfCo (ForAllCo tv kind_co co) fv_cand in_scope acc
= (tyCoFVsVarBndr tv (tyCoFVsOfCo co) `unionFV` tyCoFVsOfCo kind_co) fv_cand in_scope acc
tyCoFVsOfCo (FunCo _ co1 co2) fv_cand in_scope acc
= (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2) fv_cand in_scope acc
tyCoFVsOfCo (CoVarCo v) fv_cand in_scope acc
= tyCoFVsOfCoVar v fv_cand in_scope acc
tyCoFVsOfCo (HoleCo h) fv_cand in_scope acc
= tyCoFVsOfCoVar (coHoleCoVar h) fv_cand in_scope acc
tyCoFVsOfCo (AxiomInstCo _ _ cos) fv_cand in_scope acc = tyCoFVsOfCos cos fv_cand in_scope acc
tyCoFVsOfCo (UnivCo p _ t1 t2) fv_cand in_scope acc
= (tyCoFVsOfProv p `unionFV` tyCoFVsOfType t1
`unionFV` tyCoFVsOfType t2) fv_cand in_scope acc
tyCoFVsOfCo (SymCo co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfCo (TransCo co1 co2) fv_cand in_scope acc = (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2) fv_cand in_scope acc
tyCoFVsOfCo (NthCo _ _ co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfCo (LRCo _ co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfCo (InstCo co arg) fv_cand in_scope acc = (tyCoFVsOfCo co `unionFV` tyCoFVsOfCo arg) fv_cand in_scope acc
tyCoFVsOfCo (KindCo co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfCo (SubCo co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfCo (AxiomRuleCo _ cs) fv_cand in_scope acc = tyCoFVsOfCos cs fv_cand in_scope acc
tyCoFVsOfCoVar :: CoVar -> FV
tyCoFVsOfCoVar v fv_cand in_scope acc
= (unitFV v `unionFV` tyCoFVsOfType (varType v)) fv_cand in_scope acc
tyCoFVsOfProv :: UnivCoProvenance -> FV
tyCoFVsOfProv UnsafeCoerceProv fv_cand in_scope acc = emptyFV fv_cand in_scope acc
tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc
tyCoFVsOfProv (PluginProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc
tyCoFVsOfCos :: [Coercion] -> FV
tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc
tyCoFVsOfCos (co:cos) fv_cand in_scope acc = (tyCoFVsOfCo co `unionFV` tyCoFVsOfCos cos) fv_cand in_scope acc
getCoVarSet :: FV -> CoVarSet
getCoVarSet fv = snd (fv isCoVar emptyVarSet ([], emptyVarSet))
coVarsOfType :: Type -> CoVarSet
coVarsOfType ty = getCoVarSet (tyCoFVsOfType ty)
coVarsOfTypes :: [Type] -> TyCoVarSet
coVarsOfTypes tys = getCoVarSet (tyCoFVsOfTypes tys)
coVarsOfCo :: Coercion -> CoVarSet
coVarsOfCo co = getCoVarSet (tyCoFVsOfCo co)
coVarsOfCos :: [Coercion] -> CoVarSet
coVarsOfCos cos = getCoVarSet (tyCoFVsOfCos cos)
almostDevoidCoVarOfCo :: CoVar -> Coercion -> Bool
almostDevoidCoVarOfCo cv co =
almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_co :: Coercion -> CoVar -> Bool
almost_devoid_co_var_of_co (Refl {}) _ = True
almost_devoid_co_var_of_co (GRefl {}) _ = True
almost_devoid_co_var_of_co (TyConAppCo _ _ cos) cv
= almost_devoid_co_var_of_cos cos cv
almost_devoid_co_var_of_co (AppCo co arg) cv
= almost_devoid_co_var_of_co co cv
&& almost_devoid_co_var_of_co arg cv
almost_devoid_co_var_of_co (ForAllCo v kind_co co) cv
= almost_devoid_co_var_of_co kind_co cv
&& (v == cv || almost_devoid_co_var_of_co co cv)
almost_devoid_co_var_of_co (FunCo _ co1 co2) cv
= almost_devoid_co_var_of_co co1 cv
&& almost_devoid_co_var_of_co co2 cv
almost_devoid_co_var_of_co (CoVarCo v) cv = v /= cv
almost_devoid_co_var_of_co (HoleCo h) cv = (coHoleCoVar h) /= cv
almost_devoid_co_var_of_co (AxiomInstCo _ _ cos) cv
= almost_devoid_co_var_of_cos cos cv
almost_devoid_co_var_of_co (UnivCo p _ t1 t2) cv
= almost_devoid_co_var_of_prov p cv
&& almost_devoid_co_var_of_type t1 cv
&& almost_devoid_co_var_of_type t2 cv
almost_devoid_co_var_of_co (SymCo co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_co (TransCo co1 co2) cv
= almost_devoid_co_var_of_co co1 cv
&& almost_devoid_co_var_of_co co2 cv
almost_devoid_co_var_of_co (NthCo _ _ co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_co (LRCo _ co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_co (InstCo co arg) cv
= almost_devoid_co_var_of_co co cv
&& almost_devoid_co_var_of_co arg cv
almost_devoid_co_var_of_co (KindCo co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_co (SubCo co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_co (AxiomRuleCo _ cs) cv
= almost_devoid_co_var_of_cos cs cv
almost_devoid_co_var_of_cos :: [Coercion] -> CoVar -> Bool
almost_devoid_co_var_of_cos [] _ = True
almost_devoid_co_var_of_cos (co:cos) cv
= almost_devoid_co_var_of_co co cv
&& almost_devoid_co_var_of_cos cos cv
almost_devoid_co_var_of_prov :: UnivCoProvenance -> CoVar -> Bool
almost_devoid_co_var_of_prov (PhantomProv co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_prov (ProofIrrelProv co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_prov UnsafeCoerceProv _ = True
almost_devoid_co_var_of_prov (PluginProv _) _ = True
almost_devoid_co_var_of_type :: Type -> CoVar -> Bool
almost_devoid_co_var_of_type (TyVarTy _) _ = True
almost_devoid_co_var_of_type (TyConApp _ tys) cv
= almost_devoid_co_var_of_types tys cv
almost_devoid_co_var_of_type (LitTy {}) _ = True
almost_devoid_co_var_of_type (AppTy fun arg) cv
= almost_devoid_co_var_of_type fun cv
&& almost_devoid_co_var_of_type arg cv
almost_devoid_co_var_of_type (FunTy _ arg res) cv
= almost_devoid_co_var_of_type arg cv
&& almost_devoid_co_var_of_type res cv
almost_devoid_co_var_of_type (ForAllTy (Bndr v _) ty) cv
= almost_devoid_co_var_of_type (varType v) cv
&& (v == cv || almost_devoid_co_var_of_type ty cv)
almost_devoid_co_var_of_type (CastTy ty co) cv
= almost_devoid_co_var_of_type ty cv
&& almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_type (CoercionTy co) cv
= almost_devoid_co_var_of_co co cv
almost_devoid_co_var_of_types :: [Type] -> CoVar -> Bool
almost_devoid_co_var_of_types [] _ = True
almost_devoid_co_var_of_types (ty:tys) cv
= almost_devoid_co_var_of_type ty cv
&& almost_devoid_co_var_of_types tys cv
injectiveVarsOfType :: Bool
-> Type -> FV
injectiveVarsOfType look_under_tfs = go
where
go ty | Just ty' <- coreView ty
= go ty'
go (TyVarTy v) = unitFV v `unionFV` go (tyVarKind v)
go (AppTy f a) = go f `unionFV` go a
go (FunTy _ ty1 ty2) = go ty1 `unionFV` go ty2
go (TyConApp tc tys) =
case tyConInjectivityInfo tc of
Injective inj
| look_under_tfs || not (isTypeFamilyTyCon tc)
-> mapUnionFV go $
filterByList (inj ++ repeat True) tys
_ -> emptyFV
go (ForAllTy (Bndr tv _) ty) = go (tyVarKind tv) `unionFV` delFV tv (go ty)
go LitTy{} = emptyFV
go (CastTy ty _) = go ty
go CoercionTy{} = emptyFV
injectiveVarsOfTypes :: Bool
-> [Type] -> FV
injectiveVarsOfTypes look_under_tfs = mapUnionFV (injectiveVarsOfType look_under_tfs)
invisibleVarsOfType :: Type -> FV
invisibleVarsOfType = go
where
go ty | Just ty' <- coreView ty
= go ty'
go (TyVarTy v) = go (tyVarKind v)
go (AppTy f a) = go f `unionFV` go a
go (FunTy _ ty1 ty2) = go ty1 `unionFV` go ty2
go (TyConApp tc tys) = tyCoFVsOfTypes invisibles `unionFV`
invisibleVarsOfTypes visibles
where (invisibles, visibles) = partitionInvisibleTypes tc tys
go (ForAllTy tvb ty) = tyCoFVsBndr tvb $ go ty
go LitTy{} = emptyFV
go (CastTy ty co) = tyCoFVsOfCo co `unionFV` go ty
go (CoercionTy co) = tyCoFVsOfCo co
invisibleVarsOfTypes :: [Type] -> FV
invisibleVarsOfTypes = mapUnionFV invisibleVarsOfType
noFreeVarsOfType :: Type -> Bool
noFreeVarsOfType (TyVarTy _) = False
noFreeVarsOfType (AppTy t1 t2) = noFreeVarsOfType t1 && noFreeVarsOfType t2
noFreeVarsOfType (TyConApp _ tys) = all noFreeVarsOfType tys
noFreeVarsOfType ty@(ForAllTy {}) = isEmptyVarSet (tyCoVarsOfType ty)
noFreeVarsOfType (FunTy _ t1 t2) = noFreeVarsOfType t1 && noFreeVarsOfType t2
noFreeVarsOfType (LitTy _) = True
noFreeVarsOfType (CastTy ty co) = noFreeVarsOfType ty && noFreeVarsOfCo co
noFreeVarsOfType (CoercionTy co) = noFreeVarsOfCo co
noFreeVarsOfMCo :: MCoercion -> Bool
noFreeVarsOfMCo MRefl = True
noFreeVarsOfMCo (MCo co) = noFreeVarsOfCo co
noFreeVarsOfTypes :: [Type] -> Bool
noFreeVarsOfTypes = all noFreeVarsOfType
noFreeVarsOfCo :: Coercion -> Bool
noFreeVarsOfCo (Refl ty) = noFreeVarsOfType ty
noFreeVarsOfCo (GRefl _ ty co) = noFreeVarsOfType ty && noFreeVarsOfMCo co
noFreeVarsOfCo (TyConAppCo _ _ args) = all noFreeVarsOfCo args
noFreeVarsOfCo (AppCo c1 c2) = noFreeVarsOfCo c1 && noFreeVarsOfCo c2
noFreeVarsOfCo co@(ForAllCo {}) = isEmptyVarSet (tyCoVarsOfCo co)
noFreeVarsOfCo (FunCo _ c1 c2) = noFreeVarsOfCo c1 && noFreeVarsOfCo c2
noFreeVarsOfCo (CoVarCo _) = False
noFreeVarsOfCo (HoleCo {}) = True
noFreeVarsOfCo (AxiomInstCo _ _ args) = all noFreeVarsOfCo args
noFreeVarsOfCo (UnivCo p _ t1 t2) = noFreeVarsOfProv p &&
noFreeVarsOfType t1 &&
noFreeVarsOfType t2
noFreeVarsOfCo (SymCo co) = noFreeVarsOfCo co
noFreeVarsOfCo (TransCo co1 co2) = noFreeVarsOfCo co1 && noFreeVarsOfCo co2
noFreeVarsOfCo (NthCo _ _ co) = noFreeVarsOfCo co
noFreeVarsOfCo (LRCo _ co) = noFreeVarsOfCo co
noFreeVarsOfCo (InstCo co1 co2) = noFreeVarsOfCo co1 && noFreeVarsOfCo co2
noFreeVarsOfCo (KindCo co) = noFreeVarsOfCo co
noFreeVarsOfCo (SubCo co) = noFreeVarsOfCo co
noFreeVarsOfCo (AxiomRuleCo _ cs) = all noFreeVarsOfCo cs
noFreeVarsOfProv :: UnivCoProvenance -> Bool
noFreeVarsOfProv UnsafeCoerceProv = True
noFreeVarsOfProv (PhantomProv co) = noFreeVarsOfCo co
noFreeVarsOfProv (ProofIrrelProv co) = noFreeVarsOfCo co
noFreeVarsOfProv (PluginProv {}) = True
scopedSort :: [TyCoVar] -> [TyCoVar]
scopedSort = go [] []
where
go :: [TyCoVar]
-> [TyCoVarSet]
-> [TyCoVar]
-> [TyCoVar]
go acc _fv_list [] = reverse acc
go acc fv_list (tv:tvs)
= go acc' fv_list' tvs
where
(acc', fv_list') = insert tv acc fv_list
insert :: TyCoVar
-> [TyCoVar]
-> [TyCoVarSet]
-> ([TyCoVar], [TyCoVarSet])
insert tv [] [] = ([tv], [tyCoVarsOfType (tyVarKind tv)])
insert tv (a:as) (fvs:fvss)
| tv `elemVarSet` fvs
, (as', fvss') <- insert tv as fvss
= (a:as', fvs `unionVarSet` fv_tv : fvss')
| otherwise
= (tv:a:as, fvs `unionVarSet` fv_tv : fvs : fvss)
where
fv_tv = tyCoVarsOfType (tyVarKind tv)
insert _ _ _ = panic "scopedSort"
tyCoVarsOfTypeWellScoped :: Type -> [TyVar]
tyCoVarsOfTypeWellScoped = scopedSort . tyCoVarsOfTypeList
tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar]
tyCoVarsOfTypesWellScoped = scopedSort . tyCoVarsOfTypesList