{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFunctor #-}
module Unify (
        tcMatchTy, tcMatchTyKi,
        tcMatchTys, tcMatchTyKis,
        tcMatchTyX, tcMatchTysX, tcMatchTyKisX,
        tcMatchTyX_BM, ruleMatchTyKiX,
        
        roughMatchTcs, instanceCantMatch,
        typesCantMatch,
        
        tcUnifyTy, tcUnifyTyKi, tcUnifyTys, tcUnifyTyKis,
        tcUnifyTysFG, tcUnifyTyWithTFs,
        BindFlag(..),
        UnifyResult, UnifyResultM(..),
        
        liftCoMatch
   ) where
#include "HsVersions.h"
import GhcPrelude
import Var
import VarEnv
import VarSet
import Name( Name )
import Type hiding ( getTvSubstEnv )
import Coercion hiding ( getCvSubstEnv )
import TyCon
import TyCoRep hiding ( getTvSubstEnv, getCvSubstEnv )
import FV( FV, fvVarSet, fvVarList )
import Util
import Pair
import Outputable
import UniqFM
import UniqSet
import Control.Monad
import qualified Control.Monad.Fail as MonadFail
import Control.Applicative hiding ( empty )
import qualified Control.Applicative
tcMatchTy :: Type -> Type -> Maybe TCvSubst
tcMatchTy :: Type -> Type -> Maybe TCvSubst
tcMatchTy ty1 :: Type
ty1 ty2 :: Type
ty2 = [Type] -> [Type] -> Maybe TCvSubst
tcMatchTys [Type
ty1] [Type
ty2]
tcMatchTyX_BM :: (TyVar -> BindFlag) -> TCvSubst
              -> Type -> Type -> Maybe TCvSubst
tcMatchTyX_BM :: (TyVar -> BindFlag) -> TCvSubst -> Type -> Type -> Maybe TCvSubst
tcMatchTyX_BM bind_me :: TyVar -> BindFlag
bind_me subst :: TCvSubst
subst ty1 :: Type
ty1 ty2 :: Type
ty2
  = (TyVar -> BindFlag)
-> Bool -> TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys_x TyVar -> BindFlag
bind_me Bool
False TCvSubst
subst [Type
ty1] [Type
ty2]
tcMatchTyKi :: Type -> Type -> Maybe TCvSubst
tcMatchTyKi :: Type -> Type -> Maybe TCvSubst
tcMatchTyKi ty1 :: Type
ty1 ty2 :: Type
ty2
  = (TyVar -> BindFlag) -> Bool -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) Bool
True [Type
ty1] [Type
ty2]
tcMatchTyX :: TCvSubst            
           -> Type                
           -> Type                
           -> Maybe TCvSubst
tcMatchTyX :: TCvSubst -> Type -> Type -> Maybe TCvSubst
tcMatchTyX subst :: TCvSubst
subst ty1 :: Type
ty1 ty2 :: Type
ty2
  = (TyVar -> BindFlag)
-> Bool -> TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys_x (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) Bool
False TCvSubst
subst [Type
ty1] [Type
ty2]
tcMatchTys :: [Type]         
           -> [Type]         
           -> Maybe TCvSubst 
                             
tcMatchTys :: [Type] -> [Type] -> Maybe TCvSubst
tcMatchTys tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = (TyVar -> BindFlag) -> Bool -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) Bool
False [Type]
tys1 [Type]
tys2
tcMatchTyKis :: [Type]         
             -> [Type]         
             -> Maybe TCvSubst 
tcMatchTyKis :: [Type] -> [Type] -> Maybe TCvSubst
tcMatchTyKis tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = (TyVar -> BindFlag) -> Bool -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) Bool
True [Type]
tys1 [Type]
tys2
tcMatchTysX :: TCvSubst       
            -> [Type]         
            -> [Type]         
            -> Maybe TCvSubst 
tcMatchTysX :: TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tcMatchTysX subst :: TCvSubst
subst tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = (TyVar -> BindFlag)
-> Bool -> TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys_x (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) Bool
False TCvSubst
subst [Type]
tys1 [Type]
tys2
tcMatchTyKisX :: TCvSubst        
              -> [Type]          
              -> [Type]          
              -> Maybe TCvSubst  
tcMatchTyKisX :: TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tcMatchTyKisX subst :: TCvSubst
subst tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = (TyVar -> BindFlag)
-> Bool -> TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys_x (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) Bool
True TCvSubst
subst [Type]
tys1 [Type]
tys2
tc_match_tys :: (TyVar -> BindFlag)
               -> Bool          
               -> [Type]
               -> [Type]
               -> Maybe TCvSubst
tc_match_tys :: (TyVar -> BindFlag) -> Bool -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys bind_me :: TyVar -> BindFlag
bind_me match_kis :: Bool
match_kis tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = (TyVar -> BindFlag)
-> Bool -> TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys_x TyVar -> BindFlag
bind_me Bool
match_kis (InScopeSet -> TCvSubst
mkEmptyTCvSubst InScopeSet
in_scope) [Type]
tys1 [Type]
tys2
  where
    in_scope :: InScopeSet
in_scope = VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet
tyCoVarsOfTypes [Type]
tys1 VarSet -> VarSet -> VarSet
`unionVarSet` [Type] -> VarSet
tyCoVarsOfTypes [Type]
tys2)
tc_match_tys_x :: (TyVar -> BindFlag)
               -> Bool          
               -> TCvSubst
               -> [Type]
               -> [Type]
               -> Maybe TCvSubst
tc_match_tys_x :: (TyVar -> BindFlag)
-> Bool -> TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
tc_match_tys_x bind_me :: TyVar -> BindFlag
bind_me match_kis :: Bool
match_kis (TCvSubst in_scope :: InScopeSet
in_scope tv_env :: TvSubstEnv
tv_env cv_env :: CvSubstEnv
cv_env) tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = case (TyVar -> BindFlag)
-> Bool
-> Bool
-> Bool
-> RnEnv2
-> TvSubstEnv
-> CvSubstEnv
-> [Type]
-> [Type]
-> UnifyResultM (TvSubstEnv, CvSubstEnv)
tc_unify_tys TyVar -> BindFlag
bind_me
                      Bool
False  
                      Bool
False  
                      Bool
