{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
module GHC.Core.TyCo.Subst
(
TCvSubst(..), TvSubstEnv, CvSubstEnv,
emptyTvSubstEnv, emptyCvSubstEnv, composeTCvSubstEnv, composeTCvSubst,
emptyTCvSubst, mkEmptyTCvSubst, isEmptyTCvSubst,
mkTCvSubst, mkTvSubst, mkCvSubst,
getTvSubstEnv,
getCvSubstEnv, getTCvInScope, getTCvSubstRangeFVs,
isInScope, notElemTCvSubst,
setTvSubstEnv, setCvSubstEnv, zapTCvSubst,
extendTCvInScope, extendTCvInScopeList, extendTCvInScopeSet,
extendTCvSubst, extendTCvSubstWithClone,
extendCvSubst, extendCvSubstWithClone,
extendTvSubst, extendTvSubstBinderAndInScope, extendTvSubstWithClone,
extendTvSubstList, extendTvSubstAndInScope,
extendTCvSubstList,
unionTCvSubst, zipTyEnv, zipCoEnv,
zipTvSubst, zipCvSubst,
zipTCvSubst,
mkTvSubstPrs,
substTyWith, substTyWithCoVars, substTysWith, substTysWithCoVars,
substCoWith,
substTy, substTyAddInScope, substScaledTy,
substTyUnchecked, substTysUnchecked, substScaledTysUnchecked, substThetaUnchecked,
substTyWithUnchecked, substScaledTyUnchecked,
substCoUnchecked, substCoWithUnchecked,
substTyWithInScope,
substTys, substScaledTys, substTheta,
lookupTyVar,
substCo, substCos, substCoVar, substCoVars, lookupCoVar,
cloneTyVarBndr, cloneTyVarBndrs,
substVarBndr, substVarBndrs,
substTyVarBndr, substTyVarBndrs,
substCoVarBndr,
substTyVar, substTyVars, substTyCoVars,
substForAllCoBndr,
substVarBndrUsing, substForAllCoBndrUsing,
checkValidSubst, isValidTCvSubst,
) where
#include "HsVersions.h"
import GHC.Prelude
import {-# SOURCE #-} GHC.Core.Type
( mkCastTy, mkAppTy, isCoercionTy )
import {-# SOURCE #-} GHC.Core.Coercion
( mkCoVarCo, mkKindCo, mkNthCo, mkTransCo
, mkNomReflCo, mkSubCo, mkSymCo
, mkFunCo, mkForAllCo, mkUnivCo
, mkAxiomInstCo, mkAppCo, mkGReflCo
, mkInstCo, mkLRCo, mkTyConAppCo
, mkCoercionType
, coercionKind, coercionLKind, coVarKindsTypesRole )
import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprTyVar )
import GHC.Core.TyCo.Rep
import GHC.Core.TyCo.FVs
import GHC.Types.Var
import GHC.Types.Var.Set
import GHC.Types.Var.Env
import GHC.Data.Pair
import GHC.Utils.Misc
import GHC.Types.Unique.Supply
import GHC.Types.Unique
import GHC.Types.Unique.FM
import GHC.Types.Unique.Set
import GHC.Utils.Outputable
import Data.List (mapAccumL)
data TCvSubst
= TCvSubst InScopeSet
TvSubstEnv
CvSubstEnv
type TvSubstEnv = TyVarEnv Type
type CvSubstEnv = CoVarEnv Coercion
emptyTvSubstEnv :: TvSubstEnv
emptyTvSubstEnv :: TvSubstEnv
emptyTvSubstEnv = TvSubstEnv
forall a. VarEnv a
emptyVarEnv
emptyCvSubstEnv :: CvSubstEnv
emptyCvSubstEnv :: CvSubstEnv
emptyCvSubstEnv = CvSubstEnv
forall a. VarEnv a
emptyVarEnv
composeTCvSubstEnv :: InScopeSet
-> (TvSubstEnv, CvSubstEnv)
-> (TvSubstEnv, CvSubstEnv)
-> (TvSubstEnv, CvSubstEnv)
composeTCvSubstEnv :: InScopeSet
-> (TvSubstEnv, CvSubstEnv)
-> (TvSubstEnv, CvSubstEnv)
-> (TvSubstEnv, CvSubstEnv)
composeTCvSubstEnv InScopeSet
in_scope (TvSubstEnv
tenv1, CvSubstEnv
cenv1) (TvSubstEnv
tenv2, CvSubstEnv
cenv2)
= ( TvSubstEnv
tenv1 TvSubstEnv -> TvSubstEnv -> TvSubstEnv
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` (Type -> Type) -> TvSubstEnv -> TvSubstEnv
forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst1) TvSubstEnv
tenv2
, CvSubstEnv
cenv1 CvSubstEnv -> CvSubstEnv -> CvSubstEnv
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` (Coercion -> Coercion) -> CvSubstEnv -> CvSubstEnv
forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo TCvSubst
subst1) CvSubstEnv
cenv2 )
where
subst1 :: TCvSubst
subst1 = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tenv1 CvSubstEnv
cenv1
composeTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
composeTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
composeTCvSubst (TCvSubst InScopeSet
is1 TvSubstEnv
tenv1 CvSubstEnv
cenv1) (TCvSubst InScopeSet
is2 TvSubstEnv
tenv2 CvSubstEnv
cenv2)
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
is3 TvSubstEnv
tenv3 CvSubstEnv
cenv3
where
is3 :: InScopeSet
is3 = InScopeSet
is1 InScopeSet -> InScopeSet -> InScopeSet
`unionInScope` InScopeSet
is2
(TvSubstEnv
tenv3, CvSubstEnv
cenv3) = InScopeSet
-> (TvSubstEnv, CvSubstEnv)
-> (TvSubstEnv, CvSubstEnv)
-> (TvSubstEnv, CvSubstEnv)
composeTCvSubstEnv InScopeSet
is3 (TvSubstEnv
tenv1, CvSubstEnv
cenv1) (TvSubstEnv
tenv2, CvSubstEnv
cenv2)
emptyTCvSubst :: TCvSubst
emptyTCvSubst :: TCvSubst
emptyTCvSubst = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
emptyInScopeSet TvSubstEnv
emptyTvSubstEnv CvSubstEnv
emptyCvSubstEnv
mkEmptyTCvSubst :: InScopeSet -> TCvSubst
mkEmptyTCvSubst :: InScopeSet -> TCvSubst
mkEmptyTCvSubst InScopeSet
is = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
is TvSubstEnv
emptyTvSubstEnv CvSubstEnv
emptyCvSubstEnv
isEmptyTCvSubst :: TCvSubst -> Bool
isEmptyTCvSubst :: TCvSubst -> Bool
isEmptyTCvSubst (TCvSubst InScopeSet
_ TvSubstEnv
tenv CvSubstEnv
cenv) = TvSubstEnv -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv TvSubstEnv
tenv Bool -> Bool -> Bool
&& CvSubstEnv -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv CvSubstEnv
cenv
mkTCvSubst :: InScopeSet -> (TvSubstEnv, CvSubstEnv) -> TCvSubst
mkTCvSubst :: InScopeSet -> (TvSubstEnv, CvSubstEnv) -> TCvSubst
mkTCvSubst InScopeSet
in_scope (TvSubstEnv
tenv, CvSubstEnv
cenv) = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv
mkTvSubst :: InScopeSet -> TvSubstEnv -> TCvSubst
mkTvSubst :: InScopeSet -> TvSubstEnv -> TCvSubst
mkTvSubst InScopeSet
in_scope TvSubstEnv
tenv = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
emptyCvSubstEnv
mkCvSubst :: InScopeSet -> CvSubstEnv -> TCvSubst
mkCvSubst :: InScopeSet -> CvSubstEnv -> TCvSubst
mkCvSubst InScopeSet
in_scope CvSubstEnv
cenv = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
emptyTvSubstEnv CvSubstEnv
cenv
getTvSubstEnv :: TCvSubst -> TvSubstEnv
getTvSubstEnv :: TCvSubst -> TvSubstEnv
getTvSubstEnv (TCvSubst InScopeSet
_ TvSubstEnv
env CvSubstEnv
_) = TvSubstEnv
env
getCvSubstEnv :: TCvSubst -> CvSubstEnv
getCvSubstEnv :: TCvSubst -> CvSubstEnv
getCvSubstEnv (TCvSubst InScopeSet
_ TvSubstEnv
_ CvSubstEnv
env) = CvSubstEnv
env
getTCvInScope :: TCvSubst -> InScopeSet
getTCvInScope :: TCvSubst -> InScopeSet
getTCvInScope (TCvSubst InScopeSet
in_scope TvSubstEnv
_ CvSubstEnv
_) = InScopeSet
in_scope
getTCvSubstRangeFVs :: TCvSubst -> VarSet
getTCvSubstRangeFVs :: TCvSubst -> VarSet
getTCvSubstRangeFVs (TCvSubst InScopeSet
_ TvSubstEnv
tenv CvSubstEnv
cenv)
= VarSet -> VarSet -> VarSet
unionVarSet VarSet
tenvFVs VarSet
cenvFVs
where
tenvFVs :: VarSet
tenvFVs = TvSubstEnv -> VarSet
shallowTyCoVarsOfTyVarEnv TvSubstEnv
tenv
cenvFVs :: VarSet
cenvFVs = CvSubstEnv -> VarSet
shallowTyCoVarsOfCoVarEnv CvSubstEnv
cenv
isInScope :: Var -> TCvSubst -> Bool
isInScope :: TyCoVar -> TCvSubst -> Bool
isInScope TyCoVar
v (TCvSubst InScopeSet
in_scope TvSubstEnv
_ CvSubstEnv
_) = TyCoVar
v TyCoVar -> InScopeSet -> Bool
`elemInScopeSet` InScopeSet
in_scope
notElemTCvSubst :: Var -> TCvSubst -> Bool
notElemTCvSubst :: TyCoVar -> TCvSubst -> Bool
notElemTCvSubst TyCoVar
v (TCvSubst InScopeSet
_ TvSubstEnv
tenv CvSubstEnv
cenv)
| TyCoVar -> Bool
isTyVar TyCoVar
v
= Bool -> Bool
not (TyCoVar
v TyCoVar -> TvSubstEnv -> Bool
forall a. TyCoVar -> VarEnv a -> Bool
`elemVarEnv` TvSubstEnv
tenv)
| Bool
otherwise
= Bool -> Bool
not (TyCoVar
v TyCoVar -> CvSubstEnv -> Bool
forall a. TyCoVar -> VarEnv a -> Bool
`elemVarEnv` CvSubstEnv
cenv)
setTvSubstEnv :: TCvSubst -> TvSubstEnv -> TCvSubst
setTvSubstEnv :: TCvSubst -> TvSubstEnv -> TCvSubst
setTvSubstEnv (TCvSubst InScopeSet
in_scope TvSubstEnv
_ CvSubstEnv
cenv) TvSubstEnv
tenv = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv
setCvSubstEnv :: TCvSubst -> CvSubstEnv -> TCvSubst
setCvSubstEnv :: TCvSubst -> CvSubstEnv -> TCvSubst
setCvSubstEnv (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
_) CvSubstEnv
cenv = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv
zapTCvSubst :: TCvSubst -> TCvSubst
zapTCvSubst :: TCvSubst -> TCvSubst
zapTCvSubst (TCvSubst InScopeSet
in_scope TvSubstEnv
_ CvSubstEnv
_) = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
forall a. VarEnv a
emptyVarEnv CvSubstEnv
forall a. VarEnv a
emptyVarEnv
extendTCvInScope :: TCvSubst -> Var -> TCvSubst
extendTCvInScope :: TCvSubst -> TyCoVar -> TCvSubst
extendTCvInScope (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
var
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet -> TyCoVar -> InScopeSet
extendInScopeSet InScopeSet
in_scope TyCoVar
var) TvSubstEnv
tenv CvSubstEnv
cenv
extendTCvInScopeList :: TCvSubst -> [Var] -> TCvSubst
extendTCvInScopeList :: TCvSubst -> [TyCoVar] -> TCvSubst
extendTCvInScopeList (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) [TyCoVar]
vars
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet -> [TyCoVar] -> InScopeSet
extendInScopeSetList InScopeSet
in_scope [TyCoVar]
vars) TvSubstEnv
tenv CvSubstEnv
cenv
extendTCvInScopeSet :: TCvSubst -> VarSet -> TCvSubst
extendTCvInScopeSet :: TCvSubst -> VarSet -> TCvSubst
extendTCvInScopeSet (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) VarSet
vars
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet -> VarSet -> InScopeSet
extendInScopeSetSet InScopeSet
in_scope VarSet
vars) TvSubstEnv
tenv CvSubstEnv
cenv
extendTCvSubst :: TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTCvSubst :: TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTCvSubst TCvSubst
subst TyCoVar
v Type
ty
| TyCoVar -> Bool
isTyVar TyCoVar
v
= TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTvSubst TCvSubst
subst TyCoVar
v Type
ty
| CoercionTy Coercion
co <- Type
ty
= TCvSubst -> TyCoVar -> Coercion -> TCvSubst
extendCvSubst TCvSubst
subst TyCoVar
v Coercion
co
| Bool
otherwise
= String -> SDoc -> TCvSubst
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"extendTCvSubst" (TyCoVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCoVar
v SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"|->" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
extendTCvSubstWithClone :: TCvSubst -> TyCoVar -> TyCoVar -> TCvSubst
extendTCvSubstWithClone :: TCvSubst -> TyCoVar -> TyCoVar -> TCvSubst
extendTCvSubstWithClone TCvSubst
subst TyCoVar
tcv
| TyCoVar -> Bool
isTyVar TyCoVar
tcv = TCvSubst -> TyCoVar -> TyCoVar -> TCvSubst
extendTvSubstWithClone TCvSubst
subst TyCoVar
tcv
| Bool
otherwise = TCvSubst -> TyCoVar -> TyCoVar -> TCvSubst
extendCvSubstWithClone TCvSubst
subst TyCoVar
tcv
extendTvSubst :: TCvSubst -> TyVar -> Type -> TCvSubst
extendTvSubst :: TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTvSubst (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
tv Type
ty
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope (TvSubstEnv -> TyCoVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv TyCoVar
tv Type
ty) CvSubstEnv
cenv
extendTvSubstBinderAndInScope :: TCvSubst -> TyCoBinder -> Type -> TCvSubst
extendTvSubstBinderAndInScope :: TCvSubst -> TyCoBinder -> Type -> TCvSubst
extendTvSubstBinderAndInScope TCvSubst
subst (Named (Bndr TyCoVar
v ArgFlag
_)) Type
ty
= ASSERT( isTyVar v )
TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTvSubstAndInScope TCvSubst
subst TyCoVar
v Type
ty
extendTvSubstBinderAndInScope TCvSubst
subst (Anon {}) Type
_
= TCvSubst
subst
extendTvSubstWithClone :: TCvSubst -> TyVar -> TyVar -> TCvSubst
extendTvSubstWithClone :: TCvSubst -> TyCoVar -> TyCoVar -> TCvSubst
extendTvSubstWithClone (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
tv TyCoVar
tv'
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet -> VarSet -> InScopeSet
extendInScopeSetSet InScopeSet
in_scope VarSet
new_in_scope)
(TvSubstEnv -> TyCoVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv TyCoVar
tv (TyCoVar -> Type
mkTyVarTy TyCoVar
tv'))
CvSubstEnv
cenv
where
new_in_scope :: VarSet
new_in_scope = Type -> VarSet
tyCoVarsOfType (TyCoVar -> Type
tyVarKind TyCoVar
tv') VarSet -> TyCoVar -> VarSet
`extendVarSet` TyCoVar
tv'
extendCvSubst :: TCvSubst -> CoVar -> Coercion -> TCvSubst
extendCvSubst :: TCvSubst -> TyCoVar -> Coercion -> TCvSubst
extendCvSubst (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
v Coercion
co
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tenv (CvSubstEnv -> TyCoVar -> Coercion -> CvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv CvSubstEnv
cenv TyCoVar
v Coercion
co)
extendCvSubstWithClone :: TCvSubst -> CoVar -> CoVar -> TCvSubst
extendCvSubstWithClone :: TCvSubst -> TyCoVar -> TyCoVar -> TCvSubst
extendCvSubstWithClone (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
cv TyCoVar
cv'
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet -> VarSet -> InScopeSet
extendInScopeSetSet InScopeSet
in_scope VarSet
new_in_scope)
TvSubstEnv
tenv
(CvSubstEnv -> TyCoVar -> Coercion -> CvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv CvSubstEnv
cenv TyCoVar
cv (TyCoVar -> Coercion
mkCoVarCo TyCoVar
cv'))
where
new_in_scope :: VarSet
new_in_scope = Type -> VarSet
tyCoVarsOfType (TyCoVar -> Type
varType TyCoVar
cv') VarSet -> TyCoVar -> VarSet
`extendVarSet` TyCoVar
cv'
extendTvSubstAndInScope :: TCvSubst -> TyVar -> Type -> TCvSubst
extendTvSubstAndInScope :: TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTvSubstAndInScope (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
tv Type
ty
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> VarSet -> InScopeSet
`extendInScopeSetSet` Type -> VarSet
tyCoVarsOfType Type
ty)
(TvSubstEnv -> TyCoVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv TyCoVar
tv Type
ty)
CvSubstEnv
cenv
extendTvSubstList :: TCvSubst -> [Var] -> [Type] -> TCvSubst
extendTvSubstList :: TCvSubst -> [TyCoVar] -> [Type] -> TCvSubst
extendTvSubstList TCvSubst
subst [TyCoVar]
tvs [Type]
tys
= (TCvSubst -> TyCoVar -> Type -> TCvSubst)
-> TCvSubst -> [TyCoVar] -> [Type] -> TCvSubst
forall acc a b. (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTvSubst TCvSubst
subst [TyCoVar]
tvs [Type]
tys
extendTCvSubstList :: TCvSubst -> [Var] -> [Type] -> TCvSubst
extendTCvSubstList :: TCvSubst -> [TyCoVar] -> [Type] -> TCvSubst
extendTCvSubstList TCvSubst
subst [TyCoVar]
tvs [Type]
tys
= (TCvSubst -> TyCoVar -> Type -> TCvSubst)
-> TCvSubst -> [TyCoVar] -> [Type] -> TCvSubst
forall acc a b. (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTCvSubst TCvSubst
subst [TyCoVar]
tvs [Type]
tys
unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
unionTCvSubst (TCvSubst InScopeSet
in_scope1 TvSubstEnv
tenv1 CvSubstEnv
cenv1) (TCvSubst InScopeSet
in_scope2 TvSubstEnv
tenv2 CvSubstEnv
cenv2)
= ASSERT( tenv1 `disjointVarEnv` tenv2
&& cenv1 `disjointVarEnv` cenv2 )
InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet
in_scope1 InScopeSet -> InScopeSet -> InScopeSet
`unionInScope` InScopeSet
in_scope2)
(TvSubstEnv
tenv1 TvSubstEnv -> TvSubstEnv -> TvSubstEnv
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` TvSubstEnv
tenv2)
(CvSubstEnv
cenv1 CvSubstEnv -> CvSubstEnv -> CvSubstEnv
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` CvSubstEnv
cenv2)
zipTvSubst :: HasDebugCallStack => [TyVar] -> [Type] -> TCvSubst
zipTvSubst :: HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTvSubst [TyCoVar]
tvs [Type]
tys
= InScopeSet -> TvSubstEnv -> TCvSubst
mkTvSubst (VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet
shallowTyCoVarsOfTypes [Type]
tys)) TvSubstEnv
tenv
where
tenv :: TvSubstEnv
tenv = [TyCoVar] -> [Type] -> TvSubstEnv
HasDebugCallStack => [TyCoVar] -> [Type] -> TvSubstEnv
zipTyEnv [TyCoVar]
tvs [Type]
tys
zipCvSubst :: HasDebugCallStack => [CoVar] -> [Coercion] -> TCvSubst
zipCvSubst :: HasDebugCallStack => [TyCoVar] -> [Coercion] -> TCvSubst
zipCvSubst [TyCoVar]
cvs [Coercion]
cos
= InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (VarSet -> InScopeSet
mkInScopeSet ([Coercion] -> VarSet
shallowTyCoVarsOfCos [Coercion]
cos)) TvSubstEnv
emptyTvSubstEnv CvSubstEnv
cenv
where
cenv :: CvSubstEnv
cenv = [TyCoVar] -> [Coercion] -> CvSubstEnv
HasDebugCallStack => [TyCoVar] -> [Coercion] -> CvSubstEnv
zipCoEnv [TyCoVar]
cvs [Coercion]
cos
zipTCvSubst :: HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTCvSubst :: HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTCvSubst [TyCoVar]
tcvs [Type]
tys
= [TyCoVar] -> [Type] -> TCvSubst -> TCvSubst
zip_tcvsubst [TyCoVar]
tcvs [Type]
tys (TCvSubst -> TCvSubst) -> TCvSubst -> TCvSubst
forall a b. (a -> b) -> a -> b
$
InScopeSet -> TCvSubst
mkEmptyTCvSubst (InScopeSet -> TCvSubst) -> InScopeSet -> TCvSubst
forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet (VarSet -> InScopeSet) -> VarSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$ [Type] -> VarSet
shallowTyCoVarsOfTypes [Type]
tys
where zip_tcvsubst :: [TyCoVar] -> [Type] -> TCvSubst -> TCvSubst
zip_tcvsubst :: [TyCoVar] -> [Type] -> TCvSubst -> TCvSubst
zip_tcvsubst (TyCoVar
tv:[TyCoVar]
tvs) (Type
ty:[Type]
tys) TCvSubst
subst
= [TyCoVar] -> [Type] -> TCvSubst -> TCvSubst
zip_tcvsubst [TyCoVar]
tvs [Type]
tys (TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTCvSubst TCvSubst
subst TyCoVar
tv Type
ty)
zip_tcvsubst [] [] TCvSubst
subst = TCvSubst
subst
zip_tcvsubst [TyCoVar]
_ [Type]
_ TCvSubst
_ = String -> SDoc -> TCvSubst
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipTCvSubst: length mismatch"
([TyCoVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVar]
tcvs SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tys)
mkTvSubstPrs :: [(TyVar, Type)] -> TCvSubst
mkTvSubstPrs :: [(TyCoVar, Type)] -> TCvSubst
mkTvSubstPrs [(TyCoVar, Type)]
prs =
ASSERT2( onlyTyVarsAndNoCoercionTy, text "prs" <+> ppr prs )
InScopeSet -> TvSubstEnv -> TCvSubst
mkTvSubst InScopeSet
in_scope TvSubstEnv
tenv
where tenv :: TvSubstEnv
tenv = [(TyCoVar, Type)] -> TvSubstEnv
forall a. [(TyCoVar, a)] -> VarEnv a
mkVarEnv [(TyCoVar, Type)]
prs
in_scope :: InScopeSet
in_scope = VarSet -> InScopeSet
mkInScopeSet (VarSet -> InScopeSet) -> VarSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$ [Type] -> VarSet
shallowTyCoVarsOfTypes ([Type] -> VarSet) -> [Type] -> VarSet
forall a b. (a -> b) -> a -> b
$ ((TyCoVar, Type) -> Type) -> [(TyCoVar, Type)] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyCoVar, Type) -> Type
forall a b. (a, b) -> b
snd [(TyCoVar, Type)]
prs
onlyTyVarsAndNoCoercionTy :: Bool
onlyTyVarsAndNoCoercionTy =
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ TyCoVar -> Bool
isTyVar TyCoVar
tv Bool -> Bool -> Bool
&& Bool -> Bool
not (Type -> Bool
isCoercionTy Type
ty)
| (TyCoVar
tv, Type
ty) <- [(TyCoVar, Type)]
prs ]
zipTyEnv :: HasDebugCallStack => [TyVar] -> [Type] -> TvSubstEnv
zipTyEnv :: HasDebugCallStack => [TyCoVar] -> [Type] -> TvSubstEnv
zipTyEnv [TyCoVar]
tyvars [Type]
tys
| Bool
debugIsOn
, Bool -> Bool
not ((TyCoVar -> Bool) -> [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all TyCoVar -> Bool
isTyVar [TyCoVar]
tyvars Bool -> Bool -> Bool
&& ([TyCoVar]
tyvars [TyCoVar] -> [Type] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys))
= String -> SDoc -> TvSubstEnv
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipTyEnv" ([TyCoVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVar]
tyvars SDoc -> SDoc -> SDoc
$$ [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tys)
| Bool
otherwise
= ASSERT( all (not . isCoercionTy) tys )
[(TyCoVar, Type)] -> TvSubstEnv
forall a. [(TyCoVar, a)] -> VarEnv a
mkVarEnv (String -> [TyCoVar] -> [Type] -> [(TyCoVar, Type)]
forall a b. String -> [a] -> [b] -> [(a, b)]
zipEqual String
"zipTyEnv" [TyCoVar]
tyvars [Type]
tys)
zipCoEnv :: HasDebugCallStack => [CoVar] -> [Coercion] -> CvSubstEnv
zipCoEnv :: HasDebugCallStack => [TyCoVar] -> [Coercion] -> CvSubstEnv
zipCoEnv [TyCoVar]
cvs [Coercion]
cos
| Bool
debugIsOn
, Bool -> Bool
not ((TyCoVar -> Bool) -> [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all TyCoVar -> Bool
isCoVar [TyCoVar]
cvs)
= String -> SDoc -> CvSubstEnv
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipCoEnv" ([TyCoVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVar]
cvs SDoc -> SDoc -> SDoc
<+> [Coercion] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Coercion]
cos)
| Bool
otherwise
= [(TyCoVar, Coercion)] -> CvSubstEnv
forall a. [(TyCoVar, a)] -> VarEnv a
mkVarEnv (String -> [TyCoVar] -> [Coercion] -> [(TyCoVar, Coercion)]
forall a b. String -> [a] -> [b] -> [(a, b)]
zipEqual String
"zipCoEnv" [TyCoVar]
cvs [Coercion]
cos)
instance Outputable TCvSubst where
ppr :: TCvSubst -> SDoc
ppr (TCvSubst InScopeSet
ins TvSubstEnv
tenv CvSubstEnv
cenv)
= SDoc -> SDoc
brackets (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
sep[ String -> SDoc
text String
"TCvSubst",
Int -> SDoc -> SDoc
nest Int
2 (String -> SDoc
text String
"In scope:" SDoc -> SDoc -> SDoc
<+> InScopeSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr InScopeSet
ins),
Int -> SDoc -> SDoc
nest Int
2 (String -> SDoc
text String
"Type env:" SDoc -> SDoc -> SDoc
<+> TvSubstEnv -> SDoc
forall a. Outputable a => a -> SDoc
ppr TvSubstEnv
tenv),
Int -> SDoc -> SDoc
nest Int
2 (String -> SDoc
text String
"Co env:" SDoc -> SDoc -> SDoc
<+> CvSubstEnv -> SDoc
forall a. Outputable a => a -> SDoc
ppr CvSubstEnv
cenv) ]
substTyWith :: HasCallStack => [TyVar] -> [Type] -> Type -> Type
substTyWith :: HasCallStack => [TyCoVar] -> [Type] -> Type -> Type
substTyWith [TyCoVar]
tvs [Type]
tys = {-#SCC "substTyWith" #-}
ASSERT( tvs `equalLength` tys )
HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy ([TyCoVar] -> [Type] -> TCvSubst
HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTvSubst [TyCoVar]
tvs [Type]
tys)
substTyWithUnchecked :: [TyVar] -> [Type] -> Type -> Type
substTyWithUnchecked :: [TyCoVar] -> [Type] -> Type -> Type
substTyWithUnchecked [TyCoVar]
tvs [Type]
tys
= ASSERT( tvs `equalLength` tys )
TCvSubst -> Type -> Type
substTyUnchecked ([TyCoVar] -> [Type] -> TCvSubst
HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTvSubst [TyCoVar]
tvs [Type]
tys)
substTyWithInScope :: InScopeSet -> [TyVar] -> [Type] -> Type -> Type
substTyWithInScope :: InScopeSet -> [TyCoVar] -> [Type] -> Type -> Type
substTyWithInScope InScopeSet
in_scope [TyCoVar]
tvs [Type]
tys Type
ty =
ASSERT( tvs `equalLength` tys )
HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy (InScopeSet -> TvSubstEnv -> TCvSubst
mkTvSubst InScopeSet
in_scope TvSubstEnv
tenv) Type
ty
where tenv :: TvSubstEnv
tenv = [TyCoVar] -> [Type] -> TvSubstEnv
HasDebugCallStack => [TyCoVar] -> [Type] -> TvSubstEnv
zipTyEnv [TyCoVar]
tvs [Type]
tys
substCoWith :: HasCallStack => [TyVar] -> [Type] -> Coercion -> Coercion
substCoWith :: HasCallStack => [TyCoVar] -> [Type] -> Coercion -> Coercion
substCoWith [TyCoVar]
tvs [Type]
tys = ASSERT( tvs `equalLength` tys )
HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo ([TyCoVar] -> [Type] -> TCvSubst
HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTvSubst [TyCoVar]
tvs [Type]
tys)
substCoWithUnchecked :: [TyVar] -> [Type] -> Coercion -> Coercion
substCoWithUnchecked :: [TyCoVar] -> [Type] -> Coercion -> Coercion
substCoWithUnchecked [TyCoVar]
tvs [Type]
tys
= ASSERT( tvs `equalLength` tys )
TCvSubst -> Coercion -> Coercion
substCoUnchecked ([TyCoVar] -> [Type] -> TCvSubst
HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTvSubst [TyCoVar]
tvs [Type]
tys)
substTyWithCoVars :: [CoVar] -> [Coercion] -> Type -> Type
substTyWithCoVars :: [TyCoVar] -> [Coercion] -> Type -> Type
substTyWithCoVars [TyCoVar]
cvs [Coercion]
cos = HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy ([TyCoVar] -> [Coercion] -> TCvSubst
HasDebugCallStack => [TyCoVar] -> [Coercion] -> TCvSubst
zipCvSubst [TyCoVar]
cvs [Coercion]
cos)
substTysWith :: [TyVar] -> [Type] -> [Type] -> [Type]
substTysWith :: [TyCoVar] -> [Type] -> [Type] -> [Type]
substTysWith [TyCoVar]
tvs [Type]
tys = ASSERT( tvs `equalLength` tys )
HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys ([TyCoVar] -> [Type] -> TCvSubst
HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTvSubst [TyCoVar]
tvs [Type]
tys)
substTysWithCoVars :: [CoVar] -> [Coercion] -> [Type] -> [Type]
substTysWithCoVars :: [TyCoVar] -> [Coercion] -> [Type] -> [Type]
substTysWithCoVars [TyCoVar]
cvs [Coercion]
cos = ASSERT( cvs `equalLength` cos )
HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys ([TyCoVar] -> [Coercion] -> TCvSubst
HasDebugCallStack => [TyCoVar] -> [Coercion] -> TCvSubst
zipCvSubst [TyCoVar]
cvs [Coercion]
cos)
substTyAddInScope :: TCvSubst -> Type -> Type
substTyAddInScope :: TCvSubst -> Type -> Type
substTyAddInScope TCvSubst
subst Type
ty =
HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy (TCvSubst -> VarSet -> TCvSubst
extendTCvInScopeSet TCvSubst
subst (VarSet -> TCvSubst) -> VarSet -> TCvSubst
forall a b. (a -> b) -> a -> b
$ Type -> VarSet
tyCoVarsOfType Type
ty) Type
ty
isValidTCvSubst :: TCvSubst -> Bool
isValidTCvSubst :: TCvSubst -> Bool
isValidTCvSubst (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) =
(VarSet
tenvFVs VarSet -> InScopeSet -> Bool
`varSetInScope` InScopeSet
in_scope) Bool -> Bool -> Bool
&&
(VarSet
cenvFVs VarSet -> InScopeSet -> Bool
`varSetInScope` InScopeSet
in_scope)
where
tenvFVs :: VarSet
tenvFVs = TvSubstEnv -> VarSet
shallowTyCoVarsOfTyVarEnv TvSubstEnv
tenv
cenvFVs :: VarSet
cenvFVs = CvSubstEnv -> VarSet
shallowTyCoVarsOfCoVarEnv CvSubstEnv
cenv
checkValidSubst :: HasCallStack => TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst :: forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) [Type]
tys [Coercion]
cos a
a
= ASSERT2( isValidTCvSubst subst,
text "in_scope" <+> ppr in_scope $$
text "tenv" <+> ppr tenv $$
text "tenvFVs" <+> ppr (shallowTyCoVarsOfTyVarEnv tenv) $$
text "cenv" <+> ppr cenv $$
text "cenvFVs" <+> ppr (shallowTyCoVarsOfCoVarEnv cenv) $$
text "tys" <+> ppr tys $$
text "cos" <+> ppr cos )
ASSERT2( tysCosFVsInScope,
text "in_scope" <+> ppr in_scope $$
text "tenv" <+> ppr tenv $$
text "cenv" <+> ppr cenv $$
text "tys" <+> ppr tys $$
text "cos" <+> ppr cos $$
text "needInScope" <+> ppr needInScope )
a
a
where
substDomain :: [Unique]
substDomain = TvSubstEnv -> [Unique]
forall key elt. UniqFM key elt -> [Unique]
nonDetKeysUFM TvSubstEnv
tenv [Unique] -> [Unique] -> [Unique]
forall a. [a] -> [a] -> [a]
++ CvSubstEnv -> [Unique]
forall key elt. UniqFM key elt -> [Unique]
nonDetKeysUFM CvSubstEnv
cenv
needInScope :: VarSet
needInScope = ([Type] -> VarSet
shallowTyCoVarsOfTypes [Type]
tys VarSet -> VarSet -> VarSet
`unionVarSet`
[Coercion] -> VarSet
shallowTyCoVarsOfCos [Coercion]
cos)
VarSet -> [Unique] -> VarSet
forall a. UniqSet a -> [Unique] -> UniqSet a
`delListFromUniqSet_Directly` [Unique]
substDomain
tysCosFVsInScope :: Bool
tysCosFVsInScope = VarSet
needInScope VarSet -> InScopeSet -> Bool
`varSetInScope` InScopeSet
in_scope
substTy :: HasCallStack => TCvSubst -> Type -> Type
substTy :: HasCallStack => TCvSubst -> Type -> Type
substTy TCvSubst
subst Type
ty
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Type
ty
| Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> Type -> Type
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [Type
ty] [] (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$
TCvSubst -> Type -> Type
subst_ty TCvSubst
subst Type
ty
substTyUnchecked :: TCvSubst -> Type -> Type
substTyUnchecked :: TCvSubst -> Type -> Type
substTyUnchecked TCvSubst
subst Type
ty
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Type
ty
| Bool
otherwise = TCvSubst -> Type -> Type
subst_ty TCvSubst
subst Type
ty
substScaledTy :: HasCallStack => TCvSubst -> Scaled Type -> Scaled Type
substScaledTy :: HasCallStack => TCvSubst -> Scaled Type -> Scaled Type
substScaledTy TCvSubst
subst Scaled Type
scaled_ty = (Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst) Scaled Type
scaled_ty
substScaledTyUnchecked :: HasCallStack => TCvSubst -> Scaled Type -> Scaled Type
substScaledTyUnchecked :: HasCallStack => TCvSubst -> Scaled Type -> Scaled Type
substScaledTyUnchecked TCvSubst
subst Scaled Type
scaled_ty = (Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (TCvSubst -> Type -> Type
substTyUnchecked TCvSubst
subst) Scaled Type
scaled_ty
substTys :: HasCallStack => TCvSubst -> [Type] -> [Type]
substTys :: HasCallStack => TCvSubst -> [Type] -> [Type]
substTys TCvSubst
subst [Type]
tys
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Type]
tys
| Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> [Type] -> [Type]
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [Type]
tys [] ([Type] -> [Type]) -> [Type] -> [Type]
forall a b. (a -> b) -> a -> b
$ (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> Type -> Type
subst_ty TCvSubst
subst) [Type]
tys
substScaledTys :: HasCallStack => TCvSubst -> [Scaled Type] -> [Scaled Type]
substScaledTys :: HasCallStack => TCvSubst -> [Scaled Type] -> [Scaled Type]
substScaledTys TCvSubst
subst [Scaled Type]
scaled_tys
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Scaled Type]
scaled_tys
| Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> [Scaled Type] -> [Scaled Type]
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst ((Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult [Scaled Type]
scaled_tys [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ (Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing [Scaled Type]
scaled_tys) [] ([Scaled Type] -> [Scaled Type]) -> [Scaled Type] -> [Scaled Type]
forall a b. (a -> b) -> a -> b
$
(Scaled Type -> Scaled Type) -> [Scaled Type] -> [Scaled Type]
forall a b. (a -> b) -> [a] -> [b]
map ((Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (TCvSubst -> Type -> Type
subst_ty TCvSubst
subst)) [Scaled Type]
scaled_tys
substTysUnchecked :: TCvSubst -> [Type] -> [Type]
substTysUnchecked :: TCvSubst -> [Type] -> [Type]
substTysUnchecked TCvSubst
subst [Type]
tys
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Type]
tys
| Bool
otherwise = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> Type -> Type
subst_ty TCvSubst
subst) [Type]
tys
substScaledTysUnchecked :: TCvSubst -> [Scaled Type] -> [Scaled Type]
substScaledTysUnchecked :: TCvSubst -> [Scaled Type] -> [Scaled Type]
substScaledTysUnchecked TCvSubst
subst [Scaled Type]
tys
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Scaled Type]
tys
| Bool
otherwise = (Scaled Type -> Scaled Type) -> [Scaled Type] -> [Scaled Type]
forall a b. (a -> b) -> [a] -> [b]
map ((Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (TCvSubst -> Type -> Type
subst_ty TCvSubst
subst)) [Scaled Type]
tys
substTheta :: HasCallStack => TCvSubst -> ThetaType -> ThetaType
substTheta :: HasCallStack => TCvSubst -> [Type] -> [Type]
substTheta = HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys
substThetaUnchecked :: TCvSubst -> ThetaType -> ThetaType
substThetaUnchecked :: TCvSubst -> [Type] -> [Type]
substThetaUnchecked = TCvSubst -> [Type] -> [Type]
substTysUnchecked
subst_ty :: TCvSubst -> Type -> Type
subst_ty :: TCvSubst -> Type -> Type
subst_ty TCvSubst
subst Type
ty
= Type -> Type
go Type
ty
where
go :: Type -> Type
go (TyVarTy TyCoVar
tv) = TCvSubst -> TyCoVar -> Type
substTyVar TCvSubst
subst TyCoVar
tv
go (AppTy Type
fun Type
arg) = (Type -> Type -> Type
mkAppTy (Type -> Type -> Type) -> Type -> Type -> Type
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
fun)) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
arg)
go ty :: Type
ty@(TyConApp TyCon
tc []) = TyCon
tc TyCon -> Type -> Type
`seq` Type
ty
go (TyConApp TyCon
tc [Type]
tys) = (TyCon -> [Type] -> Type
mkTyConApp (TyCon -> [Type] -> Type) -> TyCon -> [Type] -> Type
forall a b. (a -> b) -> a -> b
$! TyCon
tc) ([Type] -> Type) -> [Type] -> Type
forall a b. (a -> b) -> a -> b
$! (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
strictMap Type -> Type
go [Type]
tys
go ty :: Type
ty@(FunTy { ft_mult :: Type -> Type
ft_mult = Type
mult, ft_arg :: Type -> Type
ft_arg = Type
arg, ft_res :: Type -> Type
ft_res = Type
res })
= let !mult' :: Type
mult' = Type -> Type
go Type
mult
!arg' :: Type
arg' = Type -> Type
go Type
arg
!res' :: Type
res' = Type -> Type
go Type
res
in Type
ty { ft_mult :: Type
ft_mult = Type
mult', ft_arg :: Type
ft_arg = Type
arg', ft_res :: Type
ft_res = Type
res' }
go (ForAllTy (Bndr TyCoVar
tv ArgFlag
vis) Type
ty)
= case TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUnchecked TCvSubst
subst TyCoVar
tv of
(TCvSubst
subst', TyCoVar
tv') ->
(VarBndr TyCoVar ArgFlag -> Type -> Type
ForAllTy (VarBndr TyCoVar ArgFlag -> Type -> Type)
-> VarBndr TyCoVar ArgFlag -> Type -> Type
forall a b. (a -> b) -> a -> b
$! ((TyCoVar -> ArgFlag -> VarBndr TyCoVar ArgFlag
forall var argf. var -> argf -> VarBndr var argf
Bndr (TyCoVar -> ArgFlag -> VarBndr TyCoVar ArgFlag)
-> TyCoVar -> ArgFlag -> VarBndr TyCoVar ArgFlag
forall a b. (a -> b) -> a -> b
$! TyCoVar
tv') ArgFlag
vis)) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$!
(TCvSubst -> Type -> Type
subst_ty TCvSubst
subst' Type
ty)
go (LitTy TyLit
n) = TyLit -> Type
LitTy (TyLit -> Type) -> TyLit -> Type
forall a b. (a -> b) -> a -> b
$! TyLit
n
go (CastTy Type
ty Coercion
co) = (Type -> Coercion -> Type
mkCastTy (Type -> Coercion -> Type) -> Type -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
ty)) (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co)
go (CoercionTy Coercion
co) = Coercion -> Type
CoercionTy (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co)
substTyVar :: TCvSubst -> TyVar -> Type
substTyVar :: TCvSubst -> TyCoVar -> Type
substTyVar (TCvSubst InScopeSet
_ TvSubstEnv
tenv CvSubstEnv
_) TyCoVar
tv
= ASSERT( isTyVar tv )
case TvSubstEnv -> TyCoVar -> Maybe Type
forall a. VarEnv a -> TyCoVar -> Maybe a
lookupVarEnv TvSubstEnv
tenv TyCoVar
tv of
Just Type
ty -> Type
ty
Maybe Type
Nothing -> TyCoVar -> Type
TyVarTy TyCoVar
tv
substTyVars :: TCvSubst -> [TyVar] -> [Type]
substTyVars :: TCvSubst -> [TyCoVar] -> [Type]
substTyVars TCvSubst
subst = (TyCoVar -> Type) -> [TyCoVar] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ((TyCoVar -> Type) -> [TyCoVar] -> [Type])
-> (TyCoVar -> Type) -> [TyCoVar] -> [Type]
forall a b. (a -> b) -> a -> b
$ TCvSubst -> TyCoVar -> Type
substTyVar TCvSubst
subst
substTyCoVars :: TCvSubst -> [TyCoVar] -> [Type]
substTyCoVars :: TCvSubst -> [TyCoVar] -> [Type]
substTyCoVars TCvSubst
subst = (TyCoVar -> Type) -> [TyCoVar] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ((TyCoVar -> Type) -> [TyCoVar] -> [Type])
-> (TyCoVar -> Type) -> [TyCoVar] -> [Type]
forall a b. (a -> b) -> a -> b
$ TCvSubst -> TyCoVar -> Type
substTyCoVar TCvSubst
subst
substTyCoVar :: TCvSubst -> TyCoVar -> Type
substTyCoVar :: TCvSubst -> TyCoVar -> Type
substTyCoVar TCvSubst
subst TyCoVar
tv
| TyCoVar -> Bool
isTyVar TyCoVar
tv = TCvSubst -> TyCoVar -> Type
substTyVar TCvSubst
subst TyCoVar
tv
| Bool
otherwise = Coercion -> Type
CoercionTy (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$ TCvSubst -> TyCoVar -> Coercion
substCoVar TCvSubst
subst TyCoVar
tv
lookupTyVar :: TCvSubst -> TyVar -> Maybe Type
lookupTyVar :: TCvSubst -> TyCoVar -> Maybe Type
lookupTyVar (TCvSubst InScopeSet
_ TvSubstEnv
tenv CvSubstEnv
_) TyCoVar
tv
= ASSERT( isTyVar tv )
TvSubstEnv -> TyCoVar -> Maybe Type
forall a. VarEnv a -> TyCoVar -> Maybe a
lookupVarEnv TvSubstEnv
tenv TyCoVar
tv
substCo :: HasCallStack => TCvSubst -> Coercion -> Coercion
substCo :: HasCallStack => TCvSubst -> Coercion -> Coercion
substCo TCvSubst
subst Coercion
co
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Coercion
co
| Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> Coercion -> Coercion
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [] [Coercion
co] (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$ TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co
substCoUnchecked :: TCvSubst -> Coercion -> Coercion
substCoUnchecked :: TCvSubst -> Coercion -> Coercion
substCoUnchecked TCvSubst
subst Coercion
co
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Coercion
co
| Bool
otherwise = TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co
substCos :: HasCallStack => TCvSubst -> [Coercion] -> [Coercion]
substCos :: HasCallStack => TCvSubst -> [Coercion] -> [Coercion]
substCos TCvSubst
subst [Coercion]
cos
| TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Coercion]
cos
| Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> [Coercion] -> [Coercion]
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [] [Coercion]
cos ([Coercion] -> [Coercion]) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> a -> b
$ (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst) [Coercion]
cos
subst_co :: TCvSubst -> Coercion -> Coercion
subst_co :: TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co
= Coercion -> Coercion
go Coercion
co
where
go_ty :: Type -> Type
go_ty :: Type -> Type
go_ty = TCvSubst -> Type -> Type
subst_ty TCvSubst
subst
go_mco :: MCoercion -> MCoercion
go_mco :: MCoercion -> MCoercion
go_mco MCoercion
MRefl = MCoercion
MRefl
go_mco (MCo Coercion
co) = Coercion -> MCoercion
MCo (Coercion -> Coercion
go Coercion
co)
go :: Coercion -> Coercion
go :: Coercion -> Coercion
go (Refl Type
ty) = Type -> Coercion
mkNomReflCo (Type -> Coercion) -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
ty)
go (GRefl Role
r Type
ty MCoercion
mco) = (Role -> Type -> MCoercion -> Coercion
mkGReflCo Role
r (Type -> MCoercion -> Coercion) -> Type -> MCoercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
ty)) (MCoercion -> Coercion) -> MCoercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (MCoercion -> MCoercion
go_mco MCoercion
mco)
go (TyConAppCo Role
r TyCon
tc [Coercion]
args)= let args' :: [Coercion]
args' = (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
args
in [Coercion]
args' [Coercion] -> Coercion -> Coercion
forall a b. [a] -> b -> b
`seqList` HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion
Role -> TyCon -> [Coercion] -> Coercion
mkTyConAppCo Role
r TyCon
tc [Coercion]
args'
go (AppCo Coercion
co Coercion
arg) = (Coercion -> Coercion -> Coercion
mkAppCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
arg
go (ForAllCo TyCoVar
tv Coercion
kind_co Coercion
co)
= case TCvSubst -> TyCoVar -> Coercion -> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndrUnchecked TCvSubst
subst TyCoVar
tv Coercion
kind_co of
(TCvSubst
subst', TyCoVar
tv', Coercion
kind_co') ->
((TyCoVar -> Coercion -> Coercion -> Coercion
mkForAllCo (TyCoVar -> Coercion -> Coercion -> Coercion)
-> TyCoVar -> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! TyCoVar
tv') (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion
kind_co') (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst' Coercion
co
go (FunCo Role
r Coercion
w Coercion
co1 Coercion
co2) = ((Role -> Coercion -> Coercion -> Coercion -> Coercion
mkFunCo Role
r (Coercion -> Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
w) (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co1) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co2
go (CoVarCo TyCoVar
cv) = TCvSubst -> TyCoVar -> Coercion
substCoVar TCvSubst
subst TyCoVar
cv
go (AxiomInstCo CoAxiom Branched
con Int
ind [Coercion]
cos) = CoAxiom Branched -> Int -> [Coercion] -> Coercion
mkAxiomInstCo CoAxiom Branched
con Int
ind ([Coercion] -> Coercion) -> [Coercion] -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
cos
go (UnivCo UnivCoProvenance
p Role
r Type
t1 Type
t2) = (((UnivCoProvenance -> Role -> Type -> Type -> Coercion
mkUnivCo (UnivCoProvenance -> Role -> Type -> Type -> Coercion)
-> UnivCoProvenance -> Role -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! UnivCoProvenance -> UnivCoProvenance
go_prov UnivCoProvenance
p) (Role -> Type -> Type -> Coercion)
-> Role -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! Role
r) (Type -> Type -> Coercion) -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$!
(Type -> Type
go_ty Type
t1)) (Type -> Coercion) -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
t2)
go (SymCo Coercion
co) = Coercion -> Coercion
mkSymCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (TransCo Coercion
co1 Coercion
co2) = (Coercion -> Coercion -> Coercion
mkTransCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co1)) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co2)
go (NthCo Role
r Int
d Coercion
co) = HasDebugCallStack => Role -> Int -> Coercion -> Coercion
Role -> Int -> Coercion -> Coercion
mkNthCo Role
r Int
d (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (LRCo LeftOrRight
lr Coercion
co) = LeftOrRight -> Coercion -> Coercion
mkLRCo LeftOrRight
lr (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (InstCo Coercion
co Coercion
arg) = (Coercion -> Coercion -> Coercion
mkInstCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
arg
go (KindCo Coercion
co) = Coercion -> Coercion
mkKindCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (SubCo Coercion
co) = Coercion -> Coercion
mkSubCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (AxiomRuleCo CoAxiomRule
c [Coercion]
cs) = let cs1 :: [Coercion]
cs1 = (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
cs
in [Coercion]
cs1 [Coercion] -> Coercion -> Coercion
forall a b. [a] -> b -> b
`seqList` CoAxiomRule -> [Coercion] -> Coercion
AxiomRuleCo CoAxiomRule
c [Coercion]
cs1
go (HoleCo CoercionHole
h) = CoercionHole -> Coercion
HoleCo (CoercionHole -> Coercion) -> CoercionHole -> Coercion
forall a b. (a -> b) -> a -> b
$! CoercionHole -> CoercionHole
go_hole CoercionHole
h
go_prov :: UnivCoProvenance -> UnivCoProvenance
go_prov (PhantomProv Coercion
kco) = Coercion -> UnivCoProvenance
PhantomProv (Coercion -> Coercion
go Coercion
kco)
go_prov (ProofIrrelProv Coercion
kco) = Coercion -> UnivCoProvenance
ProofIrrelProv (Coercion -> Coercion
go Coercion
kco)
go_prov p :: UnivCoProvenance
p@(PluginProv String
_) = UnivCoProvenance
p
go_prov p :: UnivCoProvenance
p@UnivCoProvenance
CorePrepProv = UnivCoProvenance
p
go_hole :: CoercionHole -> CoercionHole
go_hole h :: CoercionHole
h@(CoercionHole { ch_co_var :: CoercionHole -> TyCoVar
ch_co_var = TyCoVar
cv })
= CoercionHole
h { ch_co_var :: TyCoVar
ch_co_var = (Type -> Type) -> TyCoVar -> TyCoVar
updateVarType Type -> Type
go_ty TyCoVar
cv }
substForAllCoBndr :: TCvSubst -> TyCoVar -> KindCoercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndr :: TCvSubst -> TyCoVar -> Coercion -> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndr TCvSubst
subst
= Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> TyCoVar
-> Coercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndrUsing Bool
False (HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo TCvSubst
subst) TCvSubst
subst
substForAllCoBndrUnchecked :: TCvSubst -> TyCoVar -> KindCoercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndrUnchecked :: TCvSubst -> TyCoVar -> Coercion -> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndrUnchecked TCvSubst
subst
= Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> TyCoVar
-> Coercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndrUsing Bool
False (TCvSubst -> Coercion -> Coercion
substCoUnchecked TCvSubst
subst) TCvSubst
subst
substForAllCoBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst -> TyCoVar -> KindCoercion
-> (TCvSubst, TyCoVar, KindCoercion)
substForAllCoBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> TyCoVar
-> Coercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndrUsing Bool
sym Coercion -> Coercion
sco TCvSubst
subst TyCoVar
old_var
| TyCoVar -> Bool
isTyVar TyCoVar
old_var = Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> TyCoVar
-> Coercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoTyVarBndrUsing Bool
sym Coercion -> Coercion
sco TCvSubst
subst TyCoVar
old_var
| Bool
otherwise = Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> TyCoVar
-> Coercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoCoVarBndrUsing Bool
sym Coercion -> Coercion
sco TCvSubst
subst TyCoVar
old_var
substForAllCoTyVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst -> TyVar -> KindCoercion
-> (TCvSubst, TyVar, KindCoercion)
substForAllCoTyVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> TyCoVar
-> Coercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoTyVarBndrUsing Bool
sym Coercion -> Coercion
sco (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
old_var Coercion
old_kind_co
= ASSERT( isTyVar old_var )
( InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> TyCoVar -> InScopeSet
`extendInScopeSet` TyCoVar
new_var) TvSubstEnv
new_env CvSubstEnv
cenv
, TyCoVar
new_var, Coercion
new_kind_co )
where
new_env :: TvSubstEnv
new_env | Bool
no_change Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
sym = TvSubstEnv -> TyCoVar -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> VarEnv a
delVarEnv TvSubstEnv
tenv TyCoVar
old_var
| Bool
sym = TvSubstEnv -> TyCoVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv TyCoVar
old_var (Type -> TvSubstEnv) -> Type -> TvSubstEnv
forall a b. (a -> b) -> a -> b
$
TyCoVar -> Type
TyVarTy TyCoVar
new_var Type -> Coercion -> Type
`CastTy` Coercion
new_kind_co
| Bool
otherwise = TvSubstEnv -> TyCoVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv TyCoVar
old_var (TyCoVar -> Type
TyVarTy TyCoVar
new_var)
no_kind_change :: Bool
no_kind_change = Coercion -> Bool
noFreeVarsOfCo Coercion
old_kind_co
no_change :: Bool
no_change = Bool
no_kind_change Bool -> Bool -> Bool
&& (TyCoVar
new_var TyCoVar -> TyCoVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyCoVar
old_var)
new_kind_co :: Coercion
new_kind_co | Bool
no_kind_change = Coercion
old_kind_co
| Bool
otherwise = Coercion -> Coercion
sco Coercion
old_kind_co
new_ki1 :: Type
new_ki1 = Coercion -> Type
coercionLKind Coercion
new_kind_co
new_var :: TyCoVar
new_var = InScopeSet -> TyCoVar -> TyCoVar
uniqAway InScopeSet
in_scope (TyCoVar -> Type -> TyCoVar
setTyVarKind TyCoVar
old_var Type
new_ki1)
substForAllCoCoVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst -> CoVar -> KindCoercion
-> (TCvSubst, CoVar, KindCoercion)
substForAllCoCoVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> TyCoVar
-> Coercion
-> (TCvSubst, TyCoVar, Coercion)
substForAllCoCoVarBndrUsing Bool
sym Coercion -> Coercion
sco (TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv)
TyCoVar
old_var Coercion
old_kind_co
= ASSERT( isCoVar old_var )
( InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> TyCoVar -> InScopeSet
`extendInScopeSet` TyCoVar
new_var) TvSubstEnv
tenv CvSubstEnv
new_cenv
, TyCoVar
new_var, Coercion
new_kind_co )
where
new_cenv :: CvSubstEnv
new_cenv | Bool
no_change Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
sym = CvSubstEnv -> TyCoVar -> CvSubstEnv
forall a. VarEnv a -> TyCoVar -> VarEnv a
delVarEnv CvSubstEnv
cenv TyCoVar
old_var
| Bool
otherwise = CvSubstEnv -> TyCoVar -> Coercion -> CvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv CvSubstEnv
cenv TyCoVar
old_var (TyCoVar -> Coercion
mkCoVarCo TyCoVar
new_var)
no_kind_change :: Bool
no_kind_change = Coercion -> Bool
noFreeVarsOfCo Coercion
old_kind_co
no_change :: Bool
no_change = Bool
no_kind_change Bool -> Bool -> Bool
&& (TyCoVar
new_var TyCoVar -> TyCoVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyCoVar
old_var)
new_kind_co :: Coercion
new_kind_co | Bool
no_kind_change = Coercion
old_kind_co
| Bool
otherwise = Coercion -> Coercion
sco Coercion
old_kind_co
Pair Type
h1 Type
h2 = Coercion -> Pair Type
coercionKind Coercion
new_kind_co
new_var :: TyCoVar
new_var = InScopeSet -> TyCoVar -> TyCoVar
uniqAway InScopeSet
in_scope (TyCoVar -> TyCoVar) -> TyCoVar -> TyCoVar
forall a b. (a -> b) -> a -> b
$ Name -> Type -> TyCoVar
mkCoVar (TyCoVar -> Name
varName TyCoVar
old_var) Type
new_var_type
new_var_type :: Type
new_var_type | Bool
sym = Type
h2
| Bool
otherwise = Type
h1
substCoVar :: TCvSubst -> CoVar -> Coercion
substCoVar :: TCvSubst -> TyCoVar -> Coercion
substCoVar (TCvSubst InScopeSet
_ TvSubstEnv
_ CvSubstEnv
cenv) TyCoVar
cv
= case CvSubstEnv -> TyCoVar -> Maybe Coercion
forall a. VarEnv a -> TyCoVar -> Maybe a
lookupVarEnv CvSubstEnv
cenv TyCoVar
cv of
Just Coercion
co -> Coercion
co
Maybe Coercion
Nothing -> TyCoVar -> Coercion
CoVarCo TyCoVar
cv
substCoVars :: TCvSubst -> [CoVar] -> [Coercion]
substCoVars :: TCvSubst -> [TyCoVar] -> [Coercion]
substCoVars TCvSubst
subst [TyCoVar]
cvs = (TyCoVar -> Coercion) -> [TyCoVar] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> TyCoVar -> Coercion
substCoVar TCvSubst
subst) [TyCoVar]
cvs
lookupCoVar :: TCvSubst -> Var -> Maybe Coercion
lookupCoVar :: TCvSubst -> TyCoVar -> Maybe Coercion
lookupCoVar (TCvSubst InScopeSet
_ TvSubstEnv
_ CvSubstEnv
cenv) TyCoVar
v = CvSubstEnv -> TyCoVar -> Maybe Coercion
forall a. VarEnv a -> TyCoVar -> Maybe a
lookupVarEnv CvSubstEnv
cenv TyCoVar
v
substTyVarBndr :: HasCallStack => TCvSubst -> TyVar -> (TCvSubst, TyVar)
substTyVarBndr :: HasCallStack => TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substTyVarBndr = (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substTyVarBndrUsing HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy
substTyVarBndrs :: HasCallStack => TCvSubst -> [TyVar] -> (TCvSubst, [TyVar])
substTyVarBndrs :: HasCallStack => TCvSubst -> [TyCoVar] -> (TCvSubst, [TyCoVar])
substTyVarBndrs = (TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar))
-> TCvSubst -> [TyCoVar] -> (TCvSubst, [TyCoVar])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL HasCallStack => TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substTyVarBndr
substVarBndr :: HasCallStack => TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndr :: HasCallStack => TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndr = (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUsing HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy
substVarBndrs :: HasCallStack => TCvSubst -> [TyCoVar] -> (TCvSubst, [TyCoVar])
substVarBndrs :: HasCallStack => TCvSubst -> [TyCoVar] -> (TCvSubst, [TyCoVar])
substVarBndrs = (TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar))
-> TCvSubst -> [TyCoVar] -> (TCvSubst, [TyCoVar])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL HasCallStack => TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndr
substCoVarBndr :: HasCallStack => TCvSubst -> CoVar -> (TCvSubst, CoVar)
substCoVarBndr :: HasCallStack => TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substCoVarBndr = (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substCoVarBndrUsing HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy
substVarBndrUnchecked :: TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUnchecked :: TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUnchecked = (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUsing TCvSubst -> Type -> Type
substTyUnchecked
substVarBndrUsing :: (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUsing :: (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUsing TCvSubst -> Type -> Type
subst_fn TCvSubst
subst TyCoVar
v
| TyCoVar -> Bool
isTyVar TyCoVar
v = (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substTyVarBndrUsing TCvSubst -> Type -> Type
subst_fn TCvSubst
subst TyCoVar
v
| Bool
otherwise = (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substCoVarBndrUsing TCvSubst -> Type -> Type
subst_fn TCvSubst
subst TyCoVar
v
substTyVarBndrUsing
:: (TCvSubst -> Type -> Type)
-> TCvSubst -> TyVar -> (TCvSubst, TyVar)
substTyVarBndrUsing :: (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substTyVarBndrUsing TCvSubst -> Type -> Type
subst_fn subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
old_var
= ASSERT2( _no_capture, pprTyVar old_var $$ pprTyVar new_var $$ ppr subst )
ASSERT( isTyVar old_var )
(InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> TyCoVar -> InScopeSet
`extendInScopeSet` TyCoVar
new_var) TvSubstEnv
new_env CvSubstEnv
cenv, TyCoVar
new_var)
where
new_env :: TvSubstEnv
new_env | Bool
no_change = TvSubstEnv -> TyCoVar -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> VarEnv a
delVarEnv TvSubstEnv
tenv TyCoVar
old_var
| Bool
otherwise = TvSubstEnv -> TyCoVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv TyCoVar
old_var (TyCoVar -> Type
TyVarTy TyCoVar
new_var)
_no_capture :: Bool
_no_capture = Bool -> Bool
not (TyCoVar
new_var TyCoVar -> VarSet -> Bool
`elemVarSet` TvSubstEnv -> VarSet
shallowTyCoVarsOfTyVarEnv TvSubstEnv
tenv)
old_ki :: Type
old_ki = TyCoVar -> Type
tyVarKind TyCoVar
old_var
no_kind_change :: Bool
no_kind_change = Type -> Bool
noFreeVarsOfType Type
old_ki
no_change :: Bool
no_change = Bool
no_kind_change Bool -> Bool -> Bool
&& (TyCoVar
new_var TyCoVar -> TyCoVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyCoVar
old_var)
new_var :: TyCoVar
new_var | Bool
no_kind_change = InScopeSet -> TyCoVar -> TyCoVar
uniqAway InScopeSet
in_scope TyCoVar
old_var
| Bool
otherwise = InScopeSet -> TyCoVar -> TyCoVar
uniqAway InScopeSet
in_scope (TyCoVar -> TyCoVar) -> TyCoVar -> TyCoVar
forall a b. (a -> b) -> a -> b
$
TyCoVar -> Type -> TyCoVar
setTyVarKind TyCoVar
old_var (TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Type
old_ki)
substCoVarBndrUsing
:: (TCvSubst -> Type -> Type)
-> TCvSubst -> CoVar -> (TCvSubst, CoVar)
substCoVarBndrUsing :: (TCvSubst -> Type -> Type)
-> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substCoVarBndrUsing TCvSubst -> Type -> Type
subst_fn subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TvSubstEnv
tenv CvSubstEnv
cenv) TyCoVar
old_var
= ASSERT( isCoVar old_var )
(InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> TyCoVar -> InScopeSet
`extendInScopeSet` TyCoVar
new_var) TvSubstEnv
tenv CvSubstEnv
new_cenv, TyCoVar
new_var)
where
new_co :: Coercion
new_co = TyCoVar -> Coercion
mkCoVarCo TyCoVar
new_var
no_kind_change :: Bool
no_kind_change = [Type] -> Bool
noFreeVarsOfTypes [Type
t1, Type
t2]
no_change :: Bool
no_change = TyCoVar
new_var TyCoVar -> TyCoVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyCoVar
old_var Bool -> Bool -> Bool
&& Bool
no_kind_change
new_cenv :: CvSubstEnv
new_cenv | Bool
no_change = CvSubstEnv -> TyCoVar -> CvSubstEnv
forall a. VarEnv a -> TyCoVar -> VarEnv a
delVarEnv CvSubstEnv
cenv TyCoVar
old_var
| Bool
otherwise = CvSubstEnv -> TyCoVar -> Coercion -> CvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv CvSubstEnv
cenv TyCoVar
old_var Coercion
new_co
new_var :: TyCoVar
new_var = InScopeSet -> TyCoVar -> TyCoVar
uniqAway InScopeSet
in_scope TyCoVar
subst_old_var
subst_old_var :: TyCoVar
subst_old_var = Name -> Type -> TyCoVar
mkCoVar (TyCoVar -> Name
varName TyCoVar
old_var) Type
new_var_type
(Type
_, Type
_, Type
t1, Type
t2, Role
role) = HasDebugCallStack => TyCoVar -> (Type, Type, Type, Type, Role)
TyCoVar -> (Type, Type, Type, Type, Role)
coVarKindsTypesRole TyCoVar
old_var
t1' :: Type
t1' = TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Type
t1
t2' :: Type
t2' = TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Type
t2
new_var_type :: Type
new_var_type = Role -> Type -> Type -> Type
mkCoercionType Role
role Type
t1' Type
t2'
cloneTyVarBndr :: TCvSubst -> TyVar -> Unique -> (TCvSubst, TyVar)
cloneTyVarBndr :: TCvSubst -> TyCoVar -> Unique -> (TCvSubst, TyCoVar)
cloneTyVarBndr subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TvSubstEnv
tv_env CvSubstEnv
cv_env) TyCoVar
tv Unique
uniq
= ASSERT2( isTyVar tv, ppr tv )
(InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst (InScopeSet -> TyCoVar -> InScopeSet
extendInScopeSet InScopeSet
in_scope TyCoVar
tv')
(TvSubstEnv -> TyCoVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyCoVar -> a -> VarEnv a
extendVarEnv TvSubstEnv
tv_env TyCoVar
tv (TyCoVar -> Type
mkTyVarTy TyCoVar
tv')) CvSubstEnv
cv_env, TyCoVar
tv')
where
old_ki :: Type
old_ki = TyCoVar -> Type
tyVarKind TyCoVar
tv
no_kind_change :: Bool
no_kind_change = Type -> Bool
noFreeVarsOfType Type
old_ki
tv1 :: TyCoVar
tv1 | Bool
no_kind_change = TyCoVar
tv
| Bool
otherwise = TyCoVar -> Type -> TyCoVar
setTyVarKind TyCoVar
tv (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst Type
old_ki)
tv' :: TyCoVar
tv' = TyCoVar -> Unique -> TyCoVar
setVarUnique TyCoVar
tv1 Unique
uniq
cloneTyVarBndrs :: TCvSubst -> [TyVar] -> UniqSupply -> (TCvSubst, [TyVar])
cloneTyVarBndrs :: TCvSubst -> [TyCoVar] -> UniqSupply -> (TCvSubst, [TyCoVar])
cloneTyVarBndrs TCvSubst
subst [] UniqSupply
_usupply = (TCvSubst
subst, [])
cloneTyVarBndrs TCvSubst
subst (TyCoVar
t:[TyCoVar]
ts) UniqSupply
usupply = (TCvSubst
subst'', TyCoVar
tvTyCoVar -> [TyCoVar] -> [TyCoVar]
forall a. a -> [a] -> [a]
:[TyCoVar]
tvs)
where
(Unique
uniq, UniqSupply
usupply') = UniqSupply -> (Unique, UniqSupply)
takeUniqFromSupply UniqSupply
usupply
(TCvSubst
subst' , TyCoVar
tv ) = TCvSubst -> TyCoVar -> Unique -> (TCvSubst, TyCoVar)
cloneTyVarBndr TCvSubst
subst TyCoVar
t Unique
uniq
(TCvSubst
subst'', [TyCoVar]
tvs) = TCvSubst -> [TyCoVar] -> UniqSupply -> (TCvSubst, [TyCoVar])
cloneTyVarBndrs TCvSubst
subst' [TyCoVar]
ts UniqSupply
usupply'