{-# LANGUAGE BangPatterns #-}
module GHC.Core.TyCo.Subst
(
Subst(..), TvSubstEnv, CvSubstEnv, IdSubstEnv,
emptyIdSubstEnv, emptyTvSubstEnv, emptyCvSubstEnv, composeTCvSubst,
emptySubst, mkEmptySubst, isEmptyTCvSubst, isEmptySubst,
mkSubst, mkTvSubst, mkCvSubst, mkIdSubst,
getTvSubstEnv, getIdSubstEnv,
getCvSubstEnv, getSubstInScope, setInScope, getSubstRangeTyCoFVs,
isInScope, elemSubst, notElemSubst, zapSubst,
extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet,
extendTCvSubst, extendTCvSubstWithClone,
extendCvSubst, extendCvSubstWithClone,
extendTvSubst, extendTvSubstBinderAndInScope, extendTvSubstWithClone,
extendTvSubstList, extendTvSubstAndInScope,
extendTCvSubstList,
unionSubst, 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, substTyVarToTyVar,
substTyCoVars,
substTyCoBndr, substForAllCoBndr,
substVarBndrUsing, substForAllCoBndrUsing,
checkValidSubst, isValidTCvSubst,
) where
import GHC.Prelude
import {-# SOURCE #-} GHC.Core.Type
( mkCastTy, mkAppTy, isCoercionTy, mkTyConApp, getTyVar_maybe )
import {-# SOURCE #-} GHC.Core.Coercion
( mkCoVarCo, mkKindCo, mkSelCo, mkTransCo
, mkNomReflCo, mkSubCo, mkSymCo
, mkFunCo2, mkForAllCo, mkUnivCo
, mkAxiomInstCo, mkAppCo, mkGReflCo
, mkInstCo, mkLRCo, mkTyConAppCo
, mkCoercionType
, coercionKind, coercionLKind, coVarKindsTypesRole )
import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprTyVar )
import {-# SOURCE #-} GHC.Core.Ppr ( )
import {-# SOURCE #-} GHC.Core ( CoreExpr )
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.Constants (debugIsOn)
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 GHC.Utils.Panic
import GHC.Utils.Panic.Plain
import Data.List (mapAccumL)
data Subst
= Subst InScopeSet
IdSubstEnv
TvSubstEnv
CvSubstEnv
type IdSubstEnv = IdEnv CoreExpr
type TvSubstEnv = TyVarEnv Type
type CvSubstEnv = CoVarEnv Coercion
emptyIdSubstEnv :: IdSubstEnv
emptyIdSubstEnv :: IdSubstEnv
emptyIdSubstEnv = forall a. VarEnv a
emptyVarEnv
emptyTvSubstEnv :: TvSubstEnv
emptyTvSubstEnv :: TvSubstEnv
emptyTvSubstEnv = forall a. VarEnv a
emptyVarEnv
emptyCvSubstEnv :: CvSubstEnv
emptyCvSubstEnv :: CvSubstEnv
emptyCvSubstEnv = forall a. VarEnv a
emptyVarEnv
composeTCvSubst :: Subst -> Subst -> Subst
composeTCvSubst :: Subst -> Subst -> Subst
composeTCvSubst subst1 :: Subst
subst1@(Subst InScopeSet
is1 IdSubstEnv
ids1 TvSubstEnv
tenv1 CvSubstEnv
cenv1) (Subst InScopeSet
is2 IdSubstEnv
_ TvSubstEnv
tenv2 CvSubstEnv
cenv2)
= InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
is3 IdSubstEnv
ids1 TvSubstEnv
tenv3 CvSubstEnv
cenv3
where
is3 :: InScopeSet
is3 = InScopeSet
is1 InScopeSet -> InScopeSet -> InScopeSet
`unionInScope` InScopeSet
is2
tenv3 :: TvSubstEnv
tenv3 = TvSubstEnv
tenv1 forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (HasDebugCallStack => Subst -> Type -> Type
substTy Subst
extended_subst1) TvSubstEnv
tenv2
cenv3 :: CvSubstEnv
cenv3 = CvSubstEnv
cenv1 forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (HasDebugCallStack => Subst -> Coercion -> Coercion
substCo Subst
extended_subst1) CvSubstEnv
cenv2
extended_subst1 :: Subst
extended_subst1 = Subst
subst1 Subst -> InScopeSet -> Subst
`setInScope` InScopeSet
is3
emptySubst :: Subst
emptySubst :: Subst
emptySubst = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
emptyInScopeSet forall a. VarEnv a
emptyVarEnv forall a. VarEnv a
emptyVarEnv forall a. VarEnv a
emptyVarEnv
mkEmptySubst :: InScopeSet -> Subst
mkEmptySubst :: InScopeSet -> Subst
mkEmptySubst InScopeSet
in_scope = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope forall a. VarEnv a
emptyVarEnv forall a. VarEnv a
emptyVarEnv forall a. VarEnv a
emptyVarEnv
isEmptySubst :: Subst -> Bool
isEmptySubst :: Subst -> Bool
isEmptySubst (Subst InScopeSet
_ IdSubstEnv
id_env TvSubstEnv
tv_env CvSubstEnv
cv_env)
= forall a. VarEnv a -> Bool
isEmptyVarEnv IdSubstEnv
id_env Bool -> Bool -> Bool
&& forall a. VarEnv a -> Bool
isEmptyVarEnv TvSubstEnv
tv_env Bool -> Bool -> Bool
&& forall a. VarEnv a -> Bool
isEmptyVarEnv CvSubstEnv
cv_env
isEmptyTCvSubst :: Subst -> Bool
isEmptyTCvSubst :: Subst -> Bool
isEmptyTCvSubst (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
tv_env CvSubstEnv
cv_env)
= forall a. VarEnv a -> Bool
isEmptyVarEnv TvSubstEnv
tv_env Bool -> Bool -> Bool
&& forall a. VarEnv a -> Bool
isEmptyVarEnv CvSubstEnv
cv_env
mkSubst :: InScopeSet -> TvSubstEnv -> CvSubstEnv -> IdSubstEnv -> Subst
mkSubst :: InScopeSet -> TvSubstEnv -> CvSubstEnv -> IdSubstEnv -> Subst
mkSubst InScopeSet
in_scope TvSubstEnv
tvs CvSubstEnv
cvs IdSubstEnv
ids = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs
mkIdSubst :: InScopeSet -> IdSubstEnv -> Subst
mkIdSubst :: InScopeSet -> IdSubstEnv -> Subst
mkIdSubst InScopeSet
in_scope IdSubstEnv
ids = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
emptyTvSubstEnv CvSubstEnv
emptyCvSubstEnv
mkTvSubst :: InScopeSet -> TvSubstEnv -> Subst
mkTvSubst :: InScopeSet -> TvSubstEnv -> Subst
mkTvSubst InScopeSet
in_scope TvSubstEnv
tenv = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope IdSubstEnv
emptyIdSubstEnv TvSubstEnv
tenv CvSubstEnv
emptyCvSubstEnv
mkCvSubst :: InScopeSet -> CvSubstEnv -> Subst
mkCvSubst :: InScopeSet -> CvSubstEnv -> Subst
mkCvSubst InScopeSet
in_scope CvSubstEnv
cenv = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope IdSubstEnv
emptyIdSubstEnv TvSubstEnv
emptyTvSubstEnv CvSubstEnv
cenv
getIdSubstEnv :: Subst -> IdSubstEnv
getIdSubstEnv :: Subst -> IdSubstEnv
getIdSubstEnv (Subst InScopeSet
_ IdSubstEnv
ids TvSubstEnv
_ CvSubstEnv
_) = IdSubstEnv
ids
getTvSubstEnv :: Subst -> TvSubstEnv
getTvSubstEnv :: Subst -> TvSubstEnv
getTvSubstEnv (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
tenv CvSubstEnv
_) = TvSubstEnv
tenv
getCvSubstEnv :: Subst -> CvSubstEnv
getCvSubstEnv :: Subst -> CvSubstEnv
getCvSubstEnv (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
_ CvSubstEnv
cenv) = CvSubstEnv
cenv
getSubstInScope :: Subst -> InScopeSet
getSubstInScope :: Subst -> InScopeSet
getSubstInScope (Subst InScopeSet
in_scope IdSubstEnv
_ TvSubstEnv
_ CvSubstEnv
_) = InScopeSet
in_scope
setInScope :: Subst -> InScopeSet -> Subst
setInScope :: Subst -> InScopeSet -> Subst
setInScope (Subst InScopeSet
_ IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs) InScopeSet
in_scope = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs
getSubstRangeTyCoFVs :: Subst -> VarSet
getSubstRangeTyCoFVs :: Subst -> VarSet
getSubstRangeTyCoFVs (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
tenv CvSubstEnv
cenv)
= VarSet
tenvFVs VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
cenvFVs
where
tenvFVs :: VarSet
tenvFVs = TvSubstEnv -> VarSet
shallowTyCoVarsOfTyVarEnv TvSubstEnv
tenv
cenvFVs :: VarSet
cenvFVs = CvSubstEnv -> VarSet
shallowTyCoVarsOfCoVarEnv CvSubstEnv
cenv
isInScope :: Var -> Subst -> Bool
isInScope :: Var -> Subst -> Bool
isInScope Var
v (Subst InScopeSet
in_scope IdSubstEnv
_ TvSubstEnv
_ CvSubstEnv
_) = Var
v Var -> InScopeSet -> Bool
`elemInScopeSet` InScopeSet
in_scope
elemSubst :: Var -> Subst -> Bool
elemSubst :: Var -> Subst -> Bool
elemSubst Var
v (Subst InScopeSet
_ IdSubstEnv
ids TvSubstEnv
tenv CvSubstEnv
cenv)
| Var -> Bool
isTyVar Var
v
= Var
v forall a. Var -> VarEnv a -> Bool
`elemVarEnv` TvSubstEnv
tenv
| Var -> Bool
isCoVar Var
v
= Var
v forall a. Var -> VarEnv a -> Bool
`elemVarEnv` CvSubstEnv
cenv
| Bool
otherwise
= Var
v forall a. Var -> VarEnv a -> Bool
`elemVarEnv` IdSubstEnv
ids
notElemSubst :: Var -> Subst -> Bool
notElemSubst :: Var -> Subst -> Bool
notElemSubst Var
v = Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Var -> Subst -> Bool
elemSubst Var
v
zapSubst :: Subst -> Subst
zapSubst :: Subst -> Subst
zapSubst (Subst InScopeSet
in_scope IdSubstEnv
_ TvSubstEnv
_ CvSubstEnv
_) = InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope forall a. VarEnv a
emptyVarEnv forall a. VarEnv a
emptyVarEnv forall a. VarEnv a
emptyVarEnv
extendSubstInScope :: Subst -> Var -> Subst
extendSubstInScope :: Subst -> Var -> Subst
extendSubstInScope (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs) Var
v
= InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> Var -> InScopeSet
`extendInScopeSet` Var
v)
IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs
extendSubstInScopeList :: Subst -> [Var] -> Subst
extendSubstInScopeList :: Subst -> [Var] -> Subst
extendSubstInScopeList (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs) [Var]
vs
= InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> [Var] -> InScopeSet
`extendInScopeSetList` [Var]
vs)
IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs
extendSubstInScopeSet :: Subst -> VarSet -> Subst
extendSubstInScopeSet :: Subst -> VarSet -> Subst
extendSubstInScopeSet (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs) VarSet
vs
= InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> VarSet -> InScopeSet
`extendInScopeSetSet` VarSet
vs)
IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs
extendTCvSubst :: Subst -> TyCoVar -> Type -> Subst
extendTCvSubst :: Subst -> Var -> Type -> Subst
extendTCvSubst Subst
subst Var
v Type
ty
| Var -> Bool
isTyVar Var
v
= Subst -> Var -> Type -> Subst
extendTvSubst Subst
subst Var
v Type
ty
| CoercionTy Coercion
co <- Type
ty
= Subst -> Var -> Coercion -> Subst
extendCvSubst Subst
subst Var
v Coercion
co
| Bool
otherwise
= forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"extendTCvSubst" (forall a. Outputable a => a -> SDoc
ppr Var
v forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
"|->" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Type
ty)
extendTCvSubstWithClone :: Subst -> TyCoVar -> TyCoVar -> Subst
extendTCvSubstWithClone :: Subst -> Var -> Var -> Subst
extendTCvSubstWithClone Subst
subst Var
tcv
| Var -> Bool
isTyVar Var
tcv = Subst -> Var -> Var -> Subst
extendTvSubstWithClone Subst
subst Var
tcv
| Bool
otherwise = Subst -> Var -> Var -> Subst
extendCvSubstWithClone Subst
subst Var
tcv
extendTvSubst :: Subst -> TyVar -> Type -> Subst
extendTvSubst :: Subst -> Var -> Type -> Subst
extendTvSubst (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs) Var
tv Type
ty
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
tv) forall a b. (a -> b) -> a -> b
$
InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope IdSubstEnv
ids (forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tvs Var
tv Type
ty) CvSubstEnv
cvs
extendTvSubstBinderAndInScope :: Subst -> PiTyBinder -> Type -> Subst
extendTvSubstBinderAndInScope :: Subst -> PiTyBinder -> Type -> Subst
extendTvSubstBinderAndInScope Subst
subst (Named (Bndr Var
v ForAllTyFlag
_)) Type
ty
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
v )
Subst -> Var -> Type -> Subst
extendTvSubstAndInScope Subst
subst Var
v Type
ty
extendTvSubstBinderAndInScope Subst
subst (Anon {}) Type
_
= Subst
subst
extendTvSubstWithClone :: Subst -> TyVar -> TyVar -> Subst
extendTvSubstWithClone :: Subst -> Var -> Var -> Subst
extendTvSubstWithClone (Subst InScopeSet
in_scope IdSubstEnv
idenv TvSubstEnv
tenv CvSubstEnv
cenv) Var
tv Var
tv'
= InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet -> Var -> InScopeSet
extendInScopeSet InScopeSet
in_scope Var
tv')
IdSubstEnv
idenv
(forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv Var
tv (Var -> Type
mkTyVarTy Var
tv'))
CvSubstEnv
cenv
extendCvSubst :: Subst -> CoVar -> Coercion -> Subst
extendCvSubst :: Subst -> Var -> Coercion -> Subst
extendCvSubst (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs) Var
v Coercion
r
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isCoVar Var
v) forall a b. (a -> b) -> a -> b
$
InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs (forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv CvSubstEnv
cvs Var
v Coercion
r)
extendCvSubstWithClone :: Subst -> CoVar -> CoVar -> Subst
extendCvSubstWithClone :: Subst -> Var -> Var -> Subst
extendCvSubstWithClone (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tenv CvSubstEnv
cenv) Var
cv Var
cv'
= InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet -> VarSet -> InScopeSet
extendInScopeSetSet InScopeSet
in_scope VarSet
new_in_scope)
IdSubstEnv
ids
TvSubstEnv
tenv
(forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv CvSubstEnv
cenv Var
cv (Var -> Coercion
mkCoVarCo Var
cv'))
where
new_in_scope :: VarSet
new_in_scope = Type -> VarSet
tyCoVarsOfType (Var -> Type
varType Var
cv') VarSet -> Var -> VarSet
`extendVarSet` Var
cv'
extendTvSubstAndInScope :: Subst -> TyVar -> Type -> Subst
extendTvSubstAndInScope :: Subst -> Var -> Type -> Subst
extendTvSubstAndInScope (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tenv CvSubstEnv
cenv) Var
tv Type
ty
= InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> VarSet -> InScopeSet
`extendInScopeSetSet` Type -> VarSet
tyCoVarsOfType Type
ty)
IdSubstEnv
ids
(forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv Var
tv Type
ty)
CvSubstEnv
cenv
extendTvSubstList :: Subst -> [(TyVar,Type)] -> Subst
extendTvSubstList :: Subst -> [(Var, Type)] -> Subst
extendTvSubstList Subst
subst [(Var, Type)]
vrs
= forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Subst -> (Var, Type) -> Subst
extend Subst
subst [(Var, Type)]
vrs
where
extend :: Subst -> (Var, Type) -> Subst
extend Subst
subst (Var
v, Type
r) = Subst -> Var -> Type -> Subst
extendTvSubst Subst
subst Var
v Type
r
extendTCvSubstList :: Subst -> [Var] -> [Type] -> Subst
extendTCvSubstList :: Subst -> [Var] -> [Type] -> Subst
extendTCvSubstList Subst
subst [Var]
tvs [Type]
tys
= forall acc a b. (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 Subst -> Var -> Type -> Subst
extendTCvSubst Subst
subst [Var]
tvs [Type]
tys
unionSubst :: Subst -> Subst -> Subst
unionSubst :: Subst -> Subst -> Subst
unionSubst (Subst InScopeSet
in_scope1 IdSubstEnv
ids1 TvSubstEnv
tenv1 CvSubstEnv
cenv1) (Subst InScopeSet
in_scope2 IdSubstEnv
ids2 TvSubstEnv
tenv2 CvSubstEnv
cenv2)
= forall a. HasCallStack => Bool -> a -> a
assert (IdSubstEnv
ids1 forall a. VarEnv a -> VarEnv a -> Bool
`disjointVarEnv` IdSubstEnv
ids2
Bool -> Bool -> Bool
&& TvSubstEnv
tenv1 forall a. VarEnv a -> VarEnv a -> Bool
`disjointVarEnv` TvSubstEnv
tenv2
Bool -> Bool -> Bool
&& CvSubstEnv
cenv1 forall a. VarEnv a -> VarEnv a -> Bool
`disjointVarEnv` CvSubstEnv
cenv2 )
InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope1 InScopeSet -> InScopeSet -> InScopeSet
`unionInScope` InScopeSet
in_scope2)
(IdSubstEnv
ids1 forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` IdSubstEnv
ids2)
(TvSubstEnv
tenv1 forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` TvSubstEnv
tenv2)
(CvSubstEnv
cenv1 forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` CvSubstEnv
cenv2)
zipTvSubst :: HasDebugCallStack => [TyVar] -> [Type] -> Subst
zipTvSubst :: HasDebugCallStack => [Var] -> [Type] -> Subst
zipTvSubst [Var]
tvs [Type]
tys
= InScopeSet -> TvSubstEnv -> Subst
mkTvSubst (VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet
shallowTyCoVarsOfTypes [Type]
tys)) TvSubstEnv
tenv
where
tenv :: TvSubstEnv
tenv = HasDebugCallStack => [Var] -> [Type] -> TvSubstEnv
zipTyEnv [Var]
tvs [Type]
tys
zipCvSubst :: HasDebugCallStack => [CoVar] -> [Coercion] -> Subst
zipCvSubst :: HasDebugCallStack => [Var] -> [Coercion] -> Subst
zipCvSubst [Var]
cvs [Coercion]
cos
= InScopeSet -> CvSubstEnv -> Subst
mkCvSubst (VarSet -> InScopeSet
mkInScopeSet ([Coercion] -> VarSet
shallowTyCoVarsOfCos [Coercion]
cos)) CvSubstEnv
cenv
where
cenv :: CvSubstEnv
cenv = HasDebugCallStack => [Var] -> [Coercion] -> CvSubstEnv
zipCoEnv [Var]
cvs [Coercion]
cos
zipTCvSubst :: HasDebugCallStack => [TyCoVar] -> [Type] -> Subst
zipTCvSubst :: HasDebugCallStack => [Var] -> [Type] -> Subst
zipTCvSubst [Var]
tcvs [Type]
tys
= [Var] -> [Type] -> Subst -> Subst
zip_tcvsubst [Var]
tcvs [Type]
tys forall a b. (a -> b) -> a -> b
$
InScopeSet -> Subst
mkEmptySubst forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet forall a b. (a -> b) -> a -> b
$ [Type] -> VarSet
shallowTyCoVarsOfTypes [Type]
tys
where zip_tcvsubst :: [TyCoVar] -> [Type] -> Subst -> Subst
zip_tcvsubst :: [Var] -> [Type] -> Subst -> Subst
zip_tcvsubst (Var
tv:[Var]
tvs) (Type
ty:[Type]
tys) Subst
subst
= [Var] -> [Type] -> Subst -> Subst
zip_tcvsubst [Var]
tvs [Type]
tys (Subst -> Var -> Type -> Subst
extendTCvSubst Subst
subst Var
tv Type
ty)
zip_tcvsubst [] [] Subst
subst = Subst
subst
zip_tcvsubst [Var]
_ [Type]
_ Subst
_ = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipTCvSubst: length mismatch"
(forall a. Outputable a => a -> SDoc
ppr [Var]
tcvs forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [Type]
tys)
mkTvSubstPrs :: [(TyVar, Type)] -> Subst
mkTvSubstPrs :: [(Var, Type)] -> Subst
mkTvSubstPrs [] = Subst
emptySubst
mkTvSubstPrs [(Var, Type)]
prs =
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr Bool
onlyTyVarsAndNoCoercionTy (forall doc. IsLine doc => String -> doc
text String
"prs" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [(Var, Type)]
prs) forall a b. (a -> b) -> a -> b
$
InScopeSet -> TvSubstEnv -> Subst
mkTvSubst InScopeSet
in_scope TvSubstEnv
tenv
where tenv :: TvSubstEnv
tenv = forall a. [(Var, a)] -> VarEnv a
mkVarEnv [(Var, Type)]
prs
in_scope :: InScopeSet
in_scope = VarSet -> InScopeSet
mkInScopeSet forall a b. (a -> b) -> a -> b
$ [Type] -> VarSet
shallowTyCoVarsOfTypes forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(Var, Type)]
prs
onlyTyVarsAndNoCoercionTy :: Bool
onlyTyVarsAndNoCoercionTy =
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ Var -> Bool
isTyVar Var
tv Bool -> Bool -> Bool
&& Bool -> Bool
not (Type -> Bool
isCoercionTy Type
ty)
| (Var
tv, Type
ty) <- [(Var, Type)]
prs ]
zipTyEnv :: HasDebugCallStack => [TyVar] -> [Type] -> TvSubstEnv
zipTyEnv :: HasDebugCallStack => [Var] -> [Type] -> TvSubstEnv
zipTyEnv [Var]
tyvars [Type]
tys
| Bool
debugIsOn
, Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Var -> Bool
isTyVar [Var]
tyvars Bool -> Bool -> Bool
&& ([Var]
tyvars forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys))
= forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipTyEnv" (forall a. Outputable a => a -> SDoc
ppr [Var]
tyvars forall doc. IsDoc doc => doc -> doc -> doc
$$ forall a. Outputable a => a -> SDoc
ppr [Type]
tys)
| Bool
otherwise
= forall a. HasCallStack => Bool -> a -> a
assert (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Bool
isCoercionTy) [Type]
tys )
forall key elt. Uniquable key => [key] -> [elt] -> UniqFM key elt
zipToUFM [Var]
tyvars [Type]
tys
zipCoEnv :: HasDebugCallStack => [CoVar] -> [Coercion] -> CvSubstEnv
zipCoEnv :: HasDebugCallStack => [Var] -> [Coercion] -> CvSubstEnv
zipCoEnv [Var]
cvs [Coercion]
cos
| Bool
debugIsOn
, Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Var -> Bool
isCoVar [Var]
cvs)
= forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipCoEnv" (forall a. Outputable a => a -> SDoc
ppr [Var]
cvs forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [Coercion]
cos)
| Bool
otherwise
= forall a. [(Var, a)] -> VarEnv a
mkVarEnv (forall a b. HasDebugCallStack => String -> [a] -> [b] -> [(a, b)]
zipEqual String
"zipCoEnv" [Var]
cvs [Coercion]
cos)
instance Outputable Subst where
ppr :: Subst -> SDoc
ppr (Subst InScopeSet
in_scope IdSubstEnv
ids TvSubstEnv
tvs CvSubstEnv
cvs)
= forall doc. IsLine doc => String -> doc
text String
"<InScope =" forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
in_scope_doc
forall doc. IsDoc doc => doc -> doc -> doc
$$ forall doc. IsLine doc => String -> doc
text String
" IdSubst =" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr IdSubstEnv
ids
forall doc. IsDoc doc => doc -> doc -> doc
$$ forall doc. IsLine doc => String -> doc
text String
" TvSubst =" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr TvSubstEnv
tvs
forall doc. IsDoc doc => doc -> doc -> doc
$$ forall doc. IsLine doc => String -> doc
text String
" CvSubst =" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr CvSubstEnv
cvs
forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
'>'
where
in_scope_doc :: SDoc
in_scope_doc = VarSet -> ([Var] -> SDoc) -> SDoc
pprVarSet (InScopeSet -> VarSet
getInScopeVars InScopeSet
in_scope) (forall doc. IsLine doc => doc -> doc
braces forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall doc. IsLine doc => [doc] -> doc
fsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> SDoc
ppr)
substTyWith :: HasDebugCallStack => [TyVar] -> [Type] -> Type -> Type
substTyWith :: HasDebugCallStack => [Var] -> [Type] -> Type -> Type
substTyWith [Var]
tvs [Type]
tys = {-#SCC "substTyWith" #-}
forall a. HasCallStack => Bool -> a -> a
assert ([Var]
tvs forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys )
HasDebugCallStack => Subst -> Type -> Type
substTy (HasDebugCallStack => [Var] -> [Type] -> Subst
zipTvSubst [Var]
tvs [Type]
tys)
substTyWithUnchecked :: [TyVar] -> [Type] -> Type -> Type
substTyWithUnchecked :: [Var] -> [Type] -> Type -> Type
substTyWithUnchecked [Var]
tvs [Type]
tys
= forall a. HasCallStack => Bool -> a -> a
assert ([Var]
tvs forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys )
Subst -> Type -> Type
substTyUnchecked (HasDebugCallStack => [Var] -> [Type] -> Subst
zipTvSubst [Var]
tvs [Type]
tys)
substTyWithInScope :: InScopeSet -> [TyVar] -> [Type] -> Type -> Type
substTyWithInScope :: InScopeSet -> [Var] -> [Type] -> Type -> Type
substTyWithInScope InScopeSet
in_scope [Var]
tvs [Type]
tys Type
ty =
forall a. HasCallStack => Bool -> a -> a
assert ([Var]
tvs forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys )
HasDebugCallStack => Subst -> Type -> Type
substTy (InScopeSet -> TvSubstEnv -> Subst
mkTvSubst InScopeSet
in_scope TvSubstEnv
tenv) Type
ty
where tenv :: TvSubstEnv
tenv = HasDebugCallStack => [Var] -> [Type] -> TvSubstEnv
zipTyEnv [Var]
tvs [Type]
tys
substCoWith :: HasDebugCallStack => [TyVar] -> [Type] -> Coercion -> Coercion
substCoWith :: HasDebugCallStack => [Var] -> [Type] -> Coercion -> Coercion
substCoWith [Var]
tvs [Type]
tys = forall a. HasCallStack => Bool -> a -> a
assert ([Var]
tvs forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys )
HasDebugCallStack => Subst -> Coercion -> Coercion
substCo (HasDebugCallStack => [Var] -> [Type] -> Subst
zipTvSubst [Var]
tvs [Type]
tys)
substCoWithUnchecked :: [TyVar] -> [Type] -> Coercion -> Coercion
substCoWithUnchecked :: [Var] -> [Type] -> Coercion -> Coercion
substCoWithUnchecked [Var]
tvs [Type]
tys
= forall a. HasCallStack => Bool -> a -> a
assert ([Var]
tvs forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys )
Subst -> Coercion -> Coercion
substCoUnchecked (HasDebugCallStack => [Var] -> [Type] -> Subst
zipTvSubst [Var]
tvs [Type]
tys)
substTyWithCoVars :: [CoVar] -> [Coercion] -> Type -> Type
substTyWithCoVars :: [Var] -> [Coercion] -> Type -> Type
substTyWithCoVars [Var]
cvs [Coercion]
cos = HasDebugCallStack => Subst -> Type -> Type
substTy (HasDebugCallStack => [Var] -> [Coercion] -> Subst
zipCvSubst [Var]
cvs [Coercion]
cos)
substTysWith :: [TyVar] -> [Type] -> [Type] -> [Type]
substTysWith :: [Var] -> [Type] -> [Type] -> [Type]
substTysWith [Var]
tvs [Type]
tys = forall a. HasCallStack => Bool -> a -> a
assert ([Var]
tvs forall a b. [a] -> [b] -> Bool
`equalLength` [Type]
tys )
HasDebugCallStack => Subst -> [Type] -> [Type]
substTys (HasDebugCallStack => [Var] -> [Type] -> Subst
zipTvSubst [Var]
tvs [Type]
tys)
substTysWithCoVars :: [CoVar] -> [Coercion] -> [Type] -> [Type]
substTysWithCoVars :: [Var] -> [Coercion] -> [Type] -> [Type]
substTysWithCoVars [Var]
cvs [Coercion]
cos = forall a. HasCallStack => Bool -> a -> a
assert ([Var]
cvs forall a b. [a] -> [b] -> Bool
`equalLength` [Coercion]
cos )
HasDebugCallStack => Subst -> [Type] -> [Type]
substTys (HasDebugCallStack => [Var] -> [Coercion] -> Subst
zipCvSubst [Var]
cvs [Coercion]
cos)
substTyAddInScope :: Subst -> Type -> Type
substTyAddInScope :: Subst -> Type -> Type
substTyAddInScope Subst
subst Type
ty =
HasDebugCallStack => Subst -> Type -> Type
substTy (Subst -> VarSet -> Subst
extendSubstInScopeSet Subst
subst forall a b. (a -> b) -> a -> b
$ Type -> VarSet
tyCoVarsOfType Type
ty) Type
ty
isValidTCvSubst :: Subst -> Bool
isValidTCvSubst :: Subst -> Bool
isValidTCvSubst (Subst InScopeSet
in_scope IdSubstEnv
_ 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 :: HasDebugCallStack => Subst -> [Type] -> [Coercion] -> a -> a
checkValidSubst :: forall a.
HasDebugCallStack =>
Subst -> [Type] -> [Coercion] -> a -> a
checkValidSubst subst :: Subst
subst@(Subst InScopeSet
in_scope IdSubstEnv
_ TvSubstEnv
tenv CvSubstEnv
cenv) [Type]
tys [Coercion]
cos a
a
= forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (Subst -> Bool
isValidTCvSubst Subst
subst)
(forall doc. IsLine doc => String -> doc
text String
"in_scope" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr InScopeSet
in_scope forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"tenv" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr TvSubstEnv
tenv forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"tenvFVs" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr (TvSubstEnv -> VarSet
shallowTyCoVarsOfTyVarEnv TvSubstEnv
tenv) forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"cenv" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr CvSubstEnv
cenv forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"cenvFVs" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr (CvSubstEnv -> VarSet
shallowTyCoVarsOfCoVarEnv CvSubstEnv
cenv) forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"tys" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [Type]
tys forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"cos" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [Coercion]
cos) forall a b. (a -> b) -> a -> b
$
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr Bool
tysCosFVsInScope
(forall doc. IsLine doc => String -> doc
text String
"in_scope" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr InScopeSet
in_scope forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"tenv" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr TvSubstEnv
tenv forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"cenv" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr CvSubstEnv
cenv forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"tys" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [Type]
tys forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"cos" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [Coercion]
cos forall doc. IsDoc doc => doc -> doc -> doc
$$
forall doc. IsLine doc => String -> doc
text String
"needInScope" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr VarSet
needInScope)
a
a
where
substDomain :: [Unique]
substDomain = forall key elt. UniqFM key elt -> [Unique]
nonDetKeysUFM TvSubstEnv
tenv forall a. [a] -> [a] -> [a]
++ 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)
forall a. UniqSet a -> [Unique] -> UniqSet a
`delListFromUniqSet_Directly` [Unique]
substDomain
tysCosFVsInScope :: Bool
tysCosFVsInScope = VarSet
needInScope VarSet -> InScopeSet -> Bool
`varSetInScope` InScopeSet
in_scope
substTy :: HasDebugCallStack => Subst -> Type -> Type
substTy :: HasDebugCallStack => Subst -> Type -> Type
substTy Subst
subst Type
ty
| Subst -> Bool
isEmptyTCvSubst Subst
subst = Type
ty
| Bool
otherwise = forall a.
HasDebugCallStack =>
Subst -> [Type] -> [Coercion] -> a -> a
checkValidSubst Subst
subst [Type
ty] [] forall a b. (a -> b) -> a -> b
$
Subst -> Type -> Type
subst_ty Subst
subst Type
ty
substTyUnchecked :: Subst -> Type -> Type
substTyUnchecked :: Subst -> Type -> Type
substTyUnchecked Subst
subst Type
ty
| Subst -> Bool
isEmptyTCvSubst Subst
subst = Type
ty
| Bool
otherwise = Subst -> Type -> Type
subst_ty Subst
subst Type
ty
substScaledTy :: HasDebugCallStack => Subst -> Scaled Type -> Scaled Type
substScaledTy :: HasDebugCallStack => Subst -> Scaled Type -> Scaled Type
substScaledTy Subst
subst Scaled Type
scaled_ty = (Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (HasDebugCallStack => Subst -> Type -> Type
substTy Subst
subst) Scaled Type
scaled_ty
substScaledTyUnchecked :: HasDebugCallStack => Subst -> Scaled Type -> Scaled Type
substScaledTyUnchecked :: HasDebugCallStack => Subst -> Scaled Type -> Scaled Type
substScaledTyUnchecked Subst
subst Scaled Type
scaled_ty = (Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (Subst -> Type -> Type
substTyUnchecked Subst
subst) Scaled Type
scaled_ty
substTys :: HasDebugCallStack => Subst -> [Type] -> [Type]
substTys :: HasDebugCallStack => Subst -> [Type] -> [Type]
substTys Subst
subst [Type]
tys
| Subst -> Bool
isEmptyTCvSubst Subst
subst = [Type]
tys
| Bool
otherwise = forall a.
HasDebugCallStack =>
Subst -> [Type] -> [Coercion] -> a -> a
checkValidSubst Subst
subst [Type]
tys [] forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Subst -> Type -> Type
subst_ty Subst
subst) [Type]
tys
substScaledTys :: HasDebugCallStack => Subst -> [Scaled Type] -> [Scaled Type]
substScaledTys :: HasDebugCallStack => Subst -> [Scaled Type] -> [Scaled Type]
substScaledTys Subst
subst [Scaled Type]
scaled_tys
| Subst -> Bool
isEmptyTCvSubst Subst
subst = [Scaled Type]
scaled_tys
| Bool
otherwise = forall a.
HasDebugCallStack =>
Subst -> [Type] -> [Coercion] -> a -> a
checkValidSubst Subst
subst (forall a b. (a -> b) -> [a] -> [b]
map forall a. Scaled a -> Type
scaledMult [Scaled Type]
scaled_tys forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map forall a. Scaled a -> a
scaledThing [Scaled Type]
scaled_tys) [] forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map ((Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (Subst -> Type -> Type
subst_ty Subst
subst)) [Scaled Type]
scaled_tys
substTysUnchecked :: Subst -> [Type] -> [Type]
substTysUnchecked :: Subst -> [Type] -> [Type]
substTysUnchecked Subst
subst [Type]
tys
| Subst -> Bool
isEmptyTCvSubst Subst
subst = [Type]
tys
| Bool
otherwise = forall a b. (a -> b) -> [a] -> [b]
map (Subst -> Type -> Type
subst_ty Subst
subst) [Type]
tys
substScaledTysUnchecked :: Subst -> [Scaled Type] -> [Scaled Type]
substScaledTysUnchecked :: Subst -> [Scaled Type] -> [Scaled Type]
substScaledTysUnchecked Subst
subst [Scaled Type]
tys
| Subst -> Bool
isEmptyTCvSubst Subst
subst = [Scaled Type]
tys
| Bool
otherwise = forall a b. (a -> b) -> [a] -> [b]
map ((Type -> Type) -> Scaled Type -> Scaled Type
mapScaledType (Subst -> Type -> Type
subst_ty Subst
subst)) [Scaled Type]
tys
substTheta :: HasDebugCallStack => Subst -> ThetaType -> ThetaType
substTheta :: HasDebugCallStack => Subst -> [Type] -> [Type]
substTheta = HasDebugCallStack => Subst -> [Type] -> [Type]
substTys
substThetaUnchecked :: Subst -> ThetaType -> ThetaType
substThetaUnchecked :: Subst -> [Type] -> [Type]
substThetaUnchecked = Subst -> [Type] -> [Type]
substTysUnchecked
subst_ty :: Subst -> Type -> Type
subst_ty :: Subst -> Type -> Type
subst_ty Subst
subst Type
ty
= Type -> Type
go Type
ty
where
go :: Type -> Type
go (TyVarTy Var
tv) = Subst -> Var -> Type
substTyVar Subst
subst Var
tv
go (AppTy Type
fun Type
arg) = (Type -> Type -> Type
mkAppTy forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
fun)) forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
arg)
go ty :: Type
ty@(TyConApp TyCon
tc []) = TyCon
tc seq :: forall a b. a -> b -> b
`seq` Type
ty
go (TyConApp TyCon
tc [Type]
tys) = (TyCon -> [Type] -> Type
mkTyConApp forall a b. (a -> b) -> a -> b
$! TyCon
tc) forall a b. (a -> b) -> a -> b
$! 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 Var
tv ForAllTyFlag
vis) Type
ty)
= case Subst -> Var -> (Subst, Var)
substVarBndrUnchecked Subst
subst Var
tv of
(Subst
subst', Var
tv') ->
(VarBndr Var ForAllTyFlag -> Type -> Type
ForAllTy forall a b. (a -> b) -> a -> b
$! ((forall var argf. var -> argf -> VarBndr var argf
Bndr forall a b. (a -> b) -> a -> b
$! Var
tv') ForAllTyFlag
vis)) forall a b. (a -> b) -> a -> b
$!
(Subst -> Type -> Type
subst_ty Subst
subst' Type
ty)
go (LitTy TyLit
n) = TyLit -> Type
LitTy forall a b. (a -> b) -> a -> b
$! TyLit
n
go (CastTy Type
ty Coercion
co) = (Type -> Coercion -> Type
mkCastTy forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
ty)) forall a b. (a -> b) -> a -> b
$! (Subst -> Coercion -> Coercion
subst_co Subst
subst Coercion
co)
go (CoercionTy Coercion
co) = Coercion -> Type
CoercionTy forall a b. (a -> b) -> a -> b
$! (Subst -> Coercion -> Coercion
subst_co Subst
subst Coercion
co)
substTyVar :: Subst -> TyVar -> Type
substTyVar :: Subst -> Var -> Type
substTyVar (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
tenv CvSubstEnv
_) Var
tv
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
tv) forall a b. (a -> b) -> a -> b
$
case forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv TvSubstEnv
tenv Var
tv of
Just Type
ty -> Type
ty
Maybe Type
Nothing -> Var -> Type
TyVarTy Var
tv
substTyVarToTyVar :: HasDebugCallStack => Subst -> TyVar -> TyVar
substTyVarToTyVar :: HasDebugCallStack => Subst -> Var -> Var
substTyVarToTyVar (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
tenv CvSubstEnv
_) Var
tv
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
tv) forall a b. (a -> b) -> a -> b
$
case forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv TvSubstEnv
tenv Var
tv of
Just Type
ty -> case Type -> Maybe Var
getTyVar_maybe Type
ty of
Just Var
tv -> Var
tv
Maybe Var
Nothing -> forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"substTyVarToTyVar" (forall a. Outputable a => a -> SDoc
ppr Var
tv forall doc. IsDoc doc => doc -> doc -> doc
$$ forall a. Outputable a => a -> SDoc
ppr Type
ty)
Maybe Type
Nothing -> Var
tv
substTyVars :: Subst -> [TyVar] -> [Type]
substTyVars :: Subst -> [Var] -> [Type]
substTyVars Subst
subst = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a -> b) -> a -> b
$ Subst -> Var -> Type
substTyVar Subst
subst
substTyCoVars :: Subst -> [TyCoVar] -> [Type]
substTyCoVars :: Subst -> [Var] -> [Type]
substTyCoVars Subst
subst = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a -> b) -> a -> b
$ Subst -> Var -> Type
substTyCoVar Subst
subst
substTyCoVar :: Subst -> TyCoVar -> Type
substTyCoVar :: Subst -> Var -> Type
substTyCoVar Subst
subst Var
tv
| Var -> Bool
isTyVar Var
tv = Subst -> Var -> Type
substTyVar Subst
subst Var
tv
| Bool
otherwise = Coercion -> Type
CoercionTy forall a b. (a -> b) -> a -> b
$ Subst -> Var -> Coercion
substCoVar Subst
subst Var
tv
lookupTyVar :: Subst -> TyVar -> Maybe Type
lookupTyVar :: Subst -> Var -> Maybe Type
lookupTyVar (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
tenv CvSubstEnv
_) Var
tv
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
tv )
forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv TvSubstEnv
tenv Var
tv
substCo :: HasDebugCallStack => Subst -> Coercion -> Coercion
substCo :: HasDebugCallStack => Subst -> Coercion -> Coercion
substCo Subst
subst Coercion
co
| Subst -> Bool
isEmptyTCvSubst Subst
subst = Coercion
co
| Bool
otherwise = forall a.
HasDebugCallStack =>
Subst -> [Type] -> [Coercion] -> a -> a
checkValidSubst Subst
subst [] [Coercion
co] forall a b. (a -> b) -> a -> b
$ Subst -> Coercion -> Coercion
subst_co Subst
subst Coercion
co
substCoUnchecked :: Subst -> Coercion -> Coercion
substCoUnchecked :: Subst -> Coercion -> Coercion
substCoUnchecked Subst
subst Coercion
co
| Subst -> Bool
isEmptyTCvSubst Subst
subst = Coercion
co
| Bool
otherwise = Subst -> Coercion -> Coercion
subst_co Subst
subst Coercion
co
substCos :: HasDebugCallStack => Subst -> [Coercion] -> [Coercion]
substCos :: HasDebugCallStack => Subst -> [Coercion] -> [Coercion]
substCos Subst
subst [Coercion]
cos
| Subst -> Bool
isEmptyTCvSubst Subst
subst = [Coercion]
cos
| Bool
otherwise = forall a.
HasDebugCallStack =>
Subst -> [Type] -> [Coercion] -> a -> a
checkValidSubst Subst
subst [] [Coercion]
cos forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Subst -> Coercion -> Coercion
subst_co Subst
subst) [Coercion]
cos
subst_co :: Subst -> Coercion -> Coercion
subst_co :: Subst -> Coercion -> Coercion
subst_co Subst
subst Coercion
co
= Coercion -> Coercion
go Coercion
co
where
go_ty :: Type -> Type
go_ty :: Type -> Type
go_ty = Subst -> Type -> Type
subst_ty Subst
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 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 forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
ty)) 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' = forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
args
in [Coercion]
args' forall a b. [a] -> b -> b
`seqList` HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion
mkTyConAppCo Role
r TyCon
tc [Coercion]
args'
go (AppCo Coercion
co Coercion
arg) = (Coercion -> Coercion -> Coercion
mkAppCo forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co) forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
arg
go (ForAllCo Var
tv Coercion
kind_co Coercion
co)
= case Subst -> Var -> Coercion -> (Subst, Var, Coercion)
substForAllCoBndrUnchecked Subst
subst Var
tv Coercion
kind_co of
(Subst
subst', Var
tv', Coercion
kind_co') ->
((Var -> Coercion -> Coercion -> Coercion
mkForAllCo forall a b. (a -> b) -> a -> b
$! Var
tv') forall a b. (a -> b) -> a -> b
$! Coercion
kind_co') forall a b. (a -> b) -> a -> b
$! Subst -> Coercion -> Coercion
subst_co Subst
subst' Coercion
co
go (FunCo Role
r FunTyFlag
afl FunTyFlag
afr Coercion
w Coercion
co1 Coercion
co2) = ((HasDebugCallStack =>
Role
-> FunTyFlag
-> FunTyFlag
-> Coercion
-> Coercion
-> Coercion
-> Coercion
mkFunCo2 Role
r FunTyFlag
afl FunTyFlag
afr forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
w) forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co1) forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co2
go (CoVarCo Var
cv) = Subst -> Var -> Coercion
substCoVar Subst
subst Var
cv
go (AxiomInstCo CoAxiom Branched
con BranchIndex
ind [Coercion]
cos) = CoAxiom Branched -> BranchIndex -> [Coercion] -> Coercion
mkAxiomInstCo CoAxiom Branched
con BranchIndex
ind forall a b. (a -> b) -> a -> b
$! 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 forall a b. (a -> b) -> a -> b
$! UnivCoProvenance -> UnivCoProvenance
go_prov UnivCoProvenance
p) forall a b. (a -> b) -> a -> b
$! Role
r) forall a b. (a -> b) -> a -> b
$!
(Type -> Type
go_ty Type
t1)) forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
t2)
go (SymCo Coercion
co) = Coercion -> Coercion
mkSymCo forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (TransCo Coercion
co1 Coercion
co2) = (Coercion -> Coercion -> Coercion
mkTransCo forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co1)) forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co2)
go (SelCo CoSel
d Coercion
co) = HasDebugCallStack => CoSel -> Coercion -> Coercion
mkSelCo CoSel
d forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (LRCo LeftOrRight
lr Coercion
co) = LeftOrRight -> Coercion -> Coercion
mkLRCo LeftOrRight
lr forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (InstCo Coercion
co Coercion
arg) = (Coercion -> Coercion -> Coercion
mkInstCo forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)) forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
arg
go (KindCo Coercion
co) = Coercion -> Coercion
mkKindCo forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (SubCo Coercion
co) = HasDebugCallStack => Coercion -> Coercion
mkSubCo forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
go (AxiomRuleCo CoAxiomRule
c [Coercion]
cs) = let cs1 :: [Coercion]
cs1 = forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
cs
in [Coercion]
cs1 forall a b. [a] -> b -> b
`seqList` CoAxiomRule -> [Coercion] -> Coercion
AxiomRuleCo CoAxiomRule
c [Coercion]
cs1
go (HoleCo CoercionHole
h) = CoercionHole -> Coercion
HoleCo 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@(CorePrepProv Bool
_) = UnivCoProvenance
p
go_hole :: CoercionHole -> CoercionHole
go_hole h :: CoercionHole
h@(CoercionHole { ch_co_var :: CoercionHole -> Var
ch_co_var = Var
cv })
= CoercionHole
h { ch_co_var :: Var
ch_co_var = (Type -> Type) -> Var -> Var
updateVarType Type -> Type
go_ty Var
cv }
substForAllCoBndr :: Subst -> TyCoVar -> KindCoercion
-> (Subst, TyCoVar, Coercion)
substForAllCoBndr :: Subst -> Var -> Coercion -> (Subst, Var, Coercion)
substForAllCoBndr Subst
subst
= Bool
-> (Coercion -> Coercion)
-> Subst
-> Var
-> Coercion
-> (Subst, Var, Coercion)
substForAllCoBndrUsing Bool
False (HasDebugCallStack => Subst -> Coercion -> Coercion
substCo Subst
subst) Subst
subst
substForAllCoBndrUnchecked :: Subst -> TyCoVar -> KindCoercion
-> (Subst, TyCoVar, Coercion)
substForAllCoBndrUnchecked :: Subst -> Var -> Coercion -> (Subst, Var, Coercion)
substForAllCoBndrUnchecked Subst
subst
= Bool
-> (Coercion -> Coercion)
-> Subst
-> Var
-> Coercion
-> (Subst, Var, Coercion)
substForAllCoBndrUsing Bool
False (Subst -> Coercion -> Coercion
substCoUnchecked Subst
subst) Subst
subst
substForAllCoBndrUsing :: Bool
-> (Coercion -> Coercion)
-> Subst -> TyCoVar -> KindCoercion
-> (Subst, TyCoVar, KindCoercion)
substForAllCoBndrUsing :: Bool
-> (Coercion -> Coercion)
-> Subst
-> Var
-> Coercion
-> (Subst, Var, Coercion)
substForAllCoBndrUsing Bool
sym Coercion -> Coercion
sco Subst
subst Var
old_var
| Var -> Bool
isTyVar Var
old_var = Bool
-> (Coercion -> Coercion)
-> Subst
-> Var
-> Coercion
-> (Subst, Var, Coercion)
substForAllCoTyVarBndrUsing Bool
sym Coercion -> Coercion
sco Subst
subst Var
old_var
| Bool
otherwise = Bool
-> (Coercion -> Coercion)
-> Subst
-> Var
-> Coercion
-> (Subst, Var, Coercion)
substForAllCoCoVarBndrUsing Bool
sym Coercion -> Coercion
sco Subst
subst Var
old_var
substForAllCoTyVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> Subst -> TyVar -> KindCoercion
-> (Subst, TyVar, KindCoercion)
substForAllCoTyVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> Subst
-> Var
-> Coercion
-> (Subst, Var, Coercion)
substForAllCoTyVarBndrUsing Bool
sym Coercion -> Coercion
sco (Subst InScopeSet
in_scope IdSubstEnv
idenv TvSubstEnv
tenv CvSubstEnv
cenv) Var
old_var Coercion
old_kind_co
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
old_var )
( InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> Var -> InScopeSet
`extendInScopeSet` Var
new_var) IdSubstEnv
idenv TvSubstEnv
new_env CvSubstEnv
cenv
, Var
new_var, Coercion
new_kind_co )
where
new_env :: TvSubstEnv
new_env | Bool
no_change Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
sym = forall a. VarEnv a -> Var -> VarEnv a
delVarEnv TvSubstEnv
tenv Var
old_var
| Bool
sym = forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv Var
old_var forall a b. (a -> b) -> a -> b
$
Var -> Type
TyVarTy Var
new_var Type -> Coercion -> Type
`CastTy` Coercion
new_kind_co
| Bool
otherwise = forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv Var
old_var (Var -> Type
TyVarTy Var
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
&& (Var
new_var forall a. Eq a => a -> a -> Bool
== Var
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 :: Var
new_var = InScopeSet -> Var -> Var
uniqAway InScopeSet
in_scope (Var -> Type -> Var
setTyVarKind Var
old_var Type
new_ki1)
substForAllCoCoVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> Subst -> CoVar -> KindCoercion
-> (Subst, CoVar, KindCoercion)
substForAllCoCoVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> Subst
-> Var
-> Coercion
-> (Subst, Var, Coercion)
substForAllCoCoVarBndrUsing Bool
sym Coercion -> Coercion
sco (Subst InScopeSet
in_scope IdSubstEnv
idenv TvSubstEnv
tenv CvSubstEnv
cenv)
Var
old_var Coercion
old_kind_co
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isCoVar Var
old_var )
( InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> Var -> InScopeSet
`extendInScopeSet` Var
new_var) IdSubstEnv
idenv TvSubstEnv
tenv CvSubstEnv
new_cenv
, Var
new_var, Coercion
new_kind_co )
where
new_cenv :: CvSubstEnv
new_cenv | Bool
no_change Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
sym = forall a. VarEnv a -> Var -> VarEnv a
delVarEnv CvSubstEnv
cenv Var
old_var
| Bool
otherwise = forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv CvSubstEnv
cenv Var
old_var (Var -> Coercion
mkCoVarCo Var
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
&& (Var
new_var forall a. Eq a => a -> a -> Bool
== Var
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 :: Var
new_var = InScopeSet -> Var -> Var
uniqAway InScopeSet
in_scope forall a b. (a -> b) -> a -> b
$ Name -> Type -> Var
mkCoVar (Var -> Name
varName Var
old_var) Type
new_var_type
new_var_type :: Type
new_var_type | Bool
sym = Type
h2
| Bool
otherwise = Type
h1
substCoVar :: Subst -> CoVar -> Coercion
substCoVar :: Subst -> Var -> Coercion
substCoVar (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
_ CvSubstEnv
cenv) Var
cv
= case forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv CvSubstEnv
cenv Var
cv of
Just Coercion
co -> Coercion
co
Maybe Coercion
Nothing -> Var -> Coercion
CoVarCo Var
cv
substCoVars :: Subst -> [CoVar] -> [Coercion]
substCoVars :: Subst -> [Var] -> [Coercion]
substCoVars Subst
subst [Var]
cvs = forall a b. (a -> b) -> [a] -> [b]
map (Subst -> Var -> Coercion
substCoVar Subst
subst) [Var]
cvs
lookupCoVar :: Subst -> Var -> Maybe Coercion
lookupCoVar :: Subst -> Var -> Maybe Coercion
lookupCoVar (Subst InScopeSet
_ IdSubstEnv
_ TvSubstEnv
_ CvSubstEnv
cenv) Var
v = forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv CvSubstEnv
cenv Var
v
substTyVarBndr :: HasDebugCallStack => Subst -> TyVar -> (Subst, TyVar)
substTyVarBndr :: HasDebugCallStack => Subst -> Var -> (Subst, Var)
substTyVarBndr = (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substTyVarBndrUsing HasDebugCallStack => Subst -> Type -> Type
substTy
substTyVarBndrs :: HasDebugCallStack => Subst -> [TyVar] -> (Subst, [TyVar])
substTyVarBndrs :: HasDebugCallStack => Subst -> [Var] -> (Subst, [Var])
substTyVarBndrs = forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL HasDebugCallStack => Subst -> Var -> (Subst, Var)
substTyVarBndr
substVarBndr :: HasDebugCallStack => Subst -> TyCoVar -> (Subst, TyCoVar)
substVarBndr :: HasDebugCallStack => Subst -> Var -> (Subst, Var)
substVarBndr = (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substVarBndrUsing HasDebugCallStack => Subst -> Type -> Type
substTy
substVarBndrs :: HasDebugCallStack => Subst -> [TyCoVar] -> (Subst, [TyCoVar])
substVarBndrs :: HasDebugCallStack => Subst -> [Var] -> (Subst, [Var])
substVarBndrs = forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL HasDebugCallStack => Subst -> Var -> (Subst, Var)
substVarBndr
substCoVarBndr :: HasDebugCallStack => Subst -> CoVar -> (Subst, CoVar)
substCoVarBndr :: HasDebugCallStack => Subst -> Var -> (Subst, Var)
substCoVarBndr = (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substCoVarBndrUsing HasDebugCallStack => Subst -> Type -> Type
substTy
substVarBndrUnchecked :: Subst -> TyCoVar -> (Subst, TyCoVar)
substVarBndrUnchecked :: Subst -> Var -> (Subst, Var)
substVarBndrUnchecked = (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substVarBndrUsing Subst -> Type -> Type
substTyUnchecked
substVarBndrUsing :: (Subst -> Type -> Type)
-> Subst -> TyCoVar -> (Subst, TyCoVar)
substVarBndrUsing :: (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substVarBndrUsing Subst -> Type -> Type
subst_fn Subst
subst Var
v
| Var -> Bool
isTyVar Var
v = (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substTyVarBndrUsing Subst -> Type -> Type
subst_fn Subst
subst Var
v
| Bool
otherwise = (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substCoVarBndrUsing Subst -> Type -> Type
subst_fn Subst
subst Var
v
substTyVarBndrUsing
:: (Subst -> Type -> Type)
-> Subst -> TyVar -> (Subst, TyVar)
substTyVarBndrUsing :: (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substTyVarBndrUsing Subst -> Type -> Type
subst_fn subst :: Subst
subst@(Subst InScopeSet
in_scope IdSubstEnv
idenv TvSubstEnv
tenv CvSubstEnv
cenv) Var
old_var
= forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr Bool
_no_capture (Var -> SDoc
pprTyVar Var
old_var forall doc. IsDoc doc => doc -> doc -> doc
$$ Var -> SDoc
pprTyVar Var
new_var forall doc. IsDoc doc => doc -> doc -> doc
$$ forall a. Outputable a => a -> SDoc
ppr Subst
subst) forall a b. (a -> b) -> a -> b
$
forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isTyVar Var
old_var )
(InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> Var -> InScopeSet
`extendInScopeSet` Var
new_var) IdSubstEnv
idenv TvSubstEnv
new_env CvSubstEnv
cenv, Var
new_var)
where
new_env :: TvSubstEnv
new_env | Bool
no_change = forall a. VarEnv a -> Var -> VarEnv a
delVarEnv TvSubstEnv
tenv Var
old_var
| Bool
otherwise = forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tenv Var
old_var (Var -> Type
TyVarTy Var
new_var)
_no_capture :: Bool
_no_capture = Bool -> Bool
not (Var
new_var Var -> VarSet -> Bool
`elemVarSet` TvSubstEnv -> VarSet
shallowTyCoVarsOfTyVarEnv TvSubstEnv
tenv)
old_ki :: Type
old_ki = Var -> Type
tyVarKind Var
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
&& (Var
new_var forall a. Eq a => a -> a -> Bool
== Var
old_var)
new_var :: Var
new_var | Bool
no_kind_change = InScopeSet -> Var -> Var
uniqAway InScopeSet
in_scope Var
old_var
| Bool
otherwise = InScopeSet -> Var -> Var
uniqAway InScopeSet
in_scope forall a b. (a -> b) -> a -> b
$
Var -> Type -> Var
setTyVarKind Var
old_var (Subst -> Type -> Type
subst_fn Subst
subst Type
old_ki)
substCoVarBndrUsing
:: (Subst -> Type -> Type)
-> Subst -> CoVar -> (Subst, CoVar)
substCoVarBndrUsing :: (Subst -> Type -> Type) -> Subst -> Var -> (Subst, Var)
substCoVarBndrUsing Subst -> Type -> Type
subst_fn subst :: Subst
subst@(Subst InScopeSet
in_scope IdSubstEnv
idenv TvSubstEnv
tenv CvSubstEnv
cenv) Var
old_var
= forall a. HasCallStack => Bool -> a -> a
assert (Var -> Bool
isCoVar Var
old_var)
(InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet
in_scope InScopeSet -> Var -> InScopeSet
`extendInScopeSet` Var
new_var) IdSubstEnv
idenv TvSubstEnv
tenv CvSubstEnv
new_cenv, Var
new_var)
where
new_co :: Coercion
new_co = Var -> Coercion
mkCoVarCo Var
new_var
no_kind_change :: Bool
no_kind_change = [Type] -> Bool
noFreeVarsOfTypes [Type
t1, Type
t2]
no_change :: Bool
no_change = Var
new_var forall a. Eq a => a -> a -> Bool
== Var
old_var Bool -> Bool -> Bool
&& Bool
no_kind_change
new_cenv :: CvSubstEnv
new_cenv | Bool
no_change = forall a. VarEnv a -> Var -> VarEnv a
delVarEnv CvSubstEnv
cenv Var
old_var
| Bool
otherwise = forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv CvSubstEnv
cenv Var
old_var Coercion
new_co
new_var :: Var
new_var = InScopeSet -> Var -> Var
uniqAway InScopeSet
in_scope Var
subst_old_var
subst_old_var :: Var
subst_old_var = Name -> Type -> Var
mkCoVar (Var -> Name
varName Var
old_var) Type
new_var_type
(Type
_, Type
_, Type
t1, Type
t2, Role
role) = HasDebugCallStack => Var -> (Type, Type, Type, Type, Role)
coVarKindsTypesRole Var
old_var
t1' :: Type
t1' = Subst -> Type -> Type
subst_fn Subst
subst Type
t1
t2' :: Type
t2' = Subst -> Type -> Type
subst_fn Subst
subst Type
t2
new_var_type :: Type
new_var_type = Role -> Type -> Type -> Type
mkCoercionType Role
role Type
t1' Type
t2'
cloneTyVarBndr :: Subst -> TyVar -> Unique -> (Subst, TyVar)
cloneTyVarBndr :: Subst -> Var -> Unique -> (Subst, Var)
cloneTyVarBndr subst :: Subst
subst@(Subst InScopeSet
in_scope IdSubstEnv
id_env TvSubstEnv
tv_env CvSubstEnv
cv_env) Var
tv Unique
uniq
= forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (Var -> Bool
isTyVar Var
tv) (forall a. Outputable a => a -> SDoc
ppr Var
tv)
( InScopeSet -> IdSubstEnv -> TvSubstEnv -> CvSubstEnv -> Subst
Subst (InScopeSet -> Var -> InScopeSet
extendInScopeSet InScopeSet
in_scope Var
tv')
IdSubstEnv
id_env
(forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tv_env Var
tv (Var -> Type
mkTyVarTy Var
tv'))
CvSubstEnv
cv_env
, Var
tv')
where
old_ki :: Type
old_ki = Var -> Type
tyVarKind Var
tv
no_kind_change :: Bool
no_kind_change = Type -> Bool
noFreeVarsOfType Type
old_ki
tv1 :: Var
tv1 | Bool
no_kind_change = Var
tv
| Bool
otherwise = Var -> Type -> Var
setTyVarKind Var
tv (HasDebugCallStack => Subst -> Type -> Type
substTy Subst
subst Type
old_ki)
tv' :: Var
tv' = Var -> Unique -> Var
setVarUnique Var
tv1 Unique
uniq
cloneTyVarBndrs :: Subst -> [TyVar] -> UniqSupply -> (Subst, [TyVar])
cloneTyVarBndrs :: Subst -> [Var] -> UniqSupply -> (Subst, [Var])
cloneTyVarBndrs Subst
subst [] UniqSupply
_usupply = (Subst
subst, [])
cloneTyVarBndrs Subst
subst (Var
t:[Var]
ts) UniqSupply
usupply = (Subst
subst'', Var
tvforall a. a -> [a] -> [a]
:[Var]
tvs)
where
(Unique
uniq, UniqSupply
usupply') = UniqSupply -> (Unique, UniqSupply)
takeUniqFromSupply UniqSupply
usupply
(Subst
subst' , Var
tv ) = Subst -> Var -> Unique -> (Subst, Var)
cloneTyVarBndr Subst
subst Var
t Unique
uniq
(Subst
subst'', [Var]
tvs) = Subst -> [Var] -> UniqSupply -> (Subst, [Var])
cloneTyVarBndrs Subst
subst' [Var]
ts UniqSupply
usupply'
substTyCoBndr :: Subst -> PiTyBinder -> (Subst, PiTyBinder)
substTyCoBndr :: Subst -> PiTyBinder -> (Subst, PiTyBinder)
substTyCoBndr Subst
subst (Anon Scaled Type
ty FunTyFlag
af) = (Subst
subst, Scaled Type -> FunTyFlag -> PiTyBinder
Anon (HasDebugCallStack => Subst -> Scaled Type -> Scaled Type
substScaledTy Subst
subst Scaled Type
ty) FunTyFlag
af)
substTyCoBndr Subst
subst (Named (Bndr Var
tv ForAllTyFlag
vis)) = (Subst
subst', VarBndr Var ForAllTyFlag -> PiTyBinder
Named (forall var argf. var -> argf -> VarBndr var argf
Bndr Var
tv' ForAllTyFlag
vis))
where
(Subst
subst', Var
tv') = HasDebugCallStack => Subst -> Var -> (Subst, Var)
substVarBndr Subst
subst Var
tv