match_kis
                      (InScopeSet -> RnEnv2
mkRnEnv2 InScopeSet
in_scope) TvSubstEnv
tv_env CvSubstEnv
cv_env [Type]
tys1 [Type]
tys2 of
      Unifiable (tv_env' :: TvSubstEnv
tv_env', cv_env' :: CvSubstEnv
cv_env')
        -> TCvSubst -> Maybe TCvSubst
forall a. a -> Maybe a
Just (TCvSubst -> Maybe TCvSubst) -> TCvSubst -> Maybe TCvSubst
forall a b. (a -> b) -> a -> b
$ InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tv_env' CvSubstEnv
cv_env'
      _ -> Maybe TCvSubst
forall a. Maybe a
Nothing
ruleMatchTyKiX
  :: TyCoVarSet          
  -> RnEnv2
  -> TvSubstEnv          
  -> Type                
  -> Type                
  -> Maybe TvSubstEnv
ruleMatchTyKiX :: VarSet -> RnEnv2 -> TvSubstEnv -> Type -> Type -> Maybe TvSubstEnv
ruleMatchTyKiX tmpl_tvs :: VarSet
tmpl_tvs rn_env :: RnEnv2
rn_env tenv :: TvSubstEnv
tenv tmpl :: Type
tmpl target :: Type
target
  = case (TyVar -> BindFlag)
-> Bool
-> Bool
-> Bool
-> RnEnv2
-> TvSubstEnv
-> CvSubstEnv
-> [Type]
-> [Type]
-> UnifyResultM (TvSubstEnv, CvSubstEnv)
tc_unify_tys (VarSet -> TyVar -> BindFlag
matchBindFun VarSet
tmpl_tvs) Bool
False Bool
False
                      Bool
True 
                      RnEnv2
rn_env TvSubstEnv
tenv CvSubstEnv
emptyCvSubstEnv [Type
tmpl] [Type
target] of
      Unifiable (tenv' :: TvSubstEnv
tenv', _) -> TvSubstEnv -> Maybe TvSubstEnv
forall a. a -> Maybe a
Just TvSubstEnv
tenv'
      _                    -> Maybe TvSubstEnv
forall a. Maybe a
Nothing
matchBindFun :: TyCoVarSet -> TyVar -> BindFlag
matchBindFun :: VarSet -> TyVar -> BindFlag
matchBindFun tvs :: VarSet
tvs tv :: TyVar
tv = if TyVar
tv TyVar -> VarSet -> Bool
`elemVarSet` VarSet
tvs then BindFlag
BindMe else BindFlag
Skolem
roughMatchTcs :: [Type] -> [Maybe Name]
roughMatchTcs :: [Type] -> [Maybe Name]
roughMatchTcs tys :: [Type]
tys = (Type -> Maybe Name) -> [Type] -> [Maybe Name]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Maybe Name
rough [Type]
tys
  where
    rough :: Type -> Maybe Name
rough ty :: Type
ty
      | Just (ty' :: Type
ty', _) <- Type -> Maybe (Type, Coercion)
splitCastTy_maybe Type
ty   = Type -> Maybe Name
rough Type
ty'
      | Just (tc :: TyCon
tc,_)   <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty = Name -> Maybe Name
forall a. a -> Maybe a
Just (TyCon -> Name
tyConName TyCon
tc)
      | Bool
otherwise                               = Maybe Name
forall a. Maybe a
Nothing
instanceCantMatch :: [Maybe Name] -> [Maybe Name] -> Bool
instanceCantMatch :: [Maybe Name] -> [Maybe Name] -> Bool
instanceCantMatch (mt :: Maybe Name
mt : ts :: [Maybe Name]
ts) (ma :: Maybe Name
ma : as :: [Maybe Name]
as) = Maybe Name -> Maybe Name -> Bool
itemCantMatch Maybe Name
mt Maybe Name
ma Bool -> Bool -> Bool
|| [Maybe Name] -> [Maybe Name] -> Bool
instanceCantMatch [Maybe Name]
ts [Maybe Name]
as
instanceCantMatch _         _         =  Bool
False  
itemCantMatch :: Maybe Name -> Maybe Name -> Bool
itemCantMatch :: Maybe Name -> Maybe Name -> Bool
itemCantMatch (Just t :: Name
t) (Just a :: Name
a) = Name
t Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
/= Name
a
itemCantMatch _        _        = Bool
False
typesCantMatch :: [(Type,Type)] -> Bool
typesCantMatch :: [(Type, Type)] -> Bool
typesCantMatch prs :: [(Type, Type)]
prs = ((Type, Type) -> Bool) -> [(Type, Type)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Type -> Type -> Bool) -> (Type, Type) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Type -> Type -> Bool
cant_match) [(Type, Type)]
prs
  where
    cant_match :: Type -> Type -> Bool
    cant_match :: Type -> Type -> Bool
cant_match t1 :: Type
t1 t2 :: Type
t2 = case (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tcUnifyTysFG (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) [Type
t1] [Type
t2] of
      SurelyApart -> Bool
True
      _           -> Bool
False
tcUnifyTy :: Type -> Type       
          -> Maybe TCvSubst
                       
tcUnifyTy :: Type -> Type -> Maybe TCvSubst
tcUnifyTy t1 :: Type
t1 t2 :: Type
t2 = (TyVar -> BindFlag) -> [Type] -> [Type] -> Maybe TCvSubst
tcUnifyTys (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) [Type
t1] [Type
t2]
tcUnifyTyKi :: Type -> Type -> Maybe TCvSubst
tcUnifyTyKi :: Type -> Type -> Maybe TCvSubst
tcUnifyTyKi t1 :: Type
t1 t2 :: Type
t2 = (TyVar -> BindFlag) -> [Type] -> [Type] -> Maybe TCvSubst
tcUnifyTyKis (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) [Type
t1] [Type
t2]
tcUnifyTyWithTFs :: Bool  
                          
                          
                 -> Type -> Type -> Maybe TCvSubst
tcUnifyTyWithTFs :: Bool -> Type -> Type -> Maybe TCvSubst
tcUnifyTyWithTFs twoWay :: Bool
twoWay t1 :: Type
t1 t2 :: Type
t2
  = case (TyVar -> BindFlag)
-> Bool
-> Bool
-> Bool
-> RnEnv2
-> TvSubstEnv
-> CvSubstEnv
-> [Type]
-> [Type]
-> UnifyResultM (TvSubstEnv, CvSubstEnv)
tc_unify_tys (BindFlag -> TyVar -> BindFlag
forall a b. a -> b -> a
const BindFlag
BindMe) Bool
twoWay Bool
True Bool
False
                       RnEnv2
rn_env TvSubstEnv
emptyTvSubstEnv CvSubstEnv
emptyCvSubstEnv
                       [Type
t1] [Type
t2] of
      Unifiable  (subst :: TvSubstEnv
subst, _) -> TCvSubst -> Maybe TCvSubst
forall a. a -> Maybe a
Just (TCvSubst -> Maybe TCvSubst) -> TCvSubst -> Maybe TCvSubst
forall a b. (a -> b) -> a -> b
$ TvSubstEnv -> TCvSubst
niFixTCvSubst TvSubstEnv
subst
      MaybeApart (subst :: TvSubstEnv
subst, _) -> TCvSubst -> Maybe TCvSubst
forall a. a -> Maybe a
Just (TCvSubst -> Maybe TCvSubst) -> TCvSubst -> Maybe TCvSubst
forall a b. (a -> b) -> a -> b
$ TvSubstEnv -> TCvSubst
niFixTCvSubst TvSubstEnv
subst
      
      
      SurelyApart      -> Maybe TCvSubst
forall a. Maybe a
Nothing
  where
    rn_env :: RnEnv2
rn_env = InScopeSet -> RnEnv2
mkRnEnv2 (InScopeSet -> RnEnv2) -> InScopeSet -> RnEnv2
forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet (VarSet -> InScopeSet) -> VarSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$ [Type] -> VarSet
tyCoVarsOfTypes [Type
t1, Type
t2]
tcUnifyTys :: (TyCoVar -> BindFlag)
           -> [Type] -> [Type]
           -> Maybe TCvSubst
                                
                                
                                
tcUnifyTys :: (TyVar -> BindFlag) -> [Type] -> [Type] -> Maybe TCvSubst
tcUnifyTys bind_fn :: TyVar -> BindFlag
bind_fn tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = case (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tcUnifyTysFG TyVar -> BindFlag
bind_fn [Type]
tys1 [Type]
tys2 of
      Unifiable result :: TCvSubst
result -> TCvSubst -> Maybe TCvSubst
forall a. a -> Maybe a
Just TCvSubst
result
      _                -> Maybe TCvSubst
forall a. Maybe a
Nothing
tcUnifyTyKis :: (TyCoVar -> BindFlag)
             -> [Type] -> [Type]
             -> Maybe TCvSubst
tcUnifyTyKis :: (TyVar -> BindFlag) -> [Type] -> [Type] -> Maybe TCvSubst
tcUnifyTyKis bind_fn :: TyVar -> BindFlag
bind_fn tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = case (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tcUnifyTyKisFG TyVar -> BindFlag
bind_fn [Type]
tys1 [Type]
tys2 of
      Unifiable result :: TCvSubst
result -> TCvSubst -> Maybe TCvSubst
forall a. a -> Maybe a
Just TCvSubst
result
      _                -> Maybe TCvSubst
forall a. Maybe a
Nothing
type UnifyResult = UnifyResultM TCvSubst
data UnifyResultM a = Unifiable a        
                    | MaybeApart a       
                                         
                                         
                    | SurelyApart
                    deriving a -> UnifyResultM b -> UnifyResultM a
(a -> b) -> UnifyResultM a -> UnifyResultM b
(forall a b. (a -> b) -> UnifyResultM a -> UnifyResultM b)
-> (forall a b. a -> UnifyResultM b -> UnifyResultM a)
-> Functor UnifyResultM
forall a b. a -> UnifyResultM b -> UnifyResultM a
forall a b. (a -> b) -> UnifyResultM a -> UnifyResultM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> UnifyResultM b -> UnifyResultM a
$c<$ :: forall a b. a -> UnifyResultM b -> UnifyResultM a
fmap :: (a -> b) -> UnifyResultM a -> UnifyResultM b
$cfmap :: forall a b. (a -> b) -> UnifyResultM a -> UnifyResultM b
Functor
instance Applicative UnifyResultM where
  pure :: a -> UnifyResultM a
pure  = a -> UnifyResultM a
forall a. a -> UnifyResultM a
Unifiable
  <*> :: UnifyResultM (a -> b) -> UnifyResultM a -> UnifyResultM b
(<*>) = UnifyResultM (a -> b) -> UnifyResultM a -> UnifyResultM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad UnifyResultM where
  SurelyApart  >>= :: UnifyResultM a -> (a -> UnifyResultM b) -> UnifyResultM b
>>= _ = UnifyResultM b
forall a. UnifyResultM a
SurelyApart
  MaybeApart x :: a
x >>= f :: a -> UnifyResultM b
f = case a -> UnifyResultM b
f a
x of
                         Unifiable y :: b
y -> b -> UnifyResultM b
forall a. a -> UnifyResultM a
MaybeApart b
y
                         other :: UnifyResultM b
other       -> UnifyResultM b
other
  Unifiable x :: a
x  >>= f :: a -> UnifyResultM b
f = a -> UnifyResultM b
f a
x
instance Alternative UnifyResultM where
  empty :: UnifyResultM a
empty = UnifyResultM a
forall a. UnifyResultM a
SurelyApart
  a :: UnifyResultM a
a@(Unifiable {})  <|> :: UnifyResultM a -> UnifyResultM a -> UnifyResultM a
<|> _                 = UnifyResultM a
a
  _                 <|> b :: UnifyResultM a
b@(Unifiable {})  = UnifyResultM a
b
  a :: UnifyResultM a
a@(MaybeApart {}) <|> _                 = UnifyResultM a
a
  _                 <|> b :: UnifyResultM a
b@(MaybeApart {}) = UnifyResultM a
b
  SurelyApart       <|> SurelyApart       = UnifyResultM a
forall a. UnifyResultM a
SurelyApart
instance MonadPlus UnifyResultM
tcUnifyTysFG :: (TyVar -> BindFlag)
             -> [Type] -> [Type]
             -> UnifyResult
tcUnifyTysFG :: (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tcUnifyTysFG bind_fn :: TyVar -> BindFlag
bind_fn tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = Bool -> (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tc_unify_tys_fg Bool
False TyVar -> BindFlag
bind_fn [Type]
tys1 [Type]
tys2
tcUnifyTyKisFG :: (TyVar -> BindFlag)
               -> [Type] -> [Type]
               -> UnifyResult
tcUnifyTyKisFG :: (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tcUnifyTyKisFG bind_fn :: TyVar -> BindFlag
bind_fn tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = Bool -> (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tc_unify_tys_fg Bool
True TyVar -> BindFlag
bind_fn [Type]
tys1 [Type]
tys2
tc_unify_tys_fg :: Bool
                -> (TyVar -> BindFlag)
                -> [Type] -> [Type]
                -> UnifyResult
tc_unify_tys_fg :: Bool -> (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
tc_unify_tys_fg match_kis :: Bool
match_kis bind_fn :: TyVar -> BindFlag
bind_fn tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = do { (env :: TvSubstEnv
env, _) <- (TyVar -> BindFlag)
-> Bool
-> Bool
-> Bool
-> RnEnv2
-> TvSubstEnv
-> CvSubstEnv
-> [Type]
-> [Type]
-> UnifyResultM (TvSubstEnv, CvSubstEnv)
tc_unify_tys TyVar -> BindFlag
bind_fn Bool
True Bool
False Bool
match_kis RnEnv2
env
                                  TvSubstEnv
emptyTvSubstEnv CvSubstEnv
emptyCvSubstEnv
                                  [Type]
tys1 [Type]
tys2
       ; TCvSubst -> UnifyResult
forall (m :: * -> *) a. Monad m => a -> m a
return (TCvSubst -> UnifyResult) -> TCvSubst -> UnifyResult
forall a b. (a -> b) -> a -> b
$ TvSubstEnv -> TCvSubst
niFixTCvSubst TvSubstEnv
env }
  where
    vars :: VarSet
vars = [Type] -> VarSet
tyCoVarsOfTypes [Type]
tys1 VarSet -> VarSet -> VarSet
`unionVarSet` [Type] -> VarSet
tyCoVarsOfTypes [Type]
tys2
    env :: RnEnv2
env  = InScopeSet -> RnEnv2
mkRnEnv2 (InScopeSet -> RnEnv2) -> InScopeSet -> RnEnv2
forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet VarSet
vars
tc_unify_tys :: (TyVar -> BindFlag)
             -> AmIUnifying 
             -> Bool        
             -> Bool        
             -> RnEnv2
             -> TvSubstEnv  
             -> CvSubstEnv
             -> [Type] -> [Type]
             -> UnifyResultM (TvSubstEnv, CvSubstEnv)
tc_unify_tys :: (TyVar -> BindFlag)
-> Bool
-> Bool
-> Bool
-> RnEnv2
-> TvSubstEnv
-> CvSubstEnv
-> [Type]
-> [Type]
-> UnifyResultM (TvSubstEnv, CvSubstEnv)
tc_unify_tys bind_fn :: TyVar -> BindFlag
bind_fn unif :: Bool
unif inj_check :: Bool
inj_check match_kis :: Bool
match_kis rn_env :: RnEnv2
rn_env tv_env :: TvSubstEnv
tv_env cv_env :: CvSubstEnv
cv_env tys1 :: [Type]
tys1 tys2 :: [Type]
tys2
  = TvSubstEnv
-> CvSubstEnv
-> UM (TvSubstEnv, CvSubstEnv)
-> UnifyResultM (TvSubstEnv, CvSubstEnv)
forall a. TvSubstEnv -> CvSubstEnv -> UM a -> UnifyResultM a
initUM TvSubstEnv
tv_env CvSubstEnv
cv_env (UM (TvSubstEnv, CvSubstEnv)
 -> UnifyResultM (TvSubstEnv, CvSubstEnv))
-> UM (TvSubstEnv, CvSubstEnv)
-> UnifyResultM (TvSubstEnv, CvSubstEnv)
forall a b. (a -> b) -> a -> b
$
    do { Bool -> UM () -> UM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
match_kis (UM () -> UM ()) -> UM () -> UM ()
forall a b. (a -> b) -> a -> b
$
         UMEnv -> [Type] -> [Type] -> UM ()
unify_tys UMEnv
env [Type]
kis1 [Type]
kis2
       ; UMEnv -> [Type] -> [Type] -> UM ()
unify_tys UMEnv
env [Type]
tys1 [Type]
tys2
       ; (,) (TvSubstEnv -> CvSubstEnv -> (TvSubstEnv, CvSubstEnv))
-> UM TvSubstEnv -> UM (CvSubstEnv -> (TvSubstEnv, CvSubstEnv))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UM TvSubstEnv
getTvSubstEnv UM (CvSubstEnv -> (TvSubstEnv, CvSubstEnv))
-> UM CvSubstEnv -> UM (TvSubstEnv, CvSubstEnv)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> UM CvSubstEnv
getCvSubstEnv }
  where
    env :: UMEnv
env = UMEnv :: Bool -> Bool -> RnEnv2 -> VarSet -> (TyVar -> BindFlag) -> UMEnv
UMEnv { um_bind_fun :: TyVar -> BindFlag
um_bind_fun = TyVar -> BindFlag
bind_fn
                , um_skols :: VarSet
um_skols    = VarSet
emptyVarSet
                , um_unif :: Bool
um_unif     = Bool
unif
                , um_inj_tf :: Bool
um_inj_tf   = Bool
inj_check
                , um_rn_env :: RnEnv2
um_rn_env   = RnEnv2
rn_env }
    kis1 :: [Type]
kis1 = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map HasDebugCallStack => Type -> Type
Type -> Type
typeKind [Type]
tys1
    kis2 :: [Type]
kis2 = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map HasDebugCallStack => Type -> Type
Type -> Type
typeKind [Type]
tys2
instance Outputable a => Outputable (UnifyResultM a) where
  ppr :: UnifyResultM a -> SDoc
ppr SurelyApart    = String -> SDoc
text "SurelyApart"
  ppr (Unifiable x :: a
x)  = String -> SDoc
text "Unifiable" SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
x
  ppr (MaybeApart x :: a
x) = String -> SDoc
text "MaybeApart" SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
x
niFixTCvSubst :: TvSubstEnv -> TCvSubst
niFixTCvSubst :: TvSubstEnv -> TCvSubst
niFixTCvSubst tenv :: TvSubstEnv
tenv
  | Bool
not_fixpoint = TvSubstEnv -> TCvSubst
niFixTCvSubst ((Type -> Type) -> TvSubstEnv -> TvSubstEnv
forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst) TvSubstEnv
tenv)
  | Bool
otherwise    = TCvSubst
subst
  where
    range_fvs :: FV
    range_fvs :: FV
range_fvs = [Type] -> FV
tyCoFVsOfTypes (TvSubstEnv -> [Type]
forall elt. UniqFM elt -> [elt]
nonDetEltsUFM TvSubstEnv
tenv)
          
          
    range_tvs :: [TyVar]
    range_tvs :: [TyVar]
range_tvs = FV -> [TyVar]
fvVarList FV
range_fvs
    not_fixpoint :: Bool
not_fixpoint  = (TyVar -> Bool) -> [TyVar] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any TyVar -> Bool
in_domain [TyVar]
range_tvs
    in_domain :: TyVar -> Bool
in_domain tv :: TyVar
tv  = TyVar
tv TyVar -> TvSubstEnv -> Bool
forall a. TyVar -> VarEnv a -> Bool
`elemVarEnv` TvSubstEnv
tenv
    free_tvs :: [TyVar]
free_tvs = [TyVar] -> [TyVar]
scopedSort ((TyVar -> Bool) -> [TyVar] -> [TyVar]
forall a. (a -> Bool) -> [a] -> [a]
filterOut TyVar -> Bool
in_domain [TyVar]
range_tvs)
    
    init_in_scope :: InScopeSet
init_in_scope = VarSet -> InScopeSet
mkInScopeSet (FV -> VarSet
fvVarSet FV
range_fvs)
    subst :: TCvSubst
subst = (TCvSubst -> TyVar -> TCvSubst) -> TCvSubst -> [TyVar] -> TCvSubst
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' TCvSubst -> TyVar -> TCvSubst
add_free_tv
                  (InScopeSet -> TvSubstEnv -> TCvSubst
mkTvSubst InScopeSet
init_in_scope TvSubstEnv
tenv)
                  [TyVar]
free_tvs
    add_free_tv :: TCvSubst -> TyVar -> TCvSubst
    add_free_tv :: TCvSubst -> TyVar -> TCvSubst
add_free_tv subst :: TCvSubst
subst tv :: TyVar
tv
      = TCvSubst -> TyVar -> Type -> TCvSubst
extendTvSubst TCvSubst
subst TyVar
tv (TyVar -> Type
mkTyVarTy TyVar
tv')
     where
        tv' :: TyVar
tv' = (Type -> Type) -> TyVar -> TyVar
updateTyVarKind (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst) TyVar
tv
niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet
niSubstTvSet :: TvSubstEnv -> VarSet -> VarSet
niSubstTvSet tsubst :: TvSubstEnv
tsubst tvs :: VarSet
tvs
  = (TyVar -> VarSet -> VarSet) -> VarSet -> VarSet -> VarSet
forall elt a. (elt -> a -> a) -> a -> UniqSet elt -> a
nonDetFoldUniqSet (VarSet -> VarSet -> VarSet
unionVarSet (VarSet -> VarSet -> VarSet)
-> (TyVar -> VarSet) -> TyVar -> VarSet -> VarSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVar -> VarSet
get) VarSet
emptyVarSet VarSet
tvs
  
  
  where
    get :: TyVar -> VarSet
get tv :: TyVar
tv
      | Just ty :: Type
ty <- TvSubstEnv -> TyVar -> Maybe Type
forall a. VarEnv a -> TyVar -> Maybe a
lookupVarEnv TvSubstEnv
tsubst TyVar
tv
      = TvSubstEnv -> VarSet -> VarSet
niSubstTvSet TvSubstEnv
tsubst (Type -> VarSet
tyCoVarsOfType Type
ty)
      | Bool
otherwise
      = TyVar -> VarSet
unitVarSet TyVar
tv
type AmIUnifying = Bool   
                          
unify_ty :: UMEnv
         -> Type -> Type  
         -> CoercionN     
                          
         -> UM ()
unify_ty :: UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty env :: UMEnv
env ty1 :: Type
ty1 ty2 :: Type
ty2 kco :: Coercion
kco
    
  | Just ty1' :: Type
ty1' <- Type -> Maybe Type
tcView Type
ty1   = UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env Type
ty1' Type
ty2 Coercion
kco
  | Just ty2' :: Type
ty2' <- Type -> Maybe Type
tcView Type
ty2   = UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env Type
ty1 Type
ty2' Coercion
kco
  | CastTy ty1' :: Type
ty1' co :: Coercion
co <- Type
ty1     = if UMEnv -> Bool
um_unif UMEnv
env
                                then UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env Type
ty1' Type
ty2 (Coercion
co Coercion -> Coercion -> Coercion
`mkTransCo` Coercion
kco)
                                else 
                                     do { TCvSubst
subst <- UMEnv -> UM TCvSubst
getSubst UMEnv
env
                                        ; let co' :: Coercion
co' = HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo TCvSubst
subst Coercion
co
                                        ; UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env Type
ty1' Type
ty2 (Coercion
co' Coercion -> Coercion -> Coercion
`mkTransCo` Coercion
kco) }
  | CastTy ty2' :: Type
ty2' co :: Coercion
co <- Type
ty2     = UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env Type
ty1 Type
ty2' (Coercion
kco Coercion -> Coercion -> Coercion
`mkTransCo` Coercion -> Coercion
mkSymCo Coercion
co)
unify_ty env :: UMEnv
env (TyVarTy tv1 :: TyVar
tv1) ty2 :: Type
ty2 kco :: Coercion
kco
  = UMEnv -> TyVar -> Type -> Coercion -> UM ()
uVar UMEnv
env TyVar
tv1 Type
ty2 Coercion
kco
unify_ty env :: UMEnv
env ty1 :: Type
ty1 (TyVarTy tv2 :: TyVar
tv2) kco :: Coercion
kco
  | UMEnv -> Bool
um_unif UMEnv
env  
  = UMEnv -> TyVar -> Type -> Coercion -> UM ()
uVar (UMEnv -> UMEnv
umSwapRn UMEnv
env) TyVar
tv2 Type
ty1 (Coercion -> Coercion
mkSymCo Coercion
kco)
unify_ty env :: UMEnv
env ty1 :: Type
ty1 ty2 :: Type
ty2 _kco :: Coercion
_kco
  | Just (tc1 :: TyCon
tc1, tys1 :: [Type]
tys1) <- Maybe (TyCon, [Type])
mb_tc_app1
  , Just (tc2 :: TyCon
tc2, tys2 :: [Type]
tys2) <- Maybe (TyCon, [Type])
mb_tc_app2
  , TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2 Bool -> Bool -> Bool
|| (Type -> Bool
tcIsLiftedTypeKind Type
ty1 Bool -> Bool -> Bool
&& Type -> Bool
tcIsLiftedTypeKind Type
ty2)
  = if TyCon -> Role -> Bool
isInjectiveTyCon TyCon
tc1 Role
Nominal
    then UMEnv -> [Type] -> [Type] -> UM ()
unify_tys UMEnv
env [Type]
tys1 [Type]
tys2
    else do { let inj :: [Bool]
inj | TyCon -> Bool
isTypeFamilyTyCon TyCon
tc1
                      = case TyCon -> Injectivity
tyConInjectivityInfo TyCon
tc1 of
                               NotInjective -> Bool -> [Bool]
forall a. a -> [a]
repeat Bool
False
                               Injective bs :: [Bool]
bs -> [Bool]
bs
                      | Bool
otherwise
                      = Bool -> [Bool]
forall a. a -> [a]
repeat Bool
False
                  (inj_tys1 :: [Type]
inj_tys1, noninj_tys1 :: [Type]
noninj_tys1) = [Bool] -> [Type] -> ([Type], [Type])
forall a. [Bool] -> [a] -> ([a], [a])
partitionByList [Bool]
inj [Type]
tys1
                  (inj_tys2 :: [Type]
inj_tys2, noninj_tys2 :: [Type]
noninj_tys2) = [Bool] -> [Type] -> ([Type], [Type])
forall a. [Bool] -> [a] -> ([a], [a])
partitionByList [Bool]
inj [Type]
tys2
            ; UMEnv -> [Type] -> [Type] -> UM ()
unify_tys UMEnv
env [Type]
inj_tys1 [Type]
inj_tys2
            ; Bool -> UM () -> UM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (UMEnv -> Bool
um_inj_tf UMEnv
env) (UM () -> UM ()) -> UM () -> UM ()
forall a b. (a -> b) -> a -> b
$ 
              UM () -> UM ()
don'tBeSoSure (UM () -> UM ()) -> UM () -> UM ()
forall a b. (a -> b) -> a -> b
$ UMEnv -> [Type] -> [Type] -> UM ()
unify_tys UMEnv
env [Type]
noninj_tys1 [Type]
noninj_tys2 }
  | Just (tc1 :: TyCon
tc1, _) <- Maybe (TyCon, [Type])
mb_tc_app1
  , Bool -> Bool
not (TyCon -> Role -> Bool
isGenerativeTyCon TyCon
tc1 Role
Nominal)
    
    
    
    
  = UM ()
maybeApart
  | Just (tc2 :: TyCon
tc2, _) <- Maybe (TyCon, [Type])
mb_tc_app2
  , Bool -> Bool
not (TyCon -> Role -> Bool
isGenerativeTyCon TyCon
tc2 Role
Nominal)
  , UMEnv -> Bool
um_unif UMEnv
env
    
    
    
  = UM ()
maybeApart
  where
    mb_tc_app1 :: Maybe (TyCon, [Type])
mb_tc_app1 = HasCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe Type
ty1
    mb_tc_app2 :: Maybe (TyCon, [Type])
mb_tc_app2 = HasCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe Type
ty2
        
        
        
        
unify_ty env :: UMEnv
env (AppTy ty1a :: Type
ty1a ty1b :: Type
ty1b) ty2 :: Type
ty2 _kco :: Coercion
_kco
  | Just (ty2a :: Type
ty2a, ty2b :: Type
ty2b) <- Type -> Maybe (Type, Type)
tcRepSplitAppTy_maybe Type
ty2
  = UMEnv -> Type -> [Type] -> Type -> [Type] -> UM ()
unify_ty_app UMEnv
env Type
ty1a [Type
ty1b] Type
ty2a [Type
ty2b]
unify_ty env :: UMEnv
env ty1 :: Type
ty1 (AppTy ty2a :: Type
ty2a ty2b :: Type
ty2b) _kco :: Coercion
_kco
  | Just (ty1a :: Type
ty1a, ty1b :: Type
ty1b) <- Type -> Maybe (Type, Type)
tcRepSplitAppTy_maybe Type
ty1
  = UMEnv -> Type -> [Type] -> Type -> [Type] -> UM ()
unify_ty_app UMEnv
env Type
ty1a [Type
ty1b] Type
ty2a [Type
ty2b]
unify_ty _ (LitTy x :: TyLit
x) (LitTy y :: TyLit
y) _kco :: Coercion
_kco | TyLit
x TyLit -> TyLit -> Bool
forall a. Eq a => a -> a -> Bool
== TyLit
y = () -> UM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
unify_ty env :: UMEnv
env (ForAllTy (Bndr tv1 :: TyVar
tv1 _) ty1 :: Type
ty1) (ForAllTy (Bndr tv2 :: TyVar
tv2 _) ty2 :: Type
ty2) kco :: Coercion
kco
  = do { UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env (TyVar -> Type
varType TyVar
tv1) (TyVar -> Type
varType TyVar
tv2) (Type -> Coercion
mkNomReflCo Type
liftedTypeKind)
       ; let env' :: UMEnv
env' = UMEnv -> TyVar -> TyVar -> UMEnv
umRnBndr2 UMEnv
env TyVar
tv1 TyVar
tv2
       ; UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env' Type
ty1 Type
ty2 Coercion
kco }
unify_ty env :: UMEnv
env (CoercionTy co1 :: Coercion
co1) (CoercionTy co2 :: Coercion
co2) kco :: Coercion
kco
  = do { CvSubstEnv
c_subst <- UM CvSubstEnv
getCvSubstEnv
       ; case Coercion
co1 of
           CoVarCo cv :: TyVar
cv
             | Bool -> Bool
not (UMEnv -> Bool
um_unif UMEnv
env)
             , Bool -> Bool
not (TyVar
cv TyVar -> CvSubstEnv -> Bool
forall a. TyVar -> VarEnv a -> Bool
`elemVarEnv` CvSubstEnv
c_subst)
             , BindFlag
BindMe <- UMEnv -> TyVar -> BindFlag
tvBindFlag UMEnv
env TyVar
cv
             -> do { UMEnv -> VarSet -> UM ()
checkRnEnv UMEnv
env (Coercion -> VarSet
tyCoVarsOfCo Coercion
co2)
                   ; let (co_l :: Coercion
co_l, co_r :: Coercion
co_r) = HasDebugCallStack => Role -> Coercion -> (Coercion, Coercion)
Role -> Coercion -> (Coercion, Coercion)
decomposeFunCo Role
Nominal Coercion
kco
                      
                      
                      
                      
                   ; TyVar -> Coercion -> UM ()
extendCvEnv TyVar
cv (Coercion
co_l Coercion -> Coercion -> Coercion
`mkTransCo`
                                     Coercion
co2 Coercion -> Coercion -> Coercion
`mkTransCo`
                                     Coercion -> Coercion
mkSymCo Coercion
co_r) }
           _ -> () -> UM ()
forall (m :: * -> *) a. Monad m => a -> m a
return () }
unify_ty _ _ _ _ = UM ()
forall a. UM a
surelyApart
unify_ty_app :: UMEnv -> Type -> [Type] -> Type -> [Type] -> UM ()
unify_ty_app :: UMEnv -> Type -> [Type] -> Type -> [Type] -> UM ()
unify_ty_app env :: UMEnv
env ty1 :: Type
ty1 ty1args :: [Type]
ty1args ty2 :: Type
ty2 ty2args :: [Type]
ty2args
  | Just (ty1' :: Type
ty1', ty1a :: Type
ty1a) <- HasDebugCallStack => Type -> Maybe (Type, Type)
Type -> Maybe (Type, Type)
repSplitAppTy_maybe Type
ty1
  , Just (ty2' :: Type
ty2', ty2a :: Type
ty2a) <- HasDebugCallStack => Type -> Maybe (Type, Type)
Type -> Maybe (Type, Type)
repSplitAppTy_maybe Type
ty2
  = UMEnv -> Type -> [Type] -> Type -> [Type] -> UM ()
unify_ty_app UMEnv
env Type
ty1' (Type
ty1a Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type]
ty1args) Type
ty2' (Type
ty2a Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type]
ty2args)
  | Bool
otherwise
  = do { let ki1 :: Type
ki1 = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
ty1
             ki2 :: Type
ki2 = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
ty2
           
       ; UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty  UMEnv
env Type
ki1 Type
ki2 (Type -> Coercion
mkNomReflCo Type
liftedTypeKind)
       ; UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty  UMEnv
env Type
ty1 Type
ty2 (Type -> Coercion
mkNomReflCo Type
ki1)
       ; UMEnv -> [Type] -> [Type] -> UM ()
unify_tys UMEnv
env [Type]
ty1args [Type]
ty2args }
unify_tys :: UMEnv -> [Type] -> [Type] -> UM ()
unify_tys :: UMEnv -> [Type] -> [Type] -> UM ()
unify_tys env :: UMEnv
env orig_xs :: [Type]
orig_xs orig_ys :: [Type]
orig_ys
  = [Type] -> [Type] -> UM ()
go [Type]
orig_xs [Type]
orig_ys
  where
    go :: [Type] -> [Type] -> UM ()
go []     []     = () -> UM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    go (x :: Type
x:xs :: [Type]
xs) (y :: Type
y:ys :: [Type]
ys)
      
      = do { UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env Type
x Type
y (Type -> Coercion
mkNomReflCo (Type -> Coercion) -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$ HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
x)
           ; [Type] -> [Type] -> UM ()
go [Type]
xs [Type]
ys }
    go _ _ = UM ()
forall a. UM a
surelyApart
      
      
uVar :: UMEnv
     -> InTyVar         
     -> Type            
     -> Coercion        
     -> UM ()
uVar :: UMEnv -> TyVar -> Type -> Coercion -> UM ()
uVar env :: UMEnv
env tv1 :: TyVar
tv1 ty :: Type
ty kco :: Coercion
kco
 = do { 
        let tv1' :: TyVar
tv1' = UMEnv -> TyVar -> TyVar
umRnOccL UMEnv
env TyVar
tv1
        
      ; TvSubstEnv
subst <- UM TvSubstEnv
getTvSubstEnv
      ; case (TvSubstEnv -> TyVar -> Maybe Type
forall a. VarEnv a -> TyVar -> Maybe a
lookupVarEnv TvSubstEnv
subst TyVar
tv1') of
          Just ty' :: Type
ty' | UMEnv -> Bool
um_unif UMEnv
env                
                   -> UMEnv -> Type -> Type -> Coercion -> UM ()
unify_ty UMEnv
env Type
ty' Type
ty Coercion
kco   
                   | Bool
otherwise
                   -> 
                      
                      
                      
                      Bool -> UM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard ((Type
ty' Type -> Coercion -> Type
`mkCastTy` Coercion
kco) Type -> Type -> Bool
`eqType` Type
ty)
          Nothing  -> UMEnv -> TyVar -> Type -> Type -> Coercion -> UM ()
uUnrefined UMEnv
env TyVar
tv1' Type
ty Type
ty Coercion
kco } 
uUnrefined :: UMEnv
           -> OutTyVar          
           -> Type              
           -> Type              
           -> Coercion          
           -> UM ()
uUnrefined :: UMEnv -> TyVar -> Type -> Type -> Coercion -> UM ()
uUnrefined env :: UMEnv
env tv1' :: TyVar
tv1' ty2 :: Type
ty2 ty2' :: Type
ty2' kco :: Coercion
kco
  | Just ty2'' :: Type
ty2'' <- Type -> Maybe Type
coreView Type
ty2'
  = UMEnv -> TyVar -> Type -> Type -> Coercion -> UM ()
uUnrefined UMEnv
env TyVar
tv1' Type
ty2 Type
ty2'' Coercion
kco    
                
                
                
  | TyVarTy tv2 :: TyVar
tv2 <- Type
ty2'
  = do { let tv2' :: TyVar
tv2' = UMEnv -> TyVar -> TyVar
umRnOccR UMEnv
env TyVar
tv2
       ; Bool -> UM () -> UM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (TyVar
tv1' TyVar -> TyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyVar
tv2' Bool -> Bool -> Bool
&& UMEnv -> Bool
um_unif UMEnv
env) (UM () -> UM ()) -> UM () -> UM ()
forall a b. (a -> b) -> a -> b
$ do
           
           
           
          
       { TvSubstEnv
subst <- UM TvSubstEnv
getTvSubstEnv
       ; case TvSubstEnv -> TyVar -> Maybe Type
forall a. VarEnv a -> TyVar -> Maybe a
lookupVarEnv TvSubstEnv
subst TyVar
tv2 of
         {  Just ty' :: Type
ty' | UMEnv -> Bool
um_unif UMEnv
env -> UMEnv -> TyVar -> Type -> Type -> Coercion -> UM ()
uUnrefined UMEnv
env TyVar
tv1' Type
ty' Type
ty' Coercion
kco
         ;  _ ->
    do {   
           
       ; let b1 :: BindFlag
b1  = UMEnv -> TyVar -> BindFlag
tvBindFlag UMEnv
env TyVar
tv1'
             b2 :: BindFlag
b2  = UMEnv -> TyVar -> BindFlag
tvBindFlag UMEnv
env TyVar
tv2'
             ty1 :: Type
ty1 = TyVar -> Type
mkTyVarTy TyVar
tv1'
       ; case (BindFlag
b1, BindFlag
b2) of
           (BindMe, _) -> UMEnv -> TyVar -> Type -> UM ()
bindTv UMEnv
env TyVar
tv1' (Type
ty2 Type -> Coercion -> Type
`mkCastTy` Coercion -> Coercion
mkSymCo Coercion
kco)
           (_, BindMe) | UMEnv -> Bool
um_unif UMEnv
env
                       -> UMEnv -> TyVar -> Type -> UM ()
bindTv (UMEnv -> UMEnv
umSwapRn UMEnv
env) TyVar
tv2 (Type
ty1 Type -> Coercion -> Type
`mkCastTy` Coercion
kco)
           _ | TyVar
tv1' TyVar -> TyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyVar
tv2' -> () -> UM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
             
             
           _ -> UM ()
maybeApart 
  }}}}
uUnrefined env :: UMEnv
env tv1' :: TyVar
tv1' ty2 :: Type
ty2 _ kco :: Coercion
kco 
  = case UMEnv -> TyVar -> BindFlag
tvBindFlag UMEnv
env TyVar
tv1' of
      Skolem -> UM ()
maybeApart  
      BindMe -> UMEnv -> TyVar -> Type -> UM ()
bindTv UMEnv
env TyVar
tv1' (Type
ty2 Type -> Coercion -> Type
`mkCastTy` Coercion -> Coercion
mkSymCo Coercion
kco)
bindTv :: UMEnv -> OutTyVar -> Type -> UM ()
bindTv :: UMEnv -> TyVar -> Type -> UM ()
bindTv env :: UMEnv
env tv1 :: TyVar
tv1 ty2 :: Type
ty2
  = do  { let free_tvs2 :: VarSet
free_tvs2 = Type -> VarSet
tyCoVarsOfType Type
ty2
        
        
        
        ; UMEnv -> VarSet -> UM ()
checkRnEnv UMEnv
env VarSet
free_tvs2
        
        
        ; Bool
occurs <- UMEnv -> TyVar -> VarSet -> UM Bool
occursCheck UMEnv
env TyVar
tv1 VarSet
free_tvs2
        ; if Bool
occurs then UM ()
maybeApart
                    else TyVar -> Type -> UM ()
extendTvEnv TyVar
tv1 Type
ty2 }
occursCheck :: UMEnv -> TyVar -> VarSet -> UM Bool
occursCheck :: UMEnv -> TyVar -> VarSet -> UM Bool
occursCheck env :: UMEnv
env tv :: TyVar
tv free_tvs :: VarSet
free_tvs
  | UMEnv -> Bool
um_unif UMEnv
env
  = do { TvSubstEnv
tsubst <- UM TvSubstEnv
getTvSubstEnv
       ; Bool -> UM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (TyVar
tv TyVar -> VarSet -> Bool
`elemVarSet` TvSubstEnv -> VarSet -> VarSet
niSubstTvSet TvSubstEnv
tsubst VarSet
free_tvs) }
  | Bool
otherwise      
  = Bool -> UM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False   
data BindFlag
  = BindMe      
  | Skolem      
                
  deriving BindFlag -> BindFlag -> Bool
(BindFlag -> BindFlag -> Bool)
-> (BindFlag -> BindFlag -> Bool) -> Eq BindFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BindFlag -> BindFlag -> Bool
$c/= :: BindFlag -> BindFlag -> Bool
== :: BindFlag -> BindFlag -> Bool
$c== :: BindFlag -> BindFlag -> Bool
Eq
data UMEnv
  = UMEnv { UMEnv -> Bool
um_unif :: AmIUnifying
          , UMEnv -> Bool
um_inj_tf :: Bool
            
            
          , UMEnv -> RnEnv2
um_rn_env :: RnEnv2
            
            
            
          , UMEnv -> VarSet
um_skols :: TyVarSet
            
            
            
          , UMEnv -> TyVar -> BindFlag
um_bind_fun :: TyVar -> BindFlag
            
            
          }
data UMState = UMState
                   { UMState -> TvSubstEnv
um_tv_env   :: TvSubstEnv
                   , UMState -> CvSubstEnv
um_cv_env   :: CvSubstEnv }
newtype UM a = UM { UM a -> UMState -> UnifyResultM (UMState, a)
unUM :: UMState -> UnifyResultM (UMState, a) }
instance Functor UM where
      fmap :: (a -> b) -> UM a -> UM b
fmap = (a -> b) -> UM a -> UM b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
instance Applicative UM where
      pure :: a -> UM a
pure a :: a
a = (UMState -> UnifyResultM (UMState, a)) -> UM a
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM (\s :: UMState
s -> (UMState, a) -> UnifyResultM (UMState, a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (UMState
s, a
a))
      <*> :: UM (a -> b) -> UM a -> UM b
(<*>)  = UM (a -> b) -> UM a -> UM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad UM where
#if !MIN_VERSION_base(4,13,0)
  fail     = MonadFail.fail
#endif
  m :: UM a
m >>= :: UM a -> (a -> UM b) -> UM b
>>= k :: a -> UM b
k  = (UMState -> UnifyResultM (UMState, b)) -> UM b
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM (\state :: UMState
state ->
                  do { (state' :: UMState
state', v :: a
v) <- UM a -> UMState -> UnifyResultM (UMState, a)
forall a. UM a -> UMState -> UnifyResultM (UMState, a)
unUM UM a
m UMState
state
                     ; UM b -> UMState -> UnifyResultM (UMState, b)
forall a. UM a -> UMState -> UnifyResultM (UMState, a)
unUM (a -> UM b
k a
v) UMState
state' })
instance Alternative UM where
  empty :: UM a
empty     = (UMState -> UnifyResultM (UMState, a)) -> UM a
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM (\_ -> UnifyResultM (UMState, a)
forall (f :: * -> *) a. Alternative f => f a
Control.Applicative.empty)
  m1 :: UM a
m1 <|> :: UM a -> UM a -> UM a
<|> m2 :: UM a
m2 = (UMState -> UnifyResultM (UMState, a)) -> UM a
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM (\state :: UMState
state ->
                  UM a -> UMState -> UnifyResultM (UMState, a)
forall a. UM a -> UMState -> UnifyResultM (UMState, a)
unUM UM a
m1 UMState
state UnifyResultM (UMState, a)
-> UnifyResultM (UMState, a) -> UnifyResultM (UMState, a)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                  UM a -> UMState -> UnifyResultM (UMState, a)
forall a. UM a -> UMState -> UnifyResultM (UMState, a)
unUM UM a
m2 UMState
state)
instance MonadPlus UM
instance MonadFail.MonadFail UM where
    fail :: String -> UM a
fail _   = (UMState -> UnifyResultM (UMState, a)) -> UM a
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM (\_ -> UnifyResultM (UMState, a)
forall a. UnifyResultM a
SurelyApart) 
initUM :: TvSubstEnv  
       -> CvSubstEnv
       -> UM a -> UnifyResultM a
initUM :: TvSubstEnv -> CvSubstEnv -> UM a -> UnifyResultM a
initUM subst_env :: TvSubstEnv
subst_env cv_subst_env :: CvSubstEnv
cv_subst_env um :: UM a
um
  = case UM a -> UMState -> UnifyResultM (UMState, a)
forall a. UM a -> UMState -> UnifyResultM (UMState, a)
unUM UM a
um UMState
state of
      Unifiable (_, subst :: a
subst)  -> a -> UnifyResultM a
forall a. a -> UnifyResultM a
Unifiable a
subst
      MaybeApart (_, subst :: a
subst) -> a -> UnifyResultM a
forall a. a -> UnifyResultM a
MaybeApart a
subst
      SurelyApart           -> UnifyResultM a
forall a. UnifyResultM a
SurelyApart
  where
    state :: UMState
state = UMState :: TvSubstEnv -> CvSubstEnv -> UMState
UMState { um_tv_env :: TvSubstEnv
um_tv_env = TvSubstEnv
subst_env
                    , um_cv_env :: CvSubstEnv
um_cv_env = CvSubstEnv
cv_subst_env }
tvBindFlag :: UMEnv -> OutTyVar -> BindFlag
tvBindFlag :: UMEnv -> TyVar -> BindFlag
tvBindFlag env :: UMEnv
env tv :: TyVar
tv
  | TyVar
tv TyVar -> VarSet -> Bool
`elemVarSet` UMEnv -> VarSet
um_skols UMEnv
env = BindFlag
Skolem
  | Bool
otherwise                    = UMEnv -> TyVar -> BindFlag
um_bind_fun UMEnv
env TyVar
tv
getTvSubstEnv :: UM TvSubstEnv
getTvSubstEnv :: UM TvSubstEnv
getTvSubstEnv = (UMState -> UnifyResultM (UMState, TvSubstEnv)) -> UM TvSubstEnv
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM ((UMState -> UnifyResultM (UMState, TvSubstEnv)) -> UM TvSubstEnv)
-> (UMState -> UnifyResultM (UMState, TvSubstEnv)) -> UM TvSubstEnv
forall a b. (a -> b) -> a -> b
$ \state :: UMState
state -> (UMState, TvSubstEnv) -> UnifyResultM (UMState, TvSubstEnv)
forall a. a -> UnifyResultM a
Unifiable (UMState
state, UMState -> TvSubstEnv
um_tv_env UMState
state)
getCvSubstEnv :: UM CvSubstEnv
getCvSubstEnv :: UM CvSubstEnv
getCvSubstEnv = (UMState -> UnifyResultM (UMState, CvSubstEnv)) -> UM CvSubstEnv
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM ((UMState -> UnifyResultM (UMState, CvSubstEnv)) -> UM CvSubstEnv)
-> (UMState -> UnifyResultM (UMState, CvSubstEnv)) -> UM CvSubstEnv
forall a b. (a -> b) -> a -> b
$ \state :: UMState
state -> (UMState, CvSubstEnv) -> UnifyResultM (UMState, CvSubstEnv)
forall a. a -> UnifyResultM a
Unifiable (UMState
state, UMState -> CvSubstEnv
um_cv_env UMState
state)
getSubst :: UMEnv -> UM TCvSubst
getSubst :: UMEnv -> UM TCvSubst
getSubst env :: UMEnv
env = do { TvSubstEnv
tv_env <- UM TvSubstEnv
getTvSubstEnv
                  ; CvSubstEnv
cv_env <- UM CvSubstEnv
getCvSubstEnv
                  ; let in_scope :: InScopeSet
in_scope = RnEnv2 -> InScopeSet
rnInScopeSet (UMEnv -> RnEnv2
um_rn_env UMEnv
env)
                  ; TCvSubst -> UM TCvSubst
forall (m :: * -> *) a. Monad m => a -> m a
return (InScopeSet -> (TvSubstEnv, CvSubstEnv) -> TCvSubst
mkTCvSubst InScopeSet
in_scope (TvSubstEnv
tv_env, CvSubstEnv
cv_env)) }
extendTvEnv :: TyVar -> Type -> UM ()
extendTvEnv :: TyVar -> Type -> UM ()
extendTvEnv tv :: TyVar
tv ty :: Type
ty = (UMState -> UnifyResultM (UMState, ())) -> UM ()
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM ((UMState -> UnifyResultM (UMState, ())) -> UM ())
-> (UMState -> UnifyResultM (UMState, ())) -> UM ()
forall a b. (a -> b) -> a -> b
$ \state :: UMState
state ->
  (UMState, ()) -> UnifyResultM (UMState, ())
forall a. a -> UnifyResultM a
Unifiable (UMState
state { um_tv_env :: TvSubstEnv
um_tv_env = TvSubstEnv -> TyVar -> Type -> TvSubstEnv
forall a. VarEnv a -> TyVar -> a -> VarEnv a
extendVarEnv (UMState -> TvSubstEnv
um_tv_env UMState
state) TyVar
tv Type
ty }, ())
extendCvEnv :: CoVar -> Coercion -> UM ()
extendCvEnv :: TyVar -> Coercion -> UM ()
extendCvEnv cv :: TyVar
cv co :: Coercion
co = (UMState -> UnifyResultM (UMState, ())) -> UM ()
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM ((UMState -> UnifyResultM (UMState, ())) -> UM ())
-> (UMState -> UnifyResultM (UMState, ())) -> UM ()
forall a b. (a -> b) -> a -> b
$ \state :: UMState
state ->
  (UMState, ()) -> UnifyResultM (UMState, ())
forall a. a -> UnifyResultM a
Unifiable (UMState
state { um_cv_env :: CvSubstEnv
um_cv_env = CvSubstEnv -> TyVar -> Coercion -> CvSubstEnv
forall a. VarEnv a -> TyVar -> a -> VarEnv a
extendVarEnv (UMState -> CvSubstEnv
um_cv_env UMState
state) TyVar
cv Coercion
co }, ())
umRnBndr2 :: UMEnv -> TyCoVar -> TyCoVar -> UMEnv
umRnBndr2 :: UMEnv -> TyVar -> TyVar -> UMEnv
umRnBndr2 env :: UMEnv
env v1 :: TyVar
v1 v2 :: TyVar
v2
  = UMEnv
env { um_rn_env :: RnEnv2
um_rn_env = RnEnv2
rn_env', um_skols :: VarSet
um_skols = UMEnv -> VarSet
um_skols UMEnv
env VarSet -> TyVar -> VarSet
`extendVarSet` TyVar
v' }
  where
    (rn_env' :: RnEnv2
rn_env', v' :: TyVar
v') = RnEnv2 -> TyVar -> TyVar -> (RnEnv2, TyVar)
rnBndr2_var (UMEnv -> RnEnv2
um_rn_env UMEnv
env) TyVar
v1 TyVar
v2
checkRnEnv :: UMEnv -> VarSet -> UM ()
checkRnEnv :: UMEnv -> VarSet -> UM ()
checkRnEnv env :: UMEnv
env varset :: VarSet
varset
  | VarSet -> Bool
isEmptyVarSet VarSet
skol_vars           = () -> UM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  | VarSet
varset VarSet -> VarSet -> Bool
`disjointVarSet` VarSet
skol_vars = () -> UM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  | Bool
otherwise                         = UM ()
maybeApart
               
               
  where
    skol_vars :: VarSet
skol_vars = UMEnv -> VarSet
um_skols UMEnv
env
    
    
    
don'tBeSoSure :: UM () -> UM ()
don'tBeSoSure :: UM () -> UM ()
don'tBeSoSure um :: UM ()
um = (UMState -> UnifyResultM (UMState, ())) -> UM ()
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM ((UMState -> UnifyResultM (UMState, ())) -> UM ())
-> (UMState -> UnifyResultM (UMState, ())) -> UM ()
forall a b. (a -> b) -> a -> b
$ \ state :: UMState
state ->
  case UM () -> UMState -> UnifyResultM (UMState, ())
forall a. UM a -> UMState -> UnifyResultM (UMState, a)
unUM UM ()
um UMState
state of
    SurelyApart -> (UMState, ()) -> UnifyResultM (UMState, ())
forall a. a -> UnifyResultM a
MaybeApart (UMState
state, ())
    other :: UnifyResultM (UMState, ())
other       -> UnifyResultM (UMState, ())
other
umRnOccL :: UMEnv -> TyVar -> TyVar
umRnOccL :: UMEnv -> TyVar -> TyVar
umRnOccL env :: UMEnv
env v :: TyVar
v = RnEnv2 -> TyVar -> TyVar
rnOccL (UMEnv -> RnEnv2
um_rn_env UMEnv
env) TyVar
v
umRnOccR :: UMEnv -> TyVar -> TyVar
umRnOccR :: UMEnv -> TyVar -> TyVar
umRnOccR env :: UMEnv
env v :: TyVar
v = RnEnv2 -> TyVar -> TyVar
rnOccR (UMEnv -> RnEnv2
um_rn_env UMEnv
env) TyVar
v
umSwapRn :: UMEnv -> UMEnv
umSwapRn :: UMEnv -> UMEnv
umSwapRn env :: UMEnv
env = UMEnv
env { um_rn_env :: RnEnv2
um_rn_env = RnEnv2 -> RnEnv2
rnSwap (UMEnv -> RnEnv2
um_rn_env UMEnv
env) }
maybeApart :: UM ()
maybeApart :: UM ()
maybeApart = (UMState -> UnifyResultM (UMState, ())) -> UM ()
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM (\state :: UMState
state -> (UMState, ()) -> UnifyResultM (UMState, ())
forall a. a -> UnifyResultM a
MaybeApart (UMState
state, ()))
surelyApart :: UM a
surelyApart :: UM a
surelyApart = (UMState -> UnifyResultM (UMState, a)) -> UM a
forall a. (UMState -> UnifyResultM (UMState, a)) -> UM a
UM (\_ -> UnifyResultM (UMState, a)
forall a. UnifyResultM a
SurelyApart)
data MatchEnv = ME { MatchEnv -> VarSet
me_tmpls :: TyVarSet
                   , MatchEnv -> RnEnv2
me_env   :: RnEnv2 }
liftCoMatch :: TyCoVarSet -> Type -> Coercion -> Maybe LiftingContext
liftCoMatch :: VarSet -> Type -> Coercion -> Maybe LiftingContext
liftCoMatch tmpls :: VarSet
tmpls ty :: Type
ty co :: Coercion
co
  = do { CvSubstEnv
cenv1 <- MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
forall a. VarEnv a
emptyVarEnv Type
ki Coercion
ki_co Coercion
ki_ki_co Coercion
ki_ki_co
       ; CvSubstEnv
cenv2 <- MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
cenv1       Type
ty Coercion
co
                              (Type -> Coercion
mkNomReflCo Type
co_lkind) (Type -> Coercion
mkNomReflCo Type
co_rkind)
       ; LiftingContext -> Maybe LiftingContext
forall (m :: * -> *) a. Monad m => a -> m a
return (TCvSubst -> CvSubstEnv -> LiftingContext
LC (InScopeSet -> TCvSubst
mkEmptyTCvSubst InScopeSet
in_scope) CvSubstEnv
cenv2) }
  where
    menv :: MatchEnv
menv     = ME :: VarSet -> RnEnv2 -> MatchEnv
ME { me_tmpls :: VarSet
me_tmpls = VarSet
tmpls, me_env :: RnEnv2
me_env = InScopeSet -> RnEnv2
mkRnEnv2 InScopeSet
in_scope }
    in_scope :: InScopeSet
in_scope = VarSet -> InScopeSet
mkInScopeSet (VarSet
tmpls VarSet -> VarSet -> VarSet
`unionVarSet` Coercion -> VarSet
tyCoVarsOfCo Coercion
co)
    
    
    ki :: Type
ki       = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
ty
    ki_co :: Coercion
ki_co    = Coercion -> Coercion
promoteCoercion Coercion
co
    ki_ki_co :: Coercion
ki_ki_co = Type -> Coercion
mkNomReflCo Type
liftedTypeKind
    Pair co_lkind :: Type
co_lkind co_rkind :: Type
co_rkind = Coercion -> Pair Type
coercionKind Coercion
ki_co
ty_co_match :: MatchEnv   
            -> LiftCoEnv  
            -> Type       
            -> Coercion   
            -> Coercion   
            -> Coercion   
            -> Maybe LiftCoEnv
ty_co_match :: MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty :: Type
ty co :: Coercion
co lkco :: Coercion
lkco rkco :: Coercion
rkco
  | Just ty' :: Type
ty' <- Type -> Maybe Type
coreView Type
ty = MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ty' Coercion
co Coercion
lkco Coercion
rkco
  
  | Type -> VarSet
tyCoVarsOfType Type
ty VarSet -> CvSubstEnv -> Bool
forall a. VarSet -> VarEnv a -> Bool
`isNotInDomainOf` CvSubstEnv
subst
  , Just (ty' :: Type
ty', _) <- Coercion -> Maybe (Type, Role)
isReflCo_maybe Coercion
co
  , Type
ty Type -> Type -> Bool
`eqType` Type
ty'
  = CvSubstEnv -> Maybe CvSubstEnv
forall a. a -> Maybe a
Just CvSubstEnv
subst
  where
    isNotInDomainOf :: VarSet -> VarEnv a -> Bool
    isNotInDomainOf :: VarSet -> VarEnv a -> Bool
isNotInDomainOf set :: VarSet
set env :: VarEnv a
env
      = (TyVar -> Bool) -> VarSet -> Bool
noneSet (\v :: TyVar
v -> TyVar -> VarEnv a -> Bool
forall a. TyVar -> VarEnv a -> Bool
elemVarEnv TyVar
v VarEnv a
env) VarSet
set
    noneSet :: (Var -> Bool) -> VarSet -> Bool
    noneSet :: (TyVar -> Bool) -> VarSet -> Bool
noneSet f :: TyVar -> Bool
f = (TyVar -> Bool) -> VarSet -> Bool
allVarSet (Bool -> Bool
not (Bool -> Bool) -> (TyVar -> Bool) -> TyVar -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVar -> Bool
f)
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty :: Type
ty co :: Coercion
co lkco :: Coercion
lkco rkco :: Coercion
rkco
  | CastTy ty' :: Type
ty' co' :: Coercion
co' <- Type
ty
     
  = let empty_subst :: TCvSubst
empty_subst  = InScopeSet -> TCvSubst
mkEmptyTCvSubst (RnEnv2 -> InScopeSet
rnInScopeSet (MatchEnv -> RnEnv2
me_env MatchEnv
menv))
        substed_co_l :: Coercion
substed_co_l = HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo (TCvSubst -> CvSubstEnv -> TCvSubst
liftEnvSubstLeft TCvSubst
empty_subst CvSubstEnv
subst)  Coercion
co'
        substed_co_r :: Coercion
substed_co_r = HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo (TCvSubst -> CvSubstEnv -> TCvSubst
liftEnvSubstRight TCvSubst
empty_subst CvSubstEnv
subst) Coercion
co'
    in
    MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ty' Coercion
co (Coercion
substed_co_l Coercion -> Coercion -> Coercion
`mkTransCo` Coercion
lkco)
                                  (Coercion
substed_co_r Coercion -> Coercion -> Coercion
`mkTransCo` Coercion
rkco)
  | SymCo co' :: Coercion
co' <- Coercion
co
  = CvSubstEnv -> CvSubstEnv
swapLiftCoEnv (CvSubstEnv -> CvSubstEnv) -> Maybe CvSubstEnv -> Maybe CvSubstEnv
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv (CvSubstEnv -> CvSubstEnv
swapLiftCoEnv CvSubstEnv
subst) Type
ty Coercion
co' Coercion
rkco Coercion
lkco
  
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst (TyVarTy tv1 :: TyVar
tv1) co :: Coercion
co lkco :: Coercion
lkco rkco :: Coercion
rkco
  | Just co1' :: Coercion
co1' <- CvSubstEnv -> TyVar -> Maybe Coercion
forall a. VarEnv a -> TyVar -> Maybe a
lookupVarEnv CvSubstEnv
subst TyVar
tv1' 
  = if RnEnv2 -> Coercion -> Coercion -> Bool
eqCoercionX (RnEnv2 -> RnEnv2
nukeRnEnvL RnEnv2
rn_env) Coercion
co1' Coercion
co
    then CvSubstEnv -> Maybe CvSubstEnv
forall a. a -> Maybe a
Just CvSubstEnv
subst
    else Maybe CvSubstEnv
forall a. Maybe a
Nothing       
  | TyVar
tv1' TyVar -> VarSet -> Bool
`elemVarSet` MatchEnv -> VarSet
me_tmpls MatchEnv
menv           
  = if (TyVar -> Bool) -> [TyVar] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (RnEnv2 -> TyVar -> Bool
inRnEnvR RnEnv2
rn_env) (Coercion -> [TyVar]
tyCoVarsOfCoList Coercion
co)
    then Maybe CvSubstEnv
forall a. Maybe a
Nothing      
    else CvSubstEnv -> Maybe CvSubstEnv
forall a. a -> Maybe a
Just (CvSubstEnv -> Maybe CvSubstEnv) -> CvSubstEnv -> Maybe CvSubstEnv
forall a b. (a -> b) -> a -> b
$ CvSubstEnv -> TyVar -> Coercion -> CvSubstEnv
forall a. VarEnv a -> TyVar -> a -> VarEnv a
extendVarEnv CvSubstEnv
subst TyVar
tv1' (Coercion -> CvSubstEnv) -> Coercion -> CvSubstEnv
forall a b. (a -> b) -> a -> b
$
                Coercion -> Coercion -> Coercion -> Coercion
castCoercionKindI Coercion
co (Coercion -> Coercion
mkSymCo Coercion
lkco) (Coercion -> Coercion
mkSymCo Coercion
rkco)
  | Bool
otherwise
  = Maybe CvSubstEnv
forall a. Maybe a
Nothing
  where
    rn_env :: RnEnv2
rn_env = MatchEnv -> RnEnv2
me_env MatchEnv
menv
    tv1' :: TyVar
tv1' = RnEnv2 -> TyVar -> TyVar
rnOccL RnEnv2
rn_env TyVar
tv1
  
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty :: Type
ty (SubCo co :: Coercion
co) lkco :: Coercion
lkco rkco :: Coercion
rkco
  = MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ty Coercion
co Coercion
lkco Coercion
rkco
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst (AppTy ty1a :: Type
ty1a ty1b :: Type
ty1b) co :: Coercion
co _lkco :: Coercion
_lkco _rkco :: Coercion
_rkco
  | Just (co2 :: Coercion
co2, arg2 :: Coercion
arg2) <- Coercion -> Maybe (Coercion, Coercion)
splitAppCo_maybe Coercion
co     
  = MatchEnv
-> CvSubstEnv
-> Type
-> [Type]
-> Coercion
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_app MatchEnv
menv CvSubstEnv
subst Type
ty1a [Type
ty1b] Coercion
co2 [Coercion
arg2]
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty1 :: Type
ty1 (AppCo co2 :: Coercion
co2 arg2 :: Coercion
arg2) _lkco :: Coercion
_lkco _rkco :: Coercion
_rkco
  | Just (ty1a :: Type
ty1a, ty1b :: Type
ty1b) <- HasDebugCallStack => Type -> Maybe (Type, Type)
Type -> Maybe (Type, Type)
repSplitAppTy_maybe Type
ty1
       
  = MatchEnv
-> CvSubstEnv
-> Type
-> [Type]
-> Coercion
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_app MatchEnv
menv CvSubstEnv
subst Type
ty1a [Type
ty1b] Coercion
co2 [Coercion
arg2]
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst (TyConApp tc1 :: TyCon
tc1 tys :: [Type]
tys) (TyConAppCo _ tc2 :: TyCon
tc2 cos :: [Coercion]
cos) _lkco :: Coercion
_lkco _rkco :: Coercion
_rkco
  = MatchEnv
-> CvSubstEnv
-> TyCon
-> [Type]
-> TyCon
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_tc MatchEnv
menv CvSubstEnv
subst TyCon
tc1 [Type]
tys TyCon
tc2 [Coercion]
cos
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst (FunTy ty1 :: Type
ty1 ty2 :: Type
ty2) co :: Coercion
co _lkco :: Coercion
_lkco _rkco :: Coercion
_rkco
    
    
    
    
  | Just (tc :: TyCon
tc, [_,_,co1 :: Coercion
co1,co2 :: Coercion
co2]) <- Coercion -> Maybe (TyCon, [Coercion])
splitTyConAppCo_maybe Coercion
co
  , TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
funTyCon
  = let Pair lkcos :: [Coercion]
lkcos rkcos :: [Coercion]
rkcos = (Coercion -> Pair Coercion) -> [Coercion] -> Pair [Coercion]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Type -> Coercion) -> Pair Type -> Pair Coercion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Coercion
mkNomReflCo (Pair Type -> Pair Coercion)
-> (Coercion -> Pair Type) -> Coercion -> Pair Coercion
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coercion -> Pair Type
coercionKind) [Coercion
co1,Coercion
co2]
    in MatchEnv
-> CvSubstEnv
-> [Type]
-> [Coercion]
-> [Coercion]
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_args MatchEnv
menv CvSubstEnv
subst [Type
ty1, Type
ty2] [Coercion
co1, Coercion
co2] [Coercion]
lkcos [Coercion]
rkcos
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst (ForAllTy (Bndr tv1 :: TyVar
tv1 _) ty1 :: Type
ty1)
                       (ForAllCo tv2 :: TyVar
tv2 kind_co2 :: Coercion
kind_co2 co2 :: Coercion
co2)
                       lkco :: Coercion
lkco rkco :: Coercion
rkco
  | TyVar -> Bool
isTyVar TyVar
tv1 Bool -> Bool -> Bool
&& TyVar -> Bool
isTyVar TyVar
tv2
  = do { CvSubstEnv
subst1 <- MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst (TyVar -> Type
tyVarKind TyVar
tv1) Coercion
kind_co2
                               Coercion
ki_ki_co Coercion
ki_ki_co
       ; let rn_env0 :: RnEnv2
rn_env0 = MatchEnv -> RnEnv2
me_env MatchEnv
menv
             rn_env1 :: RnEnv2
rn_env1 = RnEnv2 -> TyVar -> TyVar -> RnEnv2
rnBndr2 RnEnv2
rn_env0 TyVar
tv1 TyVar
tv2
             menv' :: MatchEnv
menv'   = MatchEnv
menv { me_env :: RnEnv2
me_env = RnEnv2
rn_env1 }
       ; MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv' CvSubstEnv
subst1 Type
ty1 Coercion
co2 Coercion
lkco Coercion
rkco }
  where
    ki_ki_co :: Coercion
ki_ki_co = Type -> Coercion
mkNomReflCo Type
liftedTypeKind
ty_co_match _ subst :: CvSubstEnv
subst (CoercionTy {}) _ _ _
  = CvSubstEnv -> Maybe CvSubstEnv
forall a. a -> Maybe a
Just CvSubstEnv
subst 
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty :: Type
ty (GRefl r :: Role
r t :: Type
t (MCo co :: Coercion
co)) lkco :: Coercion
lkco rkco :: Coercion
rkco
  =  MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ty (Role -> Type -> MCoercion -> Coercion
GRefl Role
r Type
t MCoercion
MRefl) Coercion
lkco (Coercion
rkco Coercion -> Coercion -> Coercion
`mkTransCo` Coercion -> Coercion
mkSymCo Coercion
co)
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty :: Type
ty co1 :: Coercion
co1 lkco :: Coercion
lkco rkco :: Coercion
rkco
  | Just (CastTy t :: Type
t co :: Coercion
co, r :: Role
r) <- Coercion -> Maybe (Type, Role)
isReflCo_maybe Coercion
co1
  
  
  
  
  
  = let kco' :: Coercion
kco' = Coercion -> Coercion
mkSymCo Coercion
co
    in MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ty (Role -> Type -> Coercion
mkReflCo Role
r Type
t) (Coercion
lkco Coercion -> Coercion -> Coercion
`mkTransCo` Coercion
kco')
                                                (Coercion
rkco Coercion -> Coercion -> Coercion
`mkTransCo` Coercion
kco')
ty_co_match menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty :: Type
ty co :: Coercion
co lkco :: Coercion
lkco rkco :: Coercion
rkco
  | Just co' :: Coercion
co' <- Coercion -> Maybe Coercion
pushRefl Coercion
co = MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ty Coercion
co' Coercion
lkco Coercion
rkco
  | Bool
otherwise               = Maybe CvSubstEnv
forall a. Maybe a
Nothing
ty_co_match_tc :: MatchEnv -> LiftCoEnv
               -> TyCon -> [Type]
               -> TyCon -> [Coercion]
               -> Maybe LiftCoEnv
ty_co_match_tc :: MatchEnv
-> CvSubstEnv
-> TyCon
-> [Type]
-> TyCon
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_tc menv :: MatchEnv
menv subst :: CvSubstEnv
subst tc1 :: TyCon
tc1 tys1 :: [Type]
tys1 tc2 :: TyCon
tc2 cos2 :: [Coercion]
cos2
  = do { Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2)
       ; MatchEnv
-> CvSubstEnv
-> [Type]
-> [Coercion]
-> [Coercion]
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_args MatchEnv
menv CvSubstEnv
subst [Type]
tys1 [Coercion]
cos2 [Coercion]
lkcos [Coercion]
rkcos }
  where
    Pair lkcos :: [Coercion]
lkcos rkcos :: [Coercion]
rkcos
      = (Coercion -> Pair Coercion) -> [Coercion] -> Pair [Coercion]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Type -> Coercion) -> Pair Type -> Pair Coercion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Coercion
mkNomReflCo (Pair Type -> Pair Coercion)
-> (Coercion -> Pair Type) -> Coercion -> Pair Coercion
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coercion -> Pair Type
coercionKind) [Coercion]
cos2
ty_co_match_app :: MatchEnv -> LiftCoEnv
                -> Type -> [Type] -> Coercion -> [Coercion]
                -> Maybe LiftCoEnv
ty_co_match_app :: MatchEnv
-> CvSubstEnv
-> Type
-> [Type]
-> Coercion
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_app menv :: MatchEnv
menv subst :: CvSubstEnv
subst ty1 :: Type
ty1 ty1args :: [Type]
ty1args co2 :: Coercion
co2 co2args :: [Coercion]
co2args
  | Just (ty1' :: Type
ty1', ty1a :: Type
ty1a) <- HasDebugCallStack => Type -> Maybe (Type, Type)
Type -> Maybe (Type, Type)
repSplitAppTy_maybe Type
ty1
  , Just (co2' :: Coercion
co2', co2a :: Coercion
co2a) <- Coercion -> Maybe (Coercion, Coercion)
splitAppCo_maybe Coercion
co2
  = MatchEnv
-> CvSubstEnv
-> Type
-> [Type]
-> Coercion
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_app MatchEnv
menv CvSubstEnv
subst Type
ty1' (Type
ty1a Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type]
ty1args) Coercion
co2' (Coercion
co2a Coercion -> [Coercion] -> [Coercion]
forall a. a -> [a] -> [a]
: [Coercion]
co2args)
  | Bool
otherwise
  = do { CvSubstEnv
subst1 <- MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ki1 Coercion
ki2 Coercion
ki_ki_co Coercion
ki_ki_co
       ; let Pair lkco :: Coercion
lkco rkco :: Coercion
rkco = Type -> Coercion
mkNomReflCo (Type -> Coercion) -> Pair Type -> Pair Coercion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Coercion -> Pair Type
coercionKind Coercion
ki2
       ; CvSubstEnv
subst2 <- MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst1 Type
ty1 Coercion
co2 Coercion
lkco Coercion
rkco
       ; let Pair lkcos :: [Coercion]
lkcos rkcos :: [Coercion]
rkcos = (Coercion -> Pair Coercion) -> [Coercion] -> Pair [Coercion]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Type -> Coercion) -> Pair Type -> Pair Coercion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Coercion
mkNomReflCo (Pair Type -> Pair Coercion)
-> (Coercion -> Pair Type) -> Coercion -> Pair Coercion
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coercion -> Pair Type
coercionKind) [Coercion]
co2args
       ; MatchEnv
-> CvSubstEnv
-> [Type]
-> [Coercion]
-> [Coercion]
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_args MatchEnv
menv CvSubstEnv
subst2 [Type]
ty1args [Coercion]
co2args [Coercion]
lkcos [Coercion]
rkcos }
  where
    ki1 :: Type
ki1 = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
ty1
    ki2 :: Coercion
ki2 = Coercion -> Coercion
promoteCoercion Coercion
co2
    ki_ki_co :: Coercion
ki_ki_co = Type -> Coercion
mkNomReflCo Type
liftedTypeKind
ty_co_match_args :: MatchEnv -> LiftCoEnv -> [Type]
                 -> [Coercion] -> [Coercion] -> [Coercion]
                 -> Maybe LiftCoEnv
ty_co_match_args :: MatchEnv
-> CvSubstEnv
-> [Type]
-> [Coercion]
-> [Coercion]
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_args _    subst :: CvSubstEnv
subst []       []         _ _ = CvSubstEnv -> Maybe CvSubstEnv
forall a. a -> Maybe a
Just CvSubstEnv
subst
ty_co_match_args menv :: MatchEnv
menv subst :: CvSubstEnv
subst (ty :: Type
ty:tys :: [Type]
tys) (arg :: Coercion
arg:args :: [Coercion]
args) (lkco :: Coercion
lkco:lkcos :: [Coercion]
lkcos) (rkco :: Coercion
rkco:rkcos :: [Coercion]
rkcos)
  = do { CvSubstEnv
subst' <- MatchEnv
-> CvSubstEnv
-> Type
-> Coercion
-> Coercion
-> Coercion
-> Maybe CvSubstEnv
ty_co_match MatchEnv
menv CvSubstEnv
subst Type
ty Coercion
arg Coercion
lkco Coercion
rkco
       ; MatchEnv
-> CvSubstEnv
-> [Type]
-> [Coercion]
-> [Coercion]
-> [Coercion]
-> Maybe CvSubstEnv
ty_co_match_args MatchEnv
menv CvSubstEnv
subst' [Type]
tys [Coercion]
args [Coercion]
lkcos [Coercion]
rkcos }
ty_co_match_args _    _     _        _          _ _ = Maybe CvSubstEnv
forall a. Maybe a
Nothing
pushRefl :: Coercion -> Maybe Coercion
pushRefl :: Coercion -> Maybe Coercion
pushRefl co :: Coercion
co =
  case (Coercion -> Maybe (Type, Role)
isReflCo_maybe Coercion
co) of
    Just (AppTy ty1 :: Type
ty1 ty2 :: Type
ty2, Nominal)
      -> Coercion -> Maybe Coercion
forall a. a -> Maybe a
Just (Coercion -> Coercion -> Coercion
AppCo (Role -> Type -> Coercion
mkReflCo Role
Nominal Type
ty1) (Type -> Coercion
mkNomReflCo Type
ty2))
    Just (FunTy ty1 :: Type
ty1 ty2 :: Type
ty2, r :: Role
r)
      | Just rep1 :: Type
rep1 <- HasDebugCallStack => Type -> Maybe Type
Type -> Maybe Type
getRuntimeRep_maybe Type
ty1
      , Just rep2 :: Type
rep2 <- HasDebugCallStack => Type -> Maybe Type
Type -> Maybe Type
getRuntimeRep_maybe Type
ty2
      ->  Coercion -> Maybe Coercion
forall a. a -> Maybe a
Just (Role -> TyCon -> [Coercion] -> Coercion
TyConAppCo Role
r TyCon
funTyCon [ Role -> Type -> Coercion
mkReflCo Role
r Type
rep1, Role -> Type -> Coercion
mkReflCo Role
r Type
rep2
                                       , Role -> Type -> Coercion
mkReflCo Role
r Type
ty1,  Role -> Type -> Coercion
mkReflCo Role
r Type
ty2 ])
    Just (TyConApp tc :: TyCon
tc tys :: [Type]
tys, r :: Role
r)
      -> Coercion -> Maybe Coercion
forall a. a -> Maybe a
Just (Role -> TyCon -> [Coercion] -> Coercion
TyConAppCo Role
r TyCon
tc ((Role -> Type -> Coercion) -> [Role] -> [Type] -> [Coercion]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Role -> Type -> Coercion
mkReflCo (Role -> TyCon -> [Role]
tyConRolesX Role
r TyCon
tc) [Type]
tys))
    Just (ForAllTy (Bndr tv :: TyVar
tv _) ty :: Type
ty, r :: Role
r)
      -> Coercion -> Maybe Coercion
forall a. a -> Maybe a
Just (TyVar -> Coercion -> Coercion -> Coercion
ForAllCo TyVar
tv (Type -> Coercion
mkNomReflCo (TyVar -> Type
varType TyVar
tv)) (Role -> Type -> Coercion
mkReflCo Role
r Type
ty))
    
    _ -> Maybe Coercion
forall a. Maybe a
Nothing