{-# LANGUAGE CPP, MultiWayIf, TupleSections, ScopedTypeVariables #-}
module TcUnify (
tcWrapResult, tcWrapResultO, tcSkolemise, tcSkolemiseET,
tcSubTypeHR, tcSubTypeO, tcSubType_NC, tcSubTypeDS,
tcSubTypeDS_NC_O, tcSubTypeET,
checkConstraints, checkTvConstraints,
buildImplicationFor, emitResidualTvConstraint,
unifyType, unifyKind,
uType, promoteTcType,
swapOverTyVars, canSolveByUnification,
tcInferInst, tcInferNoInst,
matchExpectedListTy,
matchExpectedTyConApp,
matchExpectedAppTy,
matchExpectedFunTys,
matchActualFunTys, matchActualFunTysPart,
matchExpectedFunKind,
metaTyVarUpdateOK, occCheckForErrors, OccCheckResult(..)
) where
#include "HsVersions.h"
import GhcPrelude
import HsSyn
import TyCoRep
import TcMType
import TcRnMonad
import TcType
import Type
import Coercion
import TcEvidence
import Name( isSystemName )
import Inst
import TyCon
import TysWiredIn
import TysPrim( tYPE )
import Var
import VarSet
import VarEnv
import ErrUtils
import DynFlags
import BasicTypes
import Bag
import Util
import qualified GHC.LanguageExtensions as LangExt
import Outputable
import Control.Monad
import Control.Arrow ( second )
matchExpectedFunTys :: forall a.
SDoc
-> Arity
-> ExpRhoType
-> ([ExpSigmaType] -> ExpRhoType -> TcM a)
-> TcM (a, HsWrapper)
matchExpectedFunTys :: SDoc
-> Arity
-> ExpRhoType
-> ([ExpRhoType] -> ExpRhoType -> TcM a)
-> TcM (a, HsWrapper)
matchExpectedFunTys herald :: SDoc
herald arity :: Arity
arity orig_ty :: ExpRhoType
orig_ty thing_inside :: [ExpRhoType] -> ExpRhoType -> TcM a
thing_inside
= case ExpRhoType
orig_ty of
Check ty :: TcType
ty -> [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go [] Arity
arity TcType
ty
_ -> [ExpRhoType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper)
defer [] Arity
arity ExpRhoType
orig_ty
where
go :: [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go acc_arg_tys :: [ExpRhoType]
acc_arg_tys 0 ty :: TcType
ty
= do { a
result <- [ExpRhoType] -> ExpRhoType -> TcM a
thing_inside ([ExpRhoType] -> [ExpRhoType]
forall a. [a] -> [a]
reverse [ExpRhoType]
acc_arg_tys) (TcType -> ExpRhoType
mkCheckExpType TcType
ty)
; (a, HsWrapper) -> TcM (a, HsWrapper)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
result, HsWrapper
idHsWrapper) }
go acc_arg_tys :: [ExpRhoType]
acc_arg_tys n :: Arity
n ty :: TcType
ty
| Just ty' :: TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty = [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go [ExpRhoType]
acc_arg_tys Arity
n TcType
ty'
go acc_arg_tys :: [ExpRhoType]
acc_arg_tys n :: Arity
n (FunTy arg_ty :: TcType
arg_ty res_ty :: TcType
res_ty)
= ASSERT( not (isPredTy arg_ty) )
do { (result :: a
result, wrap_res :: HsWrapper
wrap_res) <- [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go (TcType -> ExpRhoType
mkCheckExpType TcType
arg_ty ExpRhoType -> [ExpRhoType] -> [ExpRhoType]
forall a. a -> [a] -> [a]
: [ExpRhoType]
acc_arg_tys)
(Arity
nArity -> Arity -> Arity
forall a. Num a => a -> a -> a
-1) TcType
res_ty
; (a, HsWrapper) -> TcM (a, HsWrapper)
forall (m :: * -> *) a. Monad m => a -> m a
return ( a
result
, HsWrapper -> HsWrapper -> TcType -> TcType -> SDoc -> HsWrapper
mkWpFun HsWrapper
idHsWrapper HsWrapper
wrap_res TcType
arg_ty TcType
res_ty SDoc
doc ) }
where
doc :: SDoc
doc = String -> SDoc
text "When inferring the argument type of a function with type" SDoc -> SDoc -> SDoc
<+>
SDoc -> SDoc
quotes (ExpRhoType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ExpRhoType
orig_ty)
go acc_arg_tys :: [ExpRhoType]
acc_arg_tys n :: Arity
n ty :: TcType
ty@(TyVarTy tv :: Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect ty' :: TcType
ty' -> [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go [ExpRhoType]
acc_arg_tys Arity
n TcType
ty'
Flexi -> [ExpRhoType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper)
defer [ExpRhoType]
acc_arg_tys Arity
n (TcType -> ExpRhoType
mkCheckExpType TcType
ty) }
go acc_arg_tys :: [ExpRhoType]
acc_arg_tys n :: Arity
n ty :: TcType
ty = (TidyEnv -> TcM (TidyEnv, SDoc))
-> TcM (a, HsWrapper) -> TcM (a, HsWrapper)
forall a. (TidyEnv -> TcM (TidyEnv, SDoc)) -> TcM a -> TcM a
addErrCtxtM TidyEnv -> TcM (TidyEnv, SDoc)
mk_ctxt (TcM (a, HsWrapper) -> TcM (a, HsWrapper))
-> TcM (a, HsWrapper) -> TcM (a, HsWrapper)
forall a b. (a -> b) -> a -> b
$
[ExpRhoType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper)
defer [ExpRhoType]
acc_arg_tys Arity
n (TcType -> ExpRhoType
mkCheckExpType TcType
ty)
defer :: [ExpSigmaType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper)
defer :: [ExpRhoType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper)
defer acc_arg_tys :: [ExpRhoType]
acc_arg_tys n :: Arity
n fun_ty :: ExpRhoType
fun_ty
= do { [ExpRhoType]
more_arg_tys <- Arity
-> IOEnv (Env TcGblEnv TcLclEnv) ExpRhoType
-> IOEnv (Env TcGblEnv TcLclEnv) [ExpRhoType]
forall (m :: * -> *) a. Applicative m => Arity -> m a -> m [a]
replicateM Arity
n IOEnv (Env TcGblEnv TcLclEnv) ExpRhoType
newInferExpTypeNoInst
; ExpRhoType
res_ty <- IOEnv (Env TcGblEnv TcLclEnv) ExpRhoType
newInferExpTypeInst
; a
result <- [ExpRhoType] -> ExpRhoType -> TcM a
thing_inside ([ExpRhoType] -> [ExpRhoType]
forall a. [a] -> [a]
reverse [ExpRhoType]
acc_arg_tys [ExpRhoType] -> [ExpRhoType] -> [ExpRhoType]
forall a. [a] -> [a] -> [a]
++ [ExpRhoType]
more_arg_tys) ExpRhoType
res_ty
; [TcType]
more_arg_tys <- (ExpRhoType -> IOEnv (Env TcGblEnv TcLclEnv) TcType)
-> [ExpRhoType] -> IOEnv (Env TcGblEnv TcLclEnv) [TcType]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ExpRhoType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
readExpType [ExpRhoType]
more_arg_tys
; TcType
res_ty <- ExpRhoType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
readExpType ExpRhoType
res_ty
; let unif_fun_ty :: TcType
unif_fun_ty = [TcType] -> TcType -> TcType
mkFunTys [TcType]
more_arg_tys TcType
res_ty
; HsWrapper
wrap <- CtOrigin -> UserTypeCtxt -> TcType -> ExpRhoType -> TcM HsWrapper
tcSubTypeDS CtOrigin
AppOrigin UserTypeCtxt
GenSigCtxt TcType
unif_fun_ty ExpRhoType
fun_ty
; (a, HsWrapper) -> TcM (a, HsWrapper)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
result, HsWrapper
wrap) }
mk_ctxt :: TidyEnv -> TcM (TidyEnv, MsgDoc)
mk_ctxt :: TidyEnv -> TcM (TidyEnv, SDoc)
mk_ctxt env :: TidyEnv
env = do { (env' :: TidyEnv
env', ty :: TcType
ty) <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
env TcType
orig_tc_ty
; let (args :: [TcType]
args, _) = TcType -> ([TcType], TcType)
tcSplitFunTys TcType
ty
n_actual :: Arity
n_actual = [TcType] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [TcType]
args
(env'' :: TidyEnv
env'', orig_ty' :: TcType
orig_ty') = TidyEnv -> TcType -> (TidyEnv, TcType)
tidyOpenType TidyEnv
env' TcType
orig_tc_ty
; (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return ( TidyEnv
env''
, TcType -> TcType -> Arity -> Arity -> SDoc -> SDoc
mk_fun_tys_msg TcType
orig_ty' TcType
ty Arity
n_actual Arity
arity SDoc
herald) }
where
orig_tc_ty :: TcType
orig_tc_ty = String -> ExpRhoType -> TcType
checkingExpType "matchExpectedFunTys" ExpRhoType
orig_ty
matchActualFunTys :: SDoc
-> CtOrigin
-> Maybe (HsExpr GhcRn)
-> Arity
-> TcSigmaType
-> TcM (HsWrapper, [TcSigmaType], TcSigmaType)
matchActualFunTys :: SDoc
-> CtOrigin
-> Maybe (HsExpr GhcRn)
-> Arity
-> TcType
-> TcM (HsWrapper, [TcType], TcType)
matchActualFunTys herald :: SDoc
herald ct_orig :: CtOrigin
ct_orig mb_thing :: Maybe (HsExpr GhcRn)
mb_thing arity :: Arity
arity ty :: TcType
ty
= SDoc
-> CtOrigin
-> Maybe (HsExpr GhcRn)
-> Arity
-> TcType
-> [TcType]
-> Arity
-> TcM (HsWrapper, [TcType], TcType)
matchActualFunTysPart SDoc
herald CtOrigin
ct_orig Maybe (HsExpr GhcRn)
mb_thing Arity
arity TcType
ty [] Arity
arity
matchActualFunTysPart :: SDoc
-> CtOrigin
-> Maybe (HsExpr GhcRn)
-> Arity
-> TcSigmaType
-> [TcSigmaType]
-> Arity
-> TcM (HsWrapper, [TcSigmaType], TcSigmaType)
matchActualFunTysPart :: SDoc
-> CtOrigin
-> Maybe (HsExpr GhcRn)
-> Arity
-> TcType
-> [TcType]
-> Arity
-> TcM (HsWrapper, [TcType], TcType)
matchActualFunTysPart herald :: SDoc
herald ct_orig :: CtOrigin
ct_orig mb_thing :: Maybe (HsExpr GhcRn)
mb_thing arity :: Arity
arity orig_ty :: TcType
orig_ty
orig_old_args :: [TcType]
orig_old_args full_arity :: Arity
full_arity
= Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go Arity
arity [TcType]
orig_old_args TcType
orig_ty
where
go :: Arity
-> [TcSigmaType]
-> TcSigmaType
-> TcM (HsWrapper, [TcSigmaType], TcSigmaType)
go :: Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go 0 _ ty :: TcType
ty = (HsWrapper, [TcType], TcType) -> TcM (HsWrapper, [TcType], TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper
idHsWrapper, [], TcType
ty)
go n :: Arity
n acc_args :: [TcType]
acc_args ty :: TcType
ty
| Bool -> Bool
not ([Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
tvs Bool -> Bool -> Bool
&& [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcType]
theta)
= do { (wrap1 :: HsWrapper
wrap1, rho :: TcType
rho) <- CtOrigin -> TcType -> TcM (HsWrapper, TcType)
topInstantiate CtOrigin
ct_orig TcType
ty
; (wrap2 :: HsWrapper
wrap2, arg_tys :: [TcType]
arg_tys, res_ty :: TcType
res_ty) <- Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go Arity
n [TcType]
acc_args TcType
rho
; (HsWrapper, [TcType], TcType) -> TcM (HsWrapper, [TcType], TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper
wrap2 HsWrapper -> HsWrapper -> HsWrapper
<.> HsWrapper
wrap1, [TcType]
arg_tys, TcType
res_ty) }
where
(tvs :: [Var]
tvs, theta :: [TcType]
theta, _) = TcType -> ([Var], [TcType], TcType)
tcSplitSigmaTy TcType
ty
go n :: Arity
n acc_args :: [TcType]
acc_args ty :: TcType
ty
| Just ty' :: TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty = Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go Arity
n [TcType]
acc_args TcType
ty'
go n :: Arity
n acc_args :: [TcType]
acc_args (FunTy arg_ty :: TcType
arg_ty res_ty :: TcType
res_ty)
= ASSERT( not (isPredTy arg_ty) )
do { (wrap_res :: HsWrapper
wrap_res, tys :: [TcType]
tys, ty_r :: TcType
ty_r) <- Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go (Arity
nArity -> Arity -> Arity
forall a. Num a => a -> a -> a
-1) (TcType
arg_ty TcType -> [TcType] -> [TcType]
forall a. a -> [a] -> [a]
: [TcType]
acc_args) TcType
res_ty
; (HsWrapper, [TcType], TcType) -> TcM (HsWrapper, [TcType], TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return ( HsWrapper -> HsWrapper -> TcType -> TcType -> SDoc -> HsWrapper
mkWpFun HsWrapper
idHsWrapper HsWrapper
wrap_res TcType
arg_ty TcType
ty_r SDoc
doc
, TcType
arg_ty TcType -> [TcType] -> [TcType]
forall a. a -> [a] -> [a]
: [TcType]
tys, TcType
ty_r ) }
where
doc :: SDoc
doc = String -> SDoc
text "When inferring the argument type of a function with type" SDoc -> SDoc -> SDoc
<+>
SDoc -> SDoc
quotes (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
orig_ty)
go n :: Arity
n acc_args :: [TcType]
acc_args ty :: TcType
ty@(TyVarTy tv :: Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect ty' :: TcType
ty' -> Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go Arity
n [TcType]
acc_args TcType
ty'
Flexi -> Arity -> TcType -> TcM (HsWrapper, [TcType], TcType)
defer Arity
n TcType
ty }
go n :: Arity
n acc_args :: [TcType]
acc_args ty :: TcType
ty = (TidyEnv -> TcM (TidyEnv, SDoc))
-> TcM (HsWrapper, [TcType], TcType)
-> TcM (HsWrapper, [TcType], TcType)
forall a. (TidyEnv -> TcM (TidyEnv, SDoc)) -> TcM a -> TcM a
addErrCtxtM ([TcType] -> TcType -> TidyEnv -> TcM (TidyEnv, SDoc)
mk_ctxt ([TcType] -> [TcType]
forall a. [a] -> [a]
reverse [TcType]
acc_args) TcType
ty) (TcM (HsWrapper, [TcType], TcType)
-> TcM (HsWrapper, [TcType], TcType))
-> TcM (HsWrapper, [TcType], TcType)
-> TcM (HsWrapper, [TcType], TcType)
forall a b. (a -> b) -> a -> b
$
Arity -> TcType -> TcM (HsWrapper, [TcType], TcType)
defer Arity
n TcType
ty
defer :: Arity -> TcType -> TcM (HsWrapper, [TcType], TcType)
defer n :: Arity
n fun_ty :: TcType
fun_ty
= do { [TcType]
arg_tys <- Arity
-> IOEnv (Env TcGblEnv TcLclEnv) TcType
-> IOEnv (Env TcGblEnv TcLclEnv) [TcType]
forall (m :: * -> *) a. Applicative m => Arity -> m a -> m [a]
replicateM Arity
n IOEnv (Env TcGblEnv TcLclEnv) TcType
newOpenFlexiTyVarTy
; TcType
res_ty <- IOEnv (Env TcGblEnv TcLclEnv) TcType
newOpenFlexiTyVarTy
; let unif_fun_ty :: TcType
unif_fun_ty = [TcType] -> TcType -> TcType
mkFunTys [TcType]
arg_tys TcType
res_ty
; TcCoercionN
co <- Maybe (HsExpr GhcRn) -> TcType -> TcType -> TcM TcCoercionN
unifyType Maybe (HsExpr GhcRn)
mb_thing TcType
fun_ty TcType
unif_fun_ty
; (HsWrapper, [TcType], TcType) -> TcM (HsWrapper, [TcType], TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> HsWrapper
mkWpCastN TcCoercionN
co, [TcType]
arg_tys, TcType
res_ty) }
mk_ctxt :: [TcSigmaType] -> TcSigmaType -> TidyEnv -> TcM (TidyEnv, MsgDoc)
mk_ctxt :: [TcType] -> TcType -> TidyEnv -> TcM (TidyEnv, SDoc)
mk_ctxt arg_tys :: [TcType]
arg_tys res_ty :: TcType
res_ty env :: TidyEnv
env
= do { let ty :: TcType
ty = [TcType] -> TcType -> TcType
mkFunTys [TcType]
arg_tys TcType
res_ty
; (env1 :: TidyEnv
env1, zonked :: TcType
zonked) <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
env TcType
ty
; let (zonked_args :: [TcType]
zonked_args, _) = TcType -> ([TcType], TcType)
tcSplitFunTys TcType
zonked
n_actual :: Arity
n_actual = [TcType] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [TcType]
zonked_args
(env2 :: TidyEnv
env2, unzonked :: TcType
unzonked) = TidyEnv -> TcType -> (TidyEnv, TcType)
tidyOpenType TidyEnv
env1 TcType
ty
; (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return ( TidyEnv
env2
, TcType -> TcType -> Arity -> Arity -> SDoc -> SDoc
mk_fun_tys_msg TcType
unzonked TcType
zonked Arity
n_actual Arity
full_arity SDoc
herald) }
mk_fun_tys_msg :: TcType
-> TcType
-> Arity
-> Arity
-> SDoc
-> SDoc
mk_fun_tys_msg :: TcType -> TcType -> Arity -> Arity -> SDoc -> SDoc
mk_fun_tys_msg full_ty :: TcType
full_ty ty :: TcType
ty n_args :: Arity
n_args full_arity :: Arity
full_arity herald :: SDoc
herald
= SDoc
herald SDoc -> SDoc -> SDoc
<+> Arity -> SDoc -> SDoc
speakNOf Arity
full_arity (String -> SDoc
text "argument") SDoc -> SDoc -> SDoc
<> SDoc
comma SDoc -> SDoc -> SDoc
$$
if Arity
n_args Arity -> Arity -> Bool
forall a. Eq a => a -> a -> Bool
== Arity
full_arity
then String -> SDoc
text "its type is" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TcType -> SDoc
pprType TcType
full_ty) SDoc -> SDoc -> SDoc
<>
SDoc
comma SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "it is specialized to" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TcType -> SDoc
pprType TcType
ty)
else [SDoc] -> SDoc
sep [String -> SDoc
text "but its type" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TcType -> SDoc
pprType TcType
ty),
if Arity
n_args Arity -> Arity -> Bool
forall a. Eq a => a -> a -> Bool
== 0 then String -> SDoc
text "has none"
else String -> SDoc
text "has only" SDoc -> SDoc -> SDoc
<+> Arity -> SDoc
speakN Arity
n_args]
matchExpectedListTy :: TcRhoType -> TcM (TcCoercionN, TcRhoType)
matchExpectedListTy :: TcType -> TcM (TcCoercionN, TcType)
matchExpectedListTy exp_ty :: TcType
exp_ty
= do { (co :: TcCoercionN
co, [elt_ty :: TcType
elt_ty]) <- TyCon -> TcType -> TcM (TcCoercionN, [TcType])
matchExpectedTyConApp TyCon
listTyCon TcType
exp_ty
; (TcCoercionN, TcType) -> TcM (TcCoercionN, TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN
co, TcType
elt_ty) }
matchExpectedTyConApp :: TyCon
-> TcRhoType
-> TcM (TcCoercionN,
[TcSigmaType])
matchExpectedTyConApp :: TyCon -> TcType -> TcM (TcCoercionN, [TcType])
matchExpectedTyConApp tc :: TyCon
tc orig_ty :: TcType
orig_ty
= ASSERT(tc /= funTyCon) go orig_ty
where
go :: TcType -> TcM (TcCoercionN, [TcType])
go ty :: TcType
ty
| Just ty' :: TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty
= TcType -> TcM (TcCoercionN, [TcType])
go TcType
ty'
go ty :: TcType
ty@(TyConApp tycon :: TyCon
tycon args :: [TcType]
args)
| TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tycon
= (TcCoercionN, [TcType]) -> TcM (TcCoercionN, [TcType])
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> TcCoercionN
mkTcNomReflCo TcType
ty, [TcType]
args)
go (TyVarTy tv :: Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect ty :: TcType
ty -> TcType -> TcM (TcCoercionN, [TcType])
go TcType
ty
Flexi -> TcM (TcCoercionN, [TcType])
defer }
go _ = TcM (TcCoercionN, [TcType])
defer
defer :: TcM (TcCoercionN, [TcType])
defer
= do { (_, arg_tvs :: [Var]
arg_tvs) <- [Var] -> TcM (TCvSubst, [Var])
newMetaTyVars (TyCon -> [Var]
tyConTyVars TyCon
tc)
; String -> SDoc -> TcRn ()
traceTc "matchExpectedTyConApp" (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
$$ [Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> [Var]
tyConTyVars TyCon
tc) SDoc -> SDoc -> SDoc
$$ [Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Var]
arg_tvs)
; let args :: [TcType]
args = [Var] -> [TcType]
mkTyVarTys [Var]
arg_tvs
tc_template :: TcType
tc_template = TyCon -> [TcType] -> TcType
mkTyConApp TyCon
tc [TcType]
args
; TcCoercionN
co <- Maybe (HsExpr GhcRn) -> TcType -> TcType -> TcM TcCoercionN
unifyType Maybe (HsExpr GhcRn)
forall a. Maybe a
Nothing TcType
tc_template TcType
orig_ty
; (TcCoercionN, [TcType]) -> TcM (TcCoercionN, [TcType])
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN
co, [TcType]
args) }
matchExpectedAppTy :: TcRhoType
-> TcM (TcCoercion,
(TcSigmaType, TcSigmaType))
matchExpectedAppTy :: TcType -> TcM (TcCoercionN, (TcType, TcType))
matchExpectedAppTy orig_ty :: TcType
orig_ty
= TcType -> TcM (TcCoercionN, (TcType, TcType))
go TcType
orig_ty
where
go :: TcType -> TcM (TcCoercionN, (TcType, TcType))
go ty :: TcType
ty
| Just ty' :: TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty = TcType -> TcM (TcCoercionN, (TcType, TcType))
go TcType
ty'
| Just (fun_ty :: TcType
fun_ty, arg_ty :: TcType
arg_ty) <- TcType -> Maybe (TcType, TcType)
tcSplitAppTy_maybe TcType
ty
= (TcCoercionN, (TcType, TcType))
-> TcM (TcCoercionN, (TcType, TcType))
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> TcCoercionN
mkTcNomReflCo TcType
orig_ty, (TcType
fun_ty, TcType
arg_ty))
go (TyVarTy tv :: Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect ty :: TcType
ty -> TcType -> TcM (TcCoercionN, (TcType, TcType))
go TcType
ty
Flexi -> TcM (TcCoercionN, (TcType, TcType))
defer }
go _ = TcM (TcCoercionN, (TcType, TcType))
defer
defer :: TcM (TcCoercionN, (TcType, TcType))
defer
= do { TcType
ty1 <- TcType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
newFlexiTyVarTy TcType
kind1
; TcType
ty2 <- TcType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
newFlexiTyVarTy TcType
kind2
; TcCoercionN
co <- Maybe (HsExpr GhcRn) -> TcType -> TcType -> TcM TcCoercionN
unifyType Maybe (HsExpr GhcRn)
forall a. Maybe a
Nothing (TcType -> TcType -> TcType
mkAppTy TcType
ty1 TcType
ty2) TcType
orig_ty
; (TcCoercionN, (TcType, TcType))
-> TcM (TcCoercionN, (TcType, TcType))
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN
co, (TcType
ty1, TcType
ty2)) }
orig_kind :: TcType
orig_kind = HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
orig_ty
kind1 :: TcType
kind1 = TcType -> TcType -> TcType
mkFunTy TcType
liftedTypeKind TcType
orig_kind
kind2 :: TcType
kind2 = TcType
liftedTypeKind
tcSubTypeHR :: CtOrigin
-> Maybe (HsExpr GhcRn)
-> TcSigmaType -> ExpRhoType -> TcM HsWrapper
tcSubTypeHR :: CtOrigin
-> Maybe (HsExpr GhcRn) -> TcType -> ExpRhoType -> TcM HsWrapper
tcSubTypeHR orig :: CtOrigin
orig = CtOrigin
-> UserTypeCtxt
-> Maybe (HsExpr GhcRn)
-> TcType
-> ExpRhoType
-> TcM HsWrapper
tcSubTypeDS_NC_O CtOrigin
orig UserTypeCtxt
GenSigCtxt
tcSubTypeET :: CtOrigin -> UserTypeCtxt
-> ExpSigmaType -> TcSigmaType -> TcM HsWrapper
tcSubTypeET :: CtOrigin -> UserTypeCtxt -> ExpRhoType -> TcType -> TcM HsWrapper
tcSubTypeET orig :: CtOrigin
orig ctxt :: UserTypeCtxt
ctxt (Check ty_actual :: TcType
ty_actual) ty_expected :: TcType
ty_expected
= CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_tc_type CtOrigin
eq_orig CtOrigin
orig UserTypeCtxt
ctxt TcType
ty_actual TcType
ty_expected
where
eq_orig :: CtOrigin
eq_orig = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
ty_expected
, uo_expected :: TcType
uo_expected = TcType
ty_actual
, uo_thing :: Maybe SDoc
uo_thing = Maybe SDoc
forall a. Maybe a
Nothing
, uo_visible :: Bool
uo_visible = Bool
True }
tcSubTypeET _ _ (Infer inf_res :: InferResult
inf_res) ty_expected :: TcType
ty_expected
= ASSERT2( not (ir_inst inf_res), ppr inf_res $$ ppr ty_expected )
do { TcCoercionN
co <- TcType -> InferResult -> TcM TcCoercionN
fill_infer_result TcType
ty_expected InferResult
inf_res
; HsWrapper -> TcM HsWrapper
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> HsWrapper
mkWpCastN (TcCoercionN -> TcCoercionN
mkTcSymCo TcCoercionN
co)) }
tcSubTypeO :: CtOrigin
-> UserTypeCtxt
-> TcSigmaType
-> ExpRhoType
-> TcM HsWrapper
tcSubTypeO :: CtOrigin -> UserTypeCtxt -> TcType -> ExpRhoType -> TcM HsWrapper
tcSubTypeO orig :: CtOrigin
orig ctxt :: UserTypeCtxt
ctxt ty_actual :: TcType
ty_actual ty_expected :: ExpRhoType
ty_expected
= TcType -> ExpRhoType -> TcM HsWrapper -> TcM HsWrapper
forall a. TcType -> ExpRhoType -> TcM a -> TcM a
addSubTypeCtxt TcType
ty_actual ExpRhoType
ty_expected (TcM HsWrapper -> TcM HsWrapper) -> TcM HsWrapper -> TcM HsWrapper
forall a b. (a -> b) -> a -> b
$
do { String -> SDoc -> TcRn ()
traceTc "tcSubTypeDS_O" ([SDoc] -> SDoc
vcat [ CtOrigin -> SDoc
pprCtOrigin CtOrigin
orig
, UserTypeCtxt -> SDoc
pprUserTypeCtxt UserTypeCtxt
ctxt
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual
, ExpRhoType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ExpRhoType
ty_expected ])
; CtOrigin
-> UserTypeCtxt
-> Maybe (HsExpr GhcRn)
-> TcType
-> ExpRhoType
-> TcM HsWrapper
tcSubTypeDS_NC_O CtOrigin
orig UserTypeCtxt
ctxt Maybe (HsExpr GhcRn)
forall a. Maybe a
Nothing TcType
ty_actual ExpRhoType
ty_expected }
addSubTypeCtxt :: TcType -> ExpType -> TcM a -> TcM a
addSubTypeCtxt :: TcType -> ExpRhoType -> TcM a -> TcM a
addSubTypeCtxt ty_actual :: TcType
ty_actual ty_expected :: ExpRhoType
ty_expected thing_inside :: TcM a
thing_inside
| TcType -> Bool
isRhoTy TcType
ty_actual
, ExpRhoType -> Bool
isRhoExpTy ExpRhoType
ty_expected
= TcM a
thing_inside
| Bool
otherwise
= (TidyEnv -> TcM (TidyEnv, SDoc)) -> TcM a -> TcM a
forall a. (TidyEnv -> TcM (TidyEnv, SDoc)) -> TcM a -> TcM a
addErrCtxtM TidyEnv -> TcM (TidyEnv, SDoc)
mk_msg TcM a
thing_inside
where
mk_msg :: TidyEnv -> TcM (TidyEnv, SDoc)
mk_msg tidy_env :: TidyEnv
tidy_env
= do { (tidy_env :: TidyEnv
tidy_env, ty_actual :: TcType
ty_actual) <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
tidy_env TcType
ty_actual
; Maybe TcType
mb_ty_expected <- ExpRhoType -> TcM (Maybe TcType)
readExpType_maybe ExpRhoType
ty_expected
; (tidy_env :: TidyEnv
tidy_env, ty_expected :: ExpRhoType
ty_expected) <- case Maybe TcType
mb_ty_expected of
Just ty :: TcType
ty -> (TcType -> ExpRhoType)
-> (TidyEnv, TcType) -> (TidyEnv, ExpRhoType)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second TcType -> ExpRhoType
mkCheckExpType ((TidyEnv, TcType) -> (TidyEnv, ExpRhoType))
-> TcM (TidyEnv, TcType)
-> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, ExpRhoType)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
tidy_env TcType
ty
Nothing -> (TidyEnv, ExpRhoType)
-> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, ExpRhoType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
tidy_env, ExpRhoType
ty_expected)
; TcType
ty_expected <- ExpRhoType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
readExpType ExpRhoType
ty_expected
; (tidy_env :: TidyEnv
tidy_env, ty_expected :: TcType
ty_expected) <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
tidy_env TcType
ty_expected
; let msg :: SDoc
msg = [SDoc] -> SDoc
vcat [ SDoc -> Arity -> SDoc -> SDoc
hang (String -> SDoc
text "When checking that:")
4 (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual)
, Arity -> SDoc -> SDoc
nest 2 (SDoc -> Arity -> SDoc -> SDoc
hang (String -> SDoc
text "is more polymorphic than:")
2 (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected)) ]
; (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
tidy_env, SDoc
msg) }
tcSubType_NC :: UserTypeCtxt -> TcSigmaType -> TcSigmaType -> TcM HsWrapper
tcSubType_NC :: UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tcSubType_NC ctxt :: UserTypeCtxt
ctxt ty_actual :: TcType
ty_actual ty_expected :: TcType
ty_expected
= do { String -> SDoc -> TcRn ()
traceTc "tcSubType_NC" ([SDoc] -> SDoc
vcat [UserTypeCtxt -> SDoc
pprUserTypeCtxt UserTypeCtxt
ctxt, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected])
; CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_tc_type CtOrigin
origin CtOrigin
origin UserTypeCtxt
ctxt TcType
ty_actual TcType
ty_expected }
where
origin :: CtOrigin
origin = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
ty_actual
, uo_expected :: TcType
uo_expected = TcType
ty_expected
, uo_thing :: Maybe SDoc
uo_thing = Maybe SDoc
forall a. Maybe a
Nothing
, uo_visible :: Bool
uo_visible = Bool
True }
tcSubTypeDS :: CtOrigin -> UserTypeCtxt -> TcSigmaType -> ExpRhoType -> TcM HsWrapper
tcSubTypeDS :: CtOrigin -> UserTypeCtxt -> TcType -> ExpRhoType -> TcM HsWrapper
tcSubTypeDS orig :: CtOrigin
orig ctxt :: UserTypeCtxt
ctxt ty_actual :: TcType
ty_actual ty_expected :: ExpRhoType
ty_expected
= TcType -> ExpRhoType -> TcM HsWrapper -> TcM HsWrapper
forall a. TcType -> ExpRhoType -> TcM a -> TcM a
addSubTypeCtxt TcType
ty_actual ExpRhoType
ty_expected (TcM HsWrapper -> TcM HsWrapper) -> TcM HsWrapper -> TcM HsWrapper
forall a b. (a -> b) -> a -> b
$
do { String -> SDoc -> TcRn ()
traceTc "tcSubTypeDS_NC" ([SDoc] -> SDoc
vcat [UserTypeCtxt -> SDoc
pprUserTypeCtxt UserTypeCtxt
ctxt, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual, ExpRhoType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ExpRhoType
ty_expected])
; CtOrigin
-> UserTypeCtxt
-> Maybe (HsExpr GhcRn)
-> TcType
-> ExpRhoType
-> TcM HsWrapper
tcSubTypeDS_NC_O CtOrigin
orig UserTypeCtxt
ctxt Maybe (HsExpr GhcRn)
forall a. Maybe a
Nothing TcType
ty_actual ExpRhoType
ty_expected }
tcSubTypeDS_NC_O :: CtOrigin
-> UserTypeCtxt
-> Maybe (HsExpr GhcRn)
-> TcSigmaType -> ExpRhoType -> TcM HsWrapper
tcSubTypeDS_NC_O :: CtOrigin
-> UserTypeCtxt
-> Maybe (HsExpr GhcRn)
-> TcType
-> ExpRhoType
-> TcM HsWrapper
tcSubTypeDS_NC_O inst_orig :: CtOrigin
inst_orig ctxt :: UserTypeCtxt
ctxt m_thing :: Maybe (HsExpr GhcRn)
m_thing ty_actual :: TcType
ty_actual ty_expected :: ExpRhoType
ty_expected
= case ExpRhoType
ty_expected of
Infer inf_res :: InferResult
inf_res -> CtOrigin -> TcType -> InferResult -> TcM HsWrapper
fillInferResult CtOrigin
inst_orig TcType
ty_actual InferResult
inf_res
Check ty :: TcType
ty -> CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_type_ds CtOrigin
eq_orig CtOrigin
inst_orig UserTypeCtxt
ctxt TcType
ty_actual TcType
ty
where
eq_orig :: CtOrigin
eq_orig = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
ty_actual, uo_expected :: TcType
uo_expected = TcType
ty
, uo_thing :: Maybe SDoc
uo_thing = HsExpr GhcRn -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HsExpr GhcRn -> SDoc) -> Maybe (HsExpr GhcRn) -> Maybe SDoc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (HsExpr GhcRn)
m_thing
, uo_visible :: Bool
uo_visible = Bool
True }
tc_sub_tc_type :: CtOrigin
-> CtOrigin
-> UserTypeCtxt -> TcSigmaType -> TcSigmaType -> TcM HsWrapper
tc_sub_tc_type :: CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_tc_type eq_orig :: CtOrigin
eq_orig inst_orig :: CtOrigin
inst_orig ctxt :: UserTypeCtxt
ctxt ty_actual :: TcType
ty_actual ty_expected :: TcType
ty_expected
| TcType -> Bool
definitely_poly TcType
ty_expected
, Bool -> Bool
not (TcType -> Bool
possibly_poly TcType
ty_actual)
= do { String -> SDoc -> TcRn ()
traceTc "tc_sub_tc_type (drop to equality)" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text "ty_actual =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual
, String -> SDoc
text "ty_expected =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected ]
; TcCoercionN -> HsWrapper
mkWpCastN (TcCoercionN -> HsWrapper) -> TcM TcCoercionN -> TcM HsWrapper
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
TypeLevel CtOrigin
eq_orig TcType
ty_actual TcType
ty_expected }
| Bool
otherwise
= do { String -> SDoc -> TcRn ()
traceTc "tc_sub_tc_type (general case)" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text "ty_actual =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual
, String -> SDoc
text "ty_expected =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected ]
; (sk_wrap :: HsWrapper
sk_wrap, inner_wrap :: HsWrapper
inner_wrap) <- UserTypeCtxt
-> TcType
-> ([Var] -> TcType -> TcM HsWrapper)
-> TcM (HsWrapper, HsWrapper)
forall result.
UserTypeCtxt
-> TcType
-> ([Var] -> TcType -> TcM result)
-> TcM (HsWrapper, result)
tcSkolemise UserTypeCtxt
ctxt TcType
ty_expected (([Var] -> TcType -> TcM HsWrapper) -> TcM (HsWrapper, HsWrapper))
-> ([Var] -> TcType -> TcM HsWrapper) -> TcM (HsWrapper, HsWrapper)
forall a b. (a -> b) -> a -> b
$
\ _ sk_rho :: TcType
sk_rho ->
CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_type_ds CtOrigin
eq_orig CtOrigin
inst_orig UserTypeCtxt
ctxt
TcType
ty_actual TcType
sk_rho
; HsWrapper -> TcM HsWrapper
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper
sk_wrap HsWrapper -> HsWrapper -> HsWrapper
<.> HsWrapper
inner_wrap) }
where
possibly_poly :: TcType -> Bool
possibly_poly ty :: TcType
ty
| TcType -> Bool
isForAllTy TcType
ty = Bool
True
| Just (_, res :: TcType
res) <- TcType -> Maybe (TcType, TcType)
splitFunTy_maybe TcType
ty = TcType -> Bool
possibly_poly TcType
res
| Bool
otherwise = Bool
False
definitely_poly :: TcType -> Bool
definitely_poly ty :: TcType
ty
| (tvs :: [Var]
tvs, theta :: [TcType]
theta, tau :: TcType
tau) <- TcType -> ([Var], [TcType], TcType)
tcSplitSigmaTy TcType
ty
, (tv :: Var
tv:_) <- [Var]
tvs
, [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcType]
theta
, EqRel -> Var -> TcType -> Bool
isInsolubleOccursCheck EqRel
NomEq Var
tv TcType
tau
= Bool
True
| Bool
otherwise
= Bool
False
tc_sub_type_ds :: CtOrigin
-> CtOrigin
-> UserTypeCtxt -> TcSigmaType -> TcRhoType -> TcM HsWrapper
tc_sub_type_ds :: CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_type_ds eq_orig :: CtOrigin
eq_orig inst_orig :: CtOrigin
inst_orig ctxt :: UserTypeCtxt
ctxt ty_actual :: TcType
ty_actual ty_expected :: TcType
ty_expected
= do { String -> SDoc -> TcRn ()
traceTc "tc_sub_type_ds" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text "ty_actual =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual
, String -> SDoc
text "ty_expected =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected ]
; TcType -> TcType -> TcM HsWrapper
go TcType
ty_actual TcType
ty_expected }
where
go :: TcType -> TcType -> TcM HsWrapper
go ty_a :: TcType
ty_a ty_e :: TcType
ty_e | Just ty_a' :: TcType
ty_a' <- TcType -> Maybe TcType
tcView TcType
ty_a = TcType -> TcType -> TcM HsWrapper
go TcType
ty_a' TcType
ty_e
| Just ty_e' :: TcType
ty_e' <- TcType -> Maybe TcType
tcView TcType
ty_e = TcType -> TcType -> TcM HsWrapper
go TcType
ty_a TcType
ty_e'
go (TyVarTy tv_a :: Var
tv_a) ty_e :: TcType
ty_e
= do { LookupTyVarResult
lookup_res <- Var -> TcM LookupTyVarResult
lookupTcTyVar Var
tv_a
; case LookupTyVarResult
lookup_res of
Filled ty_a' :: TcType
ty_a' ->
do { String -> SDoc -> TcRn ()
traceTc "tcSubTypeDS_NC_O following filled act meta-tyvar:"
(Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv_a SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "-->" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_a')
; CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_type_ds CtOrigin
eq_orig CtOrigin
inst_orig UserTypeCtxt
ctxt TcType
ty_a' TcType
ty_e }
Unfilled _ -> TcM HsWrapper
unify }
go (FunTy act_arg :: TcType
act_arg act_res :: TcType
act_res) (FunTy exp_arg :: TcType
exp_arg exp_res :: TcType
exp_res)
| Bool -> Bool
not (TcType -> Bool
isPredTy TcType
act_arg)
, Bool -> Bool
not (TcType -> Bool
isPredTy TcType
exp_arg)
=
do { HsWrapper
res_wrap <- CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_type_ds CtOrigin
eq_orig CtOrigin
inst_orig UserTypeCtxt
ctxt TcType
act_res TcType
exp_res
; HsWrapper
arg_wrap <- CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_tc_type CtOrigin
eq_orig CtOrigin
given_orig UserTypeCtxt
GenSigCtxt TcType
exp_arg TcType
act_arg
; HsWrapper -> TcM HsWrapper
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper -> HsWrapper -> TcType -> TcType -> SDoc -> HsWrapper
mkWpFun HsWrapper
arg_wrap HsWrapper
res_wrap TcType
exp_arg TcType
exp_res SDoc
doc) }
where
given_orig :: CtOrigin
given_orig = SkolemInfo -> CtOrigin
GivenOrigin (UserTypeCtxt -> TcType -> [(Name, Var)] -> SkolemInfo
SigSkol UserTypeCtxt
GenSigCtxt TcType
exp_arg [])
doc :: SDoc
doc = String -> SDoc
text "When checking that" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual) SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "is more polymorphic than" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected)
go ty_a :: TcType
ty_a ty_e :: TcType
ty_e
| let (tvs :: [Var]
tvs, theta :: [TcType]
theta, _) = TcType -> ([Var], [TcType], TcType)
tcSplitSigmaTy TcType
ty_a
, Bool -> Bool
not ([Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
tvs Bool -> Bool -> Bool
&& [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcType]
theta)
= do { (in_wrap :: HsWrapper
in_wrap, in_rho :: TcType
in_rho) <- CtOrigin -> TcType -> TcM (HsWrapper, TcType)
topInstantiate CtOrigin
inst_orig TcType
ty_a
; HsWrapper
body_wrap <- CtOrigin
-> CtOrigin -> UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tc_sub_type_ds
(CtOrigin
eq_orig { uo_actual :: TcType
uo_actual = TcType
in_rho
, uo_expected :: TcType
uo_expected = TcType
ty_expected })
CtOrigin
inst_orig UserTypeCtxt
ctxt TcType
in_rho TcType
ty_e
; HsWrapper -> TcM HsWrapper
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper
body_wrap HsWrapper -> HsWrapper -> HsWrapper
<.> HsWrapper
in_wrap) }
| Bool
otherwise
= TcM HsWrapper
inst_and_unify
inst_and_unify :: TcM HsWrapper
inst_and_unify = do { (wrap :: HsWrapper
wrap, rho_a :: TcType
rho_a) <- CtOrigin -> TcType -> TcM (HsWrapper, TcType)
deeplyInstantiate CtOrigin
inst_orig TcType
ty_actual
; let eq_orig' :: CtOrigin
eq_orig' = case CtOrigin
eq_orig of
TypeEqOrigin { uo_actual :: CtOrigin -> TcType
uo_actual = TcType
orig_ty_actual }
| TcType
orig_ty_actual HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
ty_actual
, Bool -> Bool
not (HsWrapper -> Bool
isIdHsWrapper HsWrapper
wrap)
-> CtOrigin
eq_orig { uo_actual :: TcType
uo_actual = TcType
rho_a }
_ -> CtOrigin
eq_orig
; TcCoercionN
cow <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
TypeLevel CtOrigin
eq_orig' TcType
rho_a TcType
ty_expected
; HsWrapper -> TcM HsWrapper
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> HsWrapper
mkWpCastN TcCoercionN
cow HsWrapper -> HsWrapper -> HsWrapper
<.> HsWrapper
wrap) }
unify :: TcM HsWrapper
unify = TcCoercionN -> HsWrapper
mkWpCastN (TcCoercionN -> HsWrapper) -> TcM TcCoercionN -> TcM HsWrapper
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
TypeLevel CtOrigin
eq_orig TcType
ty_actual TcType
ty_expected
tcWrapResult :: HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType
-> TcM (HsExpr GhcTcId)
tcWrapResult :: HsExpr GhcRn
-> HsExpr GhcTcId -> TcType -> ExpRhoType -> TcM (HsExpr GhcTcId)
tcWrapResult rn_expr :: HsExpr GhcRn
rn_expr = CtOrigin
-> HsExpr GhcRn
-> HsExpr GhcTcId
-> TcType
-> ExpRhoType
-> TcM (HsExpr GhcTcId)
tcWrapResultO (HsExpr GhcRn -> CtOrigin
exprCtOrigin HsExpr GhcRn
rn_expr) HsExpr GhcRn
rn_expr
tcWrapResultO :: CtOrigin -> HsExpr GhcRn -> HsExpr GhcTcId -> TcSigmaType -> ExpRhoType
-> TcM (HsExpr GhcTcId)
tcWrapResultO :: CtOrigin
-> HsExpr GhcRn
-> HsExpr GhcTcId
-> TcType
-> ExpRhoType
-> TcM (HsExpr GhcTcId)
tcWrapResultO orig :: CtOrigin
orig rn_expr :: HsExpr GhcRn
rn_expr expr :: HsExpr GhcTcId
expr actual_ty :: TcType
actual_ty res_ty :: ExpRhoType
res_ty
= do { String -> SDoc -> TcRn ()
traceTc "tcWrapResult" ([SDoc] -> SDoc
vcat [ String -> SDoc
text "Actual: " SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
actual_ty
, String -> SDoc
text "Expected:" SDoc -> SDoc -> SDoc
<+> ExpRhoType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ExpRhoType
res_ty ])
; HsWrapper
cow <- CtOrigin
-> UserTypeCtxt
-> Maybe (HsExpr GhcRn)
-> TcType
-> ExpRhoType
-> TcM HsWrapper
tcSubTypeDS_NC_O CtOrigin
orig UserTypeCtxt
GenSigCtxt
(HsExpr GhcRn -> Maybe (HsExpr GhcRn)
forall a. a -> Maybe a
Just HsExpr GhcRn
rn_expr) TcType
actual_ty ExpRhoType
res_ty
; HsExpr GhcTcId -> TcM (HsExpr GhcTcId)
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper -> HsExpr GhcTcId -> HsExpr GhcTcId
forall (id :: Pass).
HsWrapper -> HsExpr (GhcPass id) -> HsExpr (GhcPass id)
mkHsWrap HsWrapper
cow HsExpr GhcTcId
expr) }
tcInferNoInst :: (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
tcInferNoInst :: (ExpRhoType -> TcM a) -> TcM (a, TcType)
tcInferNoInst = Bool -> (ExpRhoType -> TcM a) -> TcM (a, TcType)
forall a. Bool -> (ExpRhoType -> TcM a) -> TcM (a, TcType)
tcInfer Bool
False
tcInferInst :: (ExpRhoType -> TcM a) -> TcM (a, TcRhoType)
tcInferInst :: (ExpRhoType -> TcM a) -> TcM (a, TcType)
tcInferInst = Bool -> (ExpRhoType -> TcM a) -> TcM (a, TcType)
forall a. Bool -> (ExpRhoType -> TcM a) -> TcM (a, TcType)
tcInfer Bool
True
tcInfer :: Bool -> (ExpSigmaType -> TcM a) -> TcM (a, TcSigmaType)
tcInfer :: Bool -> (ExpRhoType -> TcM a) -> TcM (a, TcType)
tcInfer instantiate :: Bool
instantiate tc_check :: ExpRhoType -> TcM a
tc_check
= do { ExpRhoType
res_ty <- Bool -> IOEnv (Env TcGblEnv TcLclEnv) ExpRhoType
newInferExpType Bool
instantiate
; a
result <- ExpRhoType -> TcM a
tc_check ExpRhoType
res_ty
; TcType
res_ty <- ExpRhoType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
readExpType ExpRhoType
res_ty
; (a, TcType) -> TcM (a, TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
result, TcType
res_ty) }
fillInferResult :: CtOrigin -> TcType -> InferResult -> TcM HsWrapper
fillInferResult :: CtOrigin -> TcType -> InferResult -> TcM HsWrapper
fillInferResult orig :: CtOrigin
orig ty :: TcType
ty inf_res :: InferResult
inf_res@(IR { ir_inst :: InferResult -> Bool
ir_inst = Bool
instantiate_me })
| Bool
instantiate_me
= do { (wrap :: HsWrapper
wrap, rho :: TcType
rho) <- CtOrigin -> TcType -> TcM (HsWrapper, TcType)
deeplyInstantiate CtOrigin
orig TcType
ty
; TcCoercionN
co <- TcType -> InferResult -> TcM TcCoercionN
fill_infer_result TcType
rho InferResult
inf_res
; HsWrapper -> TcM HsWrapper
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> HsWrapper
mkWpCastN TcCoercionN
co HsWrapper -> HsWrapper -> HsWrapper
<.> HsWrapper
wrap) }
| Bool
otherwise
= do { TcCoercionN
co <- TcType -> InferResult -> TcM TcCoercionN
fill_infer_result TcType
ty InferResult
inf_res
; HsWrapper -> TcM HsWrapper
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> HsWrapper
mkWpCastN TcCoercionN
co) }
fill_infer_result :: TcType -> InferResult -> TcM TcCoercionN
fill_infer_result :: TcType -> InferResult -> TcM TcCoercionN
fill_infer_result orig_ty :: TcType
orig_ty (IR { ir_uniq :: InferResult -> Unique
ir_uniq = Unique
u, ir_lvl :: InferResult -> TcLevel
ir_lvl = TcLevel
res_lvl
, ir_ref :: InferResult -> IORef (Maybe TcType)
ir_ref = IORef (Maybe TcType)
ref })
= do { (ty_co :: TcCoercionN
ty_co, ty_to_fill_with :: TcType
ty_to_fill_with) <- TcLevel -> TcType -> TcM (TcCoercionN, TcType)
promoteTcType TcLevel
res_lvl TcType
orig_ty
; String -> SDoc -> TcRn ()
traceTc "Filling ExpType" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
Unique -> SDoc
forall a. Outputable a => a -> SDoc
ppr Unique
u SDoc -> SDoc -> SDoc
<+> String -> SDoc
text ":=" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_to_fill_with
; Bool -> TcRn () -> TcRn ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
debugIsOn (TcType -> TcRn ()
forall gbl lcl. TcType -> IOEnv (Env gbl lcl) ()
check_hole TcType
ty_to_fill_with)
; IORef (Maybe TcType) -> Maybe TcType -> TcRn ()
forall a gbl lcl. TcRef a -> a -> TcRnIf gbl lcl ()
writeTcRef IORef (Maybe TcType)
ref (TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
ty_to_fill_with)
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return TcCoercionN
ty_co }
where
check_hole :: TcType -> IOEnv (Env gbl lcl) ()
check_hole ty :: TcType
ty
= do { let ty_lvl :: TcLevel
ty_lvl = TcType -> TcLevel
tcTypeLevel TcType
ty
; MASSERT2( not (ty_lvl `strictlyDeeperThan` res_lvl),
ppr u $$ ppr res_lvl $$ ppr ty_lvl $$
ppr ty <+> dcolon <+> ppr (tcTypeKind ty) $$ ppr orig_ty )
; Maybe TcType
cts <- IORef (Maybe TcType) -> TcRnIf gbl lcl (Maybe TcType)
forall a gbl lcl. TcRef a -> TcRnIf gbl lcl a
readTcRef IORef (Maybe TcType)
ref
; case Maybe TcType
cts of
Just already_there :: TcType
already_there -> String -> SDoc -> IOEnv (Env gbl lcl) ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic "writeExpType"
([SDoc] -> SDoc
vcat [ Unique -> SDoc
forall a. Outputable a => a -> SDoc
ppr Unique
u
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
already_there ])
Nothing -> () -> IOEnv (Env gbl lcl) ()
forall (m :: * -> *) a. Monad m => a -> m a
return () }
promoteTcType :: TcLevel -> TcType -> TcM (TcCoercion, TcType)
promoteTcType :: TcLevel -> TcType -> TcM (TcCoercionN, TcType)
promoteTcType dest_lvl :: TcLevel
dest_lvl ty :: TcType
ty
= do { TcLevel
cur_lvl <- TcM TcLevel
getTcLevel
; if (TcLevel
cur_lvl TcLevel -> TcLevel -> Bool
`sameDepthAs` TcLevel
dest_lvl)
then TcM (TcCoercionN, TcType)
dont_promote_it
else TcM (TcCoercionN, TcType)
promote_it }
where
promote_it :: TcM (TcCoercion, TcType)
promote_it :: TcM (TcCoercionN, TcType)
promote_it
= do { TcType
rr <- TcLevel -> TcType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
newMetaTyVarTyAtLevel TcLevel
dest_lvl TcType
runtimeRepTy
; TcType
prom_ty <- TcLevel -> TcType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
newMetaTyVarTyAtLevel TcLevel
dest_lvl (TcType -> TcType
tYPE TcType
rr)
; let eq_orig :: CtOrigin
eq_orig = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
ty
, uo_expected :: TcType
uo_expected = TcType
prom_ty
, uo_thing :: Maybe SDoc
uo_thing = Maybe SDoc
forall a. Maybe a
Nothing
, uo_visible :: Bool
uo_visible = Bool
False }
; TcCoercionN
co <- CtOrigin
-> TypeOrKind -> Role -> TcType -> TcType -> TcM TcCoercionN
emitWantedEq CtOrigin
eq_orig TypeOrKind
TypeLevel Role
Nominal TcType
ty TcType
prom_ty
; (TcCoercionN, TcType) -> TcM (TcCoercionN, TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN
co, TcType
prom_ty) }
dont_promote_it :: TcM (TcCoercion, TcType)
dont_promote_it :: TcM (TcCoercionN, TcType)
dont_promote_it
= do { TcType
res_kind <- IOEnv (Env TcGblEnv TcLclEnv) TcType
newOpenTypeKind
; let ty_kind :: TcType
ty_kind = HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
ty
kind_orig :: CtOrigin
kind_orig = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
ty_kind
, uo_expected :: TcType
uo_expected = TcType
res_kind
, uo_thing :: Maybe SDoc
uo_thing = Maybe SDoc
forall a. Maybe a
Nothing
, uo_visible :: Bool
uo_visible = Bool
False }
; TcCoercionN
ki_co <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
KindLevel CtOrigin
kind_orig (HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
ty) TcType
res_kind
; let co :: TcCoercionN
co = Role -> TcType -> TcCoercionN -> TcCoercionN
mkTcGReflRightCo Role
Nominal TcType
ty TcCoercionN
ki_co
; (TcCoercionN, TcType) -> TcM (TcCoercionN, TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN
co, TcType
ty TcType -> TcCoercionN -> TcType
`mkCastTy` TcCoercionN
ki_co) }
tcSkolemise :: UserTypeCtxt -> TcSigmaType
-> ([TcTyVar] -> TcType -> TcM result)
-> TcM (HsWrapper, result)
tcSkolemise :: UserTypeCtxt
-> TcType
-> ([Var] -> TcType -> TcM result)
-> TcM (HsWrapper, result)
tcSkolemise ctxt :: UserTypeCtxt
ctxt expected_ty :: TcType
expected_ty thing_inside :: [Var] -> TcType -> TcM result
thing_inside
= do { String -> SDoc -> TcRn ()
traceTc "tcSkolemise" SDoc
Outputable.empty
; (wrap :: HsWrapper
wrap, tv_prs :: [(Name, Var)]
tv_prs, given :: [Var]
given, rho' :: TcType
rho') <- TcType -> TcM (HsWrapper, [(Name, Var)], [Var], TcType)
deeplySkolemise TcType
expected_ty
; TcLevel
lvl <- TcM TcLevel
getTcLevel
; Bool -> TcRn () -> TcRn ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
debugIsOn (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$
String -> SDoc -> TcRn ()
traceTc "tcSkolemise" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
vcat [
TcLevel -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcLevel
lvl,
String -> SDoc
text "expected_ty" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
expected_ty,
String -> SDoc
text "inst tyvars" SDoc -> SDoc -> SDoc
<+> [(Name, Var)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Name, Var)]
tv_prs,
String -> SDoc
text "given" SDoc -> SDoc -> SDoc
<+> [Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Var]
given,
String -> SDoc
text "inst type" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rho' ]
; let tvs' :: [Var]
tvs' = ((Name, Var) -> Var) -> [(Name, Var)] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (Name, Var) -> Var
forall a b. (a, b) -> b
snd [(Name, Var)]
tv_prs
skol_info :: SkolemInfo
skol_info = UserTypeCtxt -> TcType -> [(Name, Var)] -> SkolemInfo
SigSkol UserTypeCtxt
ctxt TcType
expected_ty [(Name, Var)]
tv_prs
; (ev_binds :: TcEvBinds
ev_binds, result :: result
result) <- SkolemInfo
-> [Var] -> [Var] -> TcM result -> TcM (TcEvBinds, result)
forall result.
SkolemInfo
-> [Var] -> [Var] -> TcM result -> TcM (TcEvBinds, result)
checkConstraints SkolemInfo
skol_info [Var]
tvs' [Var]
given (TcM result -> TcM (TcEvBinds, result))
-> TcM result -> TcM (TcEvBinds, result)
forall a b. (a -> b) -> a -> b
$
[Var] -> TcType -> TcM result
thing_inside [Var]
tvs' TcType
rho'
; (HsWrapper, result) -> TcM (HsWrapper, result)
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper
wrap HsWrapper -> HsWrapper -> HsWrapper
<.> TcEvBinds -> HsWrapper
mkWpLet TcEvBinds
ev_binds, result
result) }
tcSkolemiseET :: UserTypeCtxt -> ExpSigmaType
-> (ExpRhoType -> TcM result)
-> TcM (HsWrapper, result)
tcSkolemiseET :: UserTypeCtxt
-> ExpRhoType
-> (ExpRhoType -> TcM result)
-> TcM (HsWrapper, result)
tcSkolemiseET _ et :: ExpRhoType
et@(Infer {}) thing_inside :: ExpRhoType -> TcM result
thing_inside
= (HsWrapper
idHsWrapper, ) (result -> (HsWrapper, result))
-> TcM result -> TcM (HsWrapper, result)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExpRhoType -> TcM result
thing_inside ExpRhoType
et
tcSkolemiseET ctxt :: UserTypeCtxt
ctxt (Check ty :: TcType
ty) thing_inside :: ExpRhoType -> TcM result
thing_inside
= UserTypeCtxt
-> TcType
-> ([Var] -> TcType -> TcM result)
-> TcM (HsWrapper, result)
forall result.
UserTypeCtxt
-> TcType
-> ([Var] -> TcType -> TcM result)
-> TcM (HsWrapper, result)
tcSkolemise UserTypeCtxt
ctxt TcType
ty (([Var] -> TcType -> TcM result) -> TcM (HsWrapper, result))
-> ([Var] -> TcType -> TcM result) -> TcM (HsWrapper, result)
forall a b. (a -> b) -> a -> b
$ \_ -> ExpRhoType -> TcM result
thing_inside (ExpRhoType -> TcM result)
-> (TcType -> ExpRhoType) -> TcType -> TcM result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcType -> ExpRhoType
mkCheckExpType
checkConstraints :: SkolemInfo
-> [TcTyVar]
-> [EvVar]
-> TcM result
-> TcM (TcEvBinds, result)
checkConstraints :: SkolemInfo
-> [Var] -> [Var] -> TcM result -> TcM (TcEvBinds, result)
checkConstraints skol_info :: SkolemInfo
skol_info skol_tvs :: [Var]
skol_tvs given :: [Var]
given thing_inside :: TcM result
thing_inside
= do { Bool
implication_needed <- SkolemInfo -> [Var] -> [Var] -> TcM Bool
implicationNeeded SkolemInfo
skol_info [Var]
skol_tvs [Var]
given
; if Bool
implication_needed
then do { (tclvl :: TcLevel
tclvl, wanted :: WantedConstraints
wanted, result :: result
result) <- TcM result -> TcM (TcLevel, WantedConstraints, result)
forall a. TcM a -> TcM (TcLevel, WantedConstraints, a)
pushLevelAndCaptureConstraints TcM result
thing_inside
; (implics :: Bag Implication
implics, ev_binds :: TcEvBinds
ev_binds) <- TcLevel
-> SkolemInfo
-> [Var]
-> [Var]
-> WantedConstraints
-> TcM (Bag Implication, TcEvBinds)
buildImplicationFor TcLevel
tclvl SkolemInfo
skol_info [Var]
skol_tvs [Var]
given WantedConstraints
wanted
; String -> SDoc -> TcRn ()
traceTc "checkConstraints" (TcLevel -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcLevel
tclvl SDoc -> SDoc -> SDoc
$$ [Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Var]
skol_tvs)
; Bag Implication -> TcRn ()
emitImplications Bag Implication
implics
; (TcEvBinds, result) -> TcM (TcEvBinds, result)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcEvBinds
ev_binds, result
result) }
else
do { result
res <- TcM result
thing_inside
; (TcEvBinds, result) -> TcM (TcEvBinds, result)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcEvBinds
emptyTcEvBinds, result
res) } }
checkTvConstraints :: SkolemInfo
-> Maybe SDoc
-> TcM ([TcTyVar], result)
-> TcM ([TcTyVar], result)
checkTvConstraints :: SkolemInfo
-> Maybe SDoc -> TcM ([Var], result) -> TcM ([Var], result)
checkTvConstraints skol_info :: SkolemInfo
skol_info m_telescope :: Maybe SDoc
m_telescope thing_inside :: TcM ([Var], result)
thing_inside
= do { (tclvl :: TcLevel
tclvl, wanted :: WantedConstraints
wanted, (skol_tvs :: [Var]
skol_tvs, result :: result
result))
<- TcM ([Var], result)
-> TcM (TcLevel, WantedConstraints, ([Var], result))
forall a. TcM a -> TcM (TcLevel, WantedConstraints, a)
pushLevelAndCaptureConstraints TcM ([Var], result)
thing_inside
; SkolemInfo
-> Maybe SDoc -> [Var] -> TcLevel -> WantedConstraints -> TcRn ()
emitResidualTvConstraint SkolemInfo
skol_info Maybe SDoc
m_telescope
[Var]
skol_tvs TcLevel
tclvl WantedConstraints
wanted
; ([Var], result) -> TcM ([Var], result)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Var]
skol_tvs, result
result) }
emitResidualTvConstraint :: SkolemInfo -> Maybe SDoc -> [TcTyVar]
-> TcLevel -> WantedConstraints -> TcM ()
emitResidualTvConstraint :: SkolemInfo
-> Maybe SDoc -> [Var] -> TcLevel -> WantedConstraints -> TcRn ()
emitResidualTvConstraint skol_info :: SkolemInfo
skol_info m_telescope :: Maybe SDoc
m_telescope skol_tvs :: [Var]
skol_tvs tclvl :: TcLevel
tclvl wanted :: WantedConstraints
wanted
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanted
= () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= do { EvBindsVar
ev_binds <- TcM EvBindsVar
newNoTcEvBinds
; Implication
implic <- TcM Implication
newImplication
; Implication -> TcRn ()
emitImplication (Implication -> TcRn ()) -> Implication -> TcRn ()
forall a b. (a -> b) -> a -> b
$
Implication
implic { ic_tclvl :: TcLevel
ic_tclvl = TcLevel
tclvl
, ic_skols :: [Var]
ic_skols = [Var]
skol_tvs
, ic_no_eqs :: Bool
ic_no_eqs = Bool
True
, ic_telescope :: Maybe SDoc
ic_telescope = Maybe SDoc
m_telescope
, ic_wanted :: WantedConstraints
ic_wanted = WantedConstraints
wanted
, ic_binds :: EvBindsVar
ic_binds = EvBindsVar
ev_binds
, ic_info :: SkolemInfo
ic_info = SkolemInfo
skol_info } }
implicationNeeded :: SkolemInfo -> [TcTyVar] -> [EvVar] -> TcM Bool
implicationNeeded :: SkolemInfo -> [Var] -> [Var] -> TcM Bool
implicationNeeded skol_info :: SkolemInfo
skol_info skol_tvs :: [Var]
skol_tvs given :: [Var]
given
| [Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
skol_tvs
, [Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
given
, Bool -> Bool
not (SkolemInfo -> Bool
alwaysBuildImplication SkolemInfo
skol_info)
=
do { TcLevel
tc_lvl <- TcM TcLevel
getTcLevel
; if Bool -> Bool
not (TcLevel -> Bool
isTopTcLevel TcLevel
tc_lvl)
then Bool -> TcM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else
do { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; Bool -> TcM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DeferTypeErrors DynFlags
dflags Bool -> Bool -> Bool
||
GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DeferTypedHoles DynFlags
dflags Bool -> Bool -> Bool
||
GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DeferOutOfScopeVariables DynFlags
dflags) } }
| Bool
otherwise
= Bool -> TcM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
alwaysBuildImplication :: SkolemInfo -> Bool
alwaysBuildImplication :: SkolemInfo -> Bool
alwaysBuildImplication _ = Bool
False
buildImplicationFor :: TcLevel -> SkolemInfo -> [TcTyVar]
-> [EvVar] -> WantedConstraints
-> TcM (Bag Implication, TcEvBinds)
buildImplicationFor :: TcLevel
-> SkolemInfo
-> [Var]
-> [Var]
-> WantedConstraints
-> TcM (Bag Implication, TcEvBinds)
buildImplicationFor tclvl :: TcLevel
tclvl skol_info :: SkolemInfo
skol_info skol_tvs :: [Var]
skol_tvs given :: [Var]
given wanted :: WantedConstraints
wanted
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanted Bool -> Bool -> Bool
&& [Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
given
= (Bag Implication, TcEvBinds) -> TcM (Bag Implication, TcEvBinds)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bag Implication
forall a. Bag a
emptyBag, TcEvBinds
emptyTcEvBinds)
| Bool
otherwise
= ASSERT2( all (isSkolemTyVar <||> isTyVarTyVar) skol_tvs, ppr skol_tvs )
do { EvBindsVar
ev_binds_var <- TcM EvBindsVar
newTcEvBinds
; Implication
implic <- TcM Implication
newImplication
; let implic' :: Implication
implic' = Implication
implic { ic_tclvl :: TcLevel
ic_tclvl = TcLevel
tclvl
, ic_skols :: [Var]
ic_skols = [Var]
skol_tvs
, ic_given :: [Var]
ic_given = [Var]
given
, ic_wanted :: WantedConstraints
ic_wanted = WantedConstraints
wanted
, ic_binds :: EvBindsVar
ic_binds = EvBindsVar
ev_binds_var
, ic_info :: SkolemInfo
ic_info = SkolemInfo
skol_info }
; (Bag Implication, TcEvBinds) -> TcM (Bag Implication, TcEvBinds)
forall (m :: * -> *) a. Monad m => a -> m a
return (Implication -> Bag Implication
forall a. a -> Bag a
unitBag Implication
implic', EvBindsVar -> TcEvBinds
TcEvBinds EvBindsVar
ev_binds_var) }
unifyType :: Maybe (HsExpr GhcRn)
-> TcTauType -> TcTauType -> TcM TcCoercionN
unifyType :: Maybe (HsExpr GhcRn) -> TcType -> TcType -> TcM TcCoercionN
unifyType thing :: Maybe (HsExpr GhcRn)
thing ty1 :: TcType
ty1 ty2 :: TcType
ty2 = String -> SDoc -> TcRn ()
traceTc "utype" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1 SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2 SDoc -> SDoc -> SDoc
$$ Maybe (HsExpr GhcRn) -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe (HsExpr GhcRn)
thing) TcRn () -> TcM TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
TypeLevel CtOrigin
origin TcType
ty1 TcType
ty2
where
origin :: CtOrigin
origin = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
ty1, uo_expected :: TcType
uo_expected = TcType
ty2
, uo_thing :: Maybe SDoc
uo_thing = HsExpr GhcRn -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HsExpr GhcRn -> SDoc) -> Maybe (HsExpr GhcRn) -> Maybe SDoc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (HsExpr GhcRn)
thing
, uo_visible :: Bool
uo_visible = Bool
True }
unifyKind :: Maybe (HsType GhcRn) -> TcKind -> TcKind -> TcM CoercionN
unifyKind :: Maybe (HsType GhcRn) -> TcType -> TcType -> TcM TcCoercionN
unifyKind thing :: Maybe (HsType GhcRn)
thing ty1 :: TcType
ty1 ty2 :: TcType
ty2 = String -> SDoc -> TcRn ()
traceTc "ukind" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1 SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2 SDoc -> SDoc -> SDoc
$$ Maybe (HsType GhcRn) -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe (HsType GhcRn)
thing) TcRn () -> TcM TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
KindLevel CtOrigin
origin TcType
ty1 TcType
ty2
where origin :: CtOrigin
origin = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
ty1, uo_expected :: TcType
uo_expected = TcType
ty2
, uo_thing :: Maybe SDoc
uo_thing = HsType GhcRn -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HsType GhcRn -> SDoc) -> Maybe (HsType GhcRn) -> Maybe SDoc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (HsType GhcRn)
thing
, uo_visible :: Bool
uo_visible = Bool
True }
uType, uType_defer
:: TypeOrKind
-> CtOrigin
-> TcType
-> TcType
-> TcM CoercionN
uType_defer :: TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType_defer t_or_k :: TypeOrKind
t_or_k origin :: CtOrigin
origin ty1 :: TcType
ty1 ty2 :: TcType
ty2
= do { TcCoercionN
co <- CtOrigin
-> TypeOrKind -> Role -> TcType -> TcType -> TcM TcCoercionN
emitWantedEq CtOrigin
origin TypeOrKind
t_or_k Role
Nominal TcType
ty1 TcType
ty2
; DumpFlag -> TcRn () -> TcRn ()
forall gbl lcl. DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl ()
whenDOptM DumpFlag
Opt_D_dump_tc_trace (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$ do
{ [ErrCtxt]
ctxt <- TcM [ErrCtxt]
getErrCtxt
; SDoc
doc <- TidyEnv -> [ErrCtxt] -> TcM SDoc
mkErrInfo TidyEnv
emptyTidyEnv [ErrCtxt]
ctxt
; String -> SDoc -> TcRn ()
traceTc "utype_defer" ([SDoc] -> SDoc
vcat [ TcType -> SDoc
debugPprType TcType
ty1
, TcType -> SDoc
debugPprType TcType
ty2
, CtOrigin -> SDoc
pprCtOrigin CtOrigin
origin
, SDoc
doc])
; String -> SDoc -> TcRn ()
traceTc "utype_defer2" (TcCoercionN -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercionN
co)
}
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return TcCoercionN
co }
uType :: TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType t_or_k :: TypeOrKind
t_or_k origin :: CtOrigin
origin orig_ty1 :: TcType
orig_ty1 orig_ty2 :: TcType
orig_ty2
= do { TcLevel
tclvl <- TcM TcLevel
getTcLevel
; String -> SDoc -> TcRn ()
traceTc "u_tys" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
vcat
[ String -> SDoc
text "tclvl" SDoc -> SDoc -> SDoc
<+> TcLevel -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcLevel
tclvl
, [SDoc] -> SDoc
sep [ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
orig_ty1, String -> SDoc
text "~", TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
orig_ty2]
, CtOrigin -> SDoc
pprCtOrigin CtOrigin
origin]
; TcCoercionN
co <- TcType -> TcType -> TcM TcCoercionN
go TcType
orig_ty1 TcType
orig_ty2
; if TcCoercionN -> Bool
isReflCo TcCoercionN
co
then String -> SDoc -> TcRn ()
traceTc "u_tys yields no coercion" SDoc
Outputable.empty
else String -> SDoc -> TcRn ()
traceTc "u_tys yields coercion:" (TcCoercionN -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercionN
co)
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return TcCoercionN
co }
where
go :: TcType -> TcType -> TcM CoercionN
go :: TcType -> TcType -> TcM TcCoercionN
go (CastTy t1 :: TcType
t1 co1 :: TcCoercionN
co1) t2 :: TcType
t2
= do { TcCoercionN
co_tys <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
t_or_k CtOrigin
origin TcType
t1 TcType
t2
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcType -> TcCoercionN -> TcCoercionN -> TcCoercionN
mkCoherenceLeftCo Role
Nominal TcType
t1 TcCoercionN
co1 TcCoercionN
co_tys) }
go t1 :: TcType
t1 (CastTy t2 :: TcType
t2 co2 :: TcCoercionN
co2)
= do { TcCoercionN
co_tys <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
t_or_k CtOrigin
origin TcType
t1 TcType
t2
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcType -> TcCoercionN -> TcCoercionN -> TcCoercionN
mkCoherenceRightCo Role
Nominal TcType
t2 TcCoercionN
co2 TcCoercionN
co_tys) }
go (TyVarTy tv1 :: Var
tv1) ty2 :: TcType
ty2
= do { LookupTyVarResult
lookup_res <- Var -> TcM LookupTyVarResult
lookupTcTyVar Var
tv1
; case LookupTyVarResult
lookup_res of
Filled ty1 :: TcType
ty1 -> do { String -> SDoc -> TcRn ()
traceTc "found filled tyvar" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv1 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text ":->" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1)
; TcType -> TcType -> TcM TcCoercionN
go TcType
ty1 TcType
ty2 }
Unfilled _ -> CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar CtOrigin
origin TypeOrKind
t_or_k SwapFlag
NotSwapped Var
tv1 TcType
ty2 }
go ty1 :: TcType
ty1 (TyVarTy tv2 :: Var
tv2)
= do { LookupTyVarResult
lookup_res <- Var -> TcM LookupTyVarResult
lookupTcTyVar Var
tv2
; case LookupTyVarResult
lookup_res of
Filled ty2 :: TcType
ty2 -> do { String -> SDoc -> TcRn ()
traceTc "found filled tyvar" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv2 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text ":->" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2)
; TcType -> TcType -> TcM TcCoercionN
go TcType
ty1 TcType
ty2 }
Unfilled _ -> CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar CtOrigin
origin TypeOrKind
t_or_k SwapFlag
IsSwapped Var
tv2 TcType
ty1 }
go ty1 :: TcType
ty1@(TyConApp tc1 :: TyCon
tc1 []) (TyConApp tc2 :: TyCon
tc2 [])
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2
= TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> TcM TcCoercionN) -> TcCoercionN -> TcM TcCoercionN
forall a b. (a -> b) -> a -> b
$ TcType -> TcCoercionN
mkNomReflCo TcType
ty1
go ty1 :: TcType
ty1 ty2 :: TcType
ty2
| Just ty1' :: TcType
ty1' <- TcType -> Maybe TcType
tcView TcType
ty1 = TcType -> TcType -> TcM TcCoercionN
go TcType
ty1' TcType
ty2
| Just ty2' :: TcType
ty2' <- TcType -> Maybe TcType
tcView TcType
ty2 = TcType -> TcType -> TcM TcCoercionN
go TcType
ty1 TcType
ty2'
go (FunTy fun1 :: TcType
fun1 arg1 :: TcType
arg1) (FunTy fun2 :: TcType
fun2 arg2 :: TcType
arg2)
= do { TcCoercionN
co_l <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
t_or_k CtOrigin
origin TcType
fun1 TcType
fun2
; TcCoercionN
co_r <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
t_or_k CtOrigin
origin TcType
arg1 TcType
arg2
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> TcM TcCoercionN) -> TcCoercionN -> TcM TcCoercionN
forall a b. (a -> b) -> a -> b
$ Role -> TcCoercionN -> TcCoercionN -> TcCoercionN
mkFunCo Role
Nominal TcCoercionN
co_l TcCoercionN
co_r }
go ty1 :: TcType
ty1@(TyConApp tc1 :: TyCon
tc1 _) ty2 :: TcType
ty2
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc1 = TcType -> TcType -> TcM TcCoercionN
defer TcType
ty1 TcType
ty2
go ty1 :: TcType
ty1 ty2 :: TcType
ty2@(TyConApp tc2 :: TyCon
tc2 _)
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc2 = TcType -> TcType -> TcM TcCoercionN
defer TcType
ty1 TcType
ty2
go (TyConApp tc1 :: TyCon
tc1 tys1 :: [TcType]
tys1) (TyConApp tc2 :: TyCon
tc2 tys2 :: [TcType]
tys2)
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2, [TcType] -> [TcType] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [TcType]
tys1 [TcType]
tys2
= ASSERT2( isGenerativeTyCon tc1 Nominal, ppr tc1 )
do { [TcCoercionN]
cos <- (CtOrigin -> TcType -> TcType -> TcM TcCoercionN)
-> [CtOrigin]
-> [TcType]
-> [TcType]
-> IOEnv (Env TcGblEnv TcLclEnv) [TcCoercionN]
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
zipWith3M (TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
t_or_k) [CtOrigin]
origins' [TcType]
tys1 [TcType]
tys2
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> TcM TcCoercionN) -> TcCoercionN -> TcM TcCoercionN
forall a b. (a -> b) -> a -> b
$ HasDebugCallStack => Role -> TyCon -> [TcCoercionN] -> TcCoercionN
Role -> TyCon -> [TcCoercionN] -> TcCoercionN
mkTyConAppCo Role
Nominal TyCon
tc1 [TcCoercionN]
cos }
where
origins' :: [CtOrigin]
origins' = (Bool -> CtOrigin) -> [Bool] -> [CtOrigin]
forall a b. (a -> b) -> [a] -> [b]
map (\is_vis :: Bool
is_vis -> if Bool
is_vis then CtOrigin
origin else CtOrigin -> CtOrigin
toInvisibleOrigin CtOrigin
origin)
(TyCon -> [Bool]
tcTyConVisibilities TyCon
tc1)
go (LitTy m :: TyLit
m) ty :: TcType
ty@(LitTy n :: TyLit
n)
| TyLit
m TyLit -> TyLit -> Bool
forall a. Eq a => a -> a -> Bool
== TyLit
n
= TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> TcM TcCoercionN) -> TcCoercionN -> TcM TcCoercionN
forall a b. (a -> b) -> a -> b
$ TcType -> TcCoercionN
mkNomReflCo TcType
ty
go (AppTy s1 :: TcType
s1 t1 :: TcType
t1) (AppTy s2 :: TcType
s2 t2 :: TcType
t2)
= Bool -> TcType -> TcType -> TcType -> TcType -> TcM TcCoercionN
go_app (TcType -> Bool
isNextArgVisible TcType
s1) TcType
s1 TcType
t1 TcType
s2 TcType
t2
go (AppTy s1 :: TcType
s1 t1 :: TcType
t1) (TyConApp tc2 :: TyCon
tc2 ts2 :: [TcType]
ts2)
| Just (ts2' :: [TcType]
ts2', t2' :: TcType
t2') <- [TcType] -> Maybe ([TcType], TcType)
forall a. [a] -> Maybe ([a], a)
snocView [TcType]
ts2
= ASSERT( mightBeUnsaturatedTyCon tc2 )
Bool -> TcType -> TcType -> TcType -> TcType -> TcM TcCoercionN
go_app (TyCon -> [TcType] -> Bool
isNextTyConArgVisible TyCon
tc2 [TcType]
ts2') TcType
s1 TcType
t1 (TyCon -> [TcType] -> TcType
TyConApp TyCon
tc2 [TcType]
ts2') TcType
t2'
go (TyConApp tc1 :: TyCon
tc1 ts1 :: [TcType]
ts1) (AppTy s2 :: TcType
s2 t2 :: TcType
t2)
| Just (ts1' :: [TcType]
ts1', t1' :: TcType
t1') <- [TcType] -> Maybe ([TcType], TcType)
forall a. [a] -> Maybe ([a], a)
snocView [TcType]
ts1
= ASSERT( mightBeUnsaturatedTyCon tc1 )
Bool -> TcType -> TcType -> TcType -> TcType -> TcM TcCoercionN
go_app (TyCon -> [TcType] -> Bool
isNextTyConArgVisible TyCon
tc1 [TcType]
ts1') (TyCon -> [TcType] -> TcType
TyConApp TyCon
tc1 [TcType]
ts1') TcType
t1' TcType
s2 TcType
t2
go (CoercionTy co1 :: TcCoercionN
co1) (CoercionTy co2 :: TcCoercionN
co2)
= do { let ty1 :: TcType
ty1 = TcCoercionN -> TcType
coercionType TcCoercionN
co1
ty2 :: TcType
ty2 = TcCoercionN -> TcType
coercionType TcCoercionN
co2
; TcCoercionN
kco <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
KindLevel
(TcType -> Maybe TcType -> CtOrigin -> Maybe TypeOrKind -> CtOrigin
KindEqOrigin TcType
orig_ty1 (TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
orig_ty2) CtOrigin
origin
(TypeOrKind -> Maybe TypeOrKind
forall a. a -> Maybe a
Just TypeOrKind
t_or_k))
TcType
ty1 TcType
ty2
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> TcM TcCoercionN) -> TcCoercionN -> TcM TcCoercionN
forall a b. (a -> b) -> a -> b
$ Role -> TcCoercionN -> TcCoercionN -> TcCoercionN -> TcCoercionN
mkProofIrrelCo Role
Nominal TcCoercionN
kco TcCoercionN
co1 TcCoercionN
co2 }
go ty1 :: TcType
ty1 ty2 :: TcType
ty2 = TcType -> TcType -> TcM TcCoercionN
defer TcType
ty1 TcType
ty2
defer :: TcType -> TcType -> TcM TcCoercionN
defer ty1 :: TcType
ty1 ty2 :: TcType
ty2
| TcType
ty1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
ty2 = TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> TcCoercionN
mkNomReflCo TcType
ty1)
| Bool
otherwise = TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType_defer TypeOrKind
t_or_k CtOrigin
origin TcType
ty1 TcType
ty2
go_app :: Bool -> TcType -> TcType -> TcType -> TcType -> TcM TcCoercionN
go_app vis :: Bool
vis s1 :: TcType
s1 t1 :: TcType
t1 s2 :: TcType
s2 t2 :: TcType
t2
= do { TcCoercionN
co_s <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
t_or_k CtOrigin
origin TcType
s1 TcType
s2
; let arg_origin :: CtOrigin
arg_origin
| Bool
vis = CtOrigin
origin
| Bool
otherwise = CtOrigin -> CtOrigin
toInvisibleOrigin CtOrigin
origin
; TcCoercionN
co_t <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
t_or_k CtOrigin
arg_origin TcType
t1 TcType
t2
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN -> TcM TcCoercionN) -> TcCoercionN -> TcM TcCoercionN
forall a b. (a -> b) -> a -> b
$ TcCoercionN -> TcCoercionN -> TcCoercionN
mkAppCo TcCoercionN
co_s TcCoercionN
co_t }
uUnfilledVar :: CtOrigin
-> TypeOrKind
-> SwapFlag
-> TcTyVar
-> TcTauType
-> TcM Coercion
uUnfilledVar :: CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar origin :: CtOrigin
origin t_or_k :: TypeOrKind
t_or_k swapped :: SwapFlag
swapped tv1 :: Var
tv1 ty2 :: TcType
ty2
= do { TcType
ty2 <- TcType -> IOEnv (Env TcGblEnv TcLclEnv) TcType
zonkTcType TcType
ty2
; CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar1 CtOrigin
origin TypeOrKind
t_or_k SwapFlag
swapped Var
tv1 TcType
ty2 }
uUnfilledVar1 :: CtOrigin
-> TypeOrKind
-> SwapFlag
-> TcTyVar
-> TcTauType
-> TcM Coercion
uUnfilledVar1 :: CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar1 origin :: CtOrigin
origin t_or_k :: TypeOrKind
t_or_k swapped :: SwapFlag
swapped tv1 :: Var
tv1 ty2 :: TcType
ty2
| Just tv2 :: Var
tv2 <- TcType -> Maybe Var
tcGetTyVar_maybe TcType
ty2
= Var -> TcM TcCoercionN
go Var
tv2
| Bool
otherwise
= CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar2 CtOrigin
origin TypeOrKind
t_or_k SwapFlag
swapped Var
tv1 TcType
ty2
where
go :: Var -> TcM TcCoercionN
go tv2 :: Var
tv2 | Var
tv1 Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
tv2
= TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> TcCoercionN
mkNomReflCo (Var -> TcType
mkTyVarTy Var
tv1))
| Var -> Var -> Bool
swapOverTyVars Var
tv1 Var
tv2
= CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar2 CtOrigin
origin TypeOrKind
t_or_k (SwapFlag -> SwapFlag
flipSwap SwapFlag
swapped)
Var
tv2 (Var -> TcType
mkTyVarTy Var
tv1)
| Bool
otherwise
= CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar2 CtOrigin
origin TypeOrKind
t_or_k SwapFlag
swapped Var
tv1 TcType
ty2
uUnfilledVar2 :: CtOrigin
-> TypeOrKind
-> SwapFlag
-> TcTyVar
-> TcTauType
-> TcM Coercion
uUnfilledVar2 :: CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar2 origin :: CtOrigin
origin t_or_k :: TypeOrKind
t_or_k swapped :: SwapFlag
swapped tv1 :: Var
tv1 ty2 :: TcType
ty2
= do { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; TcLevel
cur_lvl <- TcM TcLevel
getTcLevel
; DynFlags -> TcLevel -> TcM TcCoercionN
go DynFlags
dflags TcLevel
cur_lvl }
where
go :: DynFlags -> TcLevel -> TcM TcCoercionN
go dflags :: DynFlags
dflags cur_lvl :: TcLevel
cur_lvl
| TcLevel -> Var -> TcType -> Bool
canSolveByUnification TcLevel
cur_lvl Var
tv1 TcType
ty2
, Just ty2' :: TcType
ty2' <- DynFlags -> Var -> TcType -> Maybe TcType
metaTyVarUpdateOK DynFlags
dflags Var
tv1 TcType
ty2
= do { TcCoercionN
co_k <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
KindLevel CtOrigin
kind_origin (HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
ty2') (Var -> TcType
tyVarKind Var
tv1)
; String -> SDoc -> TcRn ()
traceTc "uUnfilledVar2 ok" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv1 SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> TcType
tyVarKind Var
tv1)
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2 SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
ty2)
, Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TcCoercionN -> Bool
isTcReflCo TcCoercionN
co_k), TcCoercionN -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercionN
co_k ]
; if TcCoercionN -> Bool
isTcReflCo TcCoercionN
co_k
then do { Var -> TcType -> TcRn ()
writeMetaTyVar Var
tv1 TcType
ty2'
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> TcCoercionN
mkTcNomReflCo TcType
ty2') }
else TcM TcCoercionN
defer }
| Bool
otherwise
= do { String -> SDoc -> TcRn ()
traceTc "uUnfilledVar2 not ok" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv1 SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2)
; TcM TcCoercionN
defer }
ty1 :: TcType
ty1 = Var -> TcType
mkTyVarTy Var
tv1
kind_origin :: CtOrigin
kind_origin = TcType -> Maybe TcType -> CtOrigin -> Maybe TypeOrKind -> CtOrigin
KindEqOrigin TcType
ty1 (TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
ty2) CtOrigin
origin (TypeOrKind -> Maybe TypeOrKind
forall a. a -> Maybe a
Just TypeOrKind
t_or_k)
defer :: TcM TcCoercionN
defer = SwapFlag
-> (TcType -> TcType -> TcM TcCoercionN)
-> TcType
-> TcType
-> TcM TcCoercionN
forall a b. SwapFlag -> (a -> a -> b) -> a -> a -> b
unSwap SwapFlag
swapped (TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType_defer TypeOrKind
t_or_k CtOrigin
origin) TcType
ty1 TcType
ty2
swapOverTyVars :: TcTyVar -> TcTyVar -> Bool
swapOverTyVars :: Var -> Var -> Bool
swapOverTyVars tv1 :: Var
tv1 tv2 :: Var
tv2
| TcLevel
lvl1 TcLevel -> TcLevel -> Bool
`strictlyDeeperThan` TcLevel
lvl2 = Bool
False
| TcLevel
lvl2 TcLevel -> TcLevel -> Bool
`strictlyDeeperThan` TcLevel
lvl1 = Bool
True
| Arity
pri1 Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
> Arity
pri2 = Bool
False
| Arity
pri2 Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
> Arity
pri1 = Bool
True
| Name -> Bool
isSystemName Name
tv2_name, Bool -> Bool
not (Name -> Bool
isSystemName Name
tv1_name) = Bool
True
| Bool
otherwise = Bool
False
where
lvl1 :: TcLevel
lvl1 = Var -> TcLevel
tcTyVarLevel Var
tv1
lvl2 :: TcLevel
lvl2 = Var -> TcLevel
tcTyVarLevel Var
tv2
pri1 :: Arity
pri1 = Var -> Arity
lhsPriority Var
tv1
pri2 :: Arity
pri2 = Var -> Arity
lhsPriority Var
tv2
tv1_name :: Name
tv1_name = Var -> Name
Var.varName Var
tv1
tv2_name :: Name
tv2_name = Var -> Name
Var.varName Var
tv2
lhsPriority :: TcTyVar -> Int
lhsPriority :: Var -> Arity
lhsPriority tv :: Var
tv
= ASSERT2( isTyVar tv, ppr tv)
case Var -> TcTyVarDetails
tcTyVarDetails Var
tv of
RuntimeUnk -> 0
SkolemTv {} -> 0
MetaTv { mtv_info :: TcTyVarDetails -> MetaInfo
mtv_info = MetaInfo
info } -> case MetaInfo
info of
FlatSkolTv -> 1
TyVarTv -> 2
TauTv -> 3
FlatMetaTv -> 4
canSolveByUnification :: TcLevel -> TcTyVar -> TcType -> Bool
canSolveByUnification :: TcLevel -> Var -> TcType -> Bool
canSolveByUnification tclvl :: TcLevel
tclvl tv :: Var
tv xi :: TcType
xi
| TcLevel -> Var -> Bool
isTouchableMetaTyVar TcLevel
tclvl Var
tv
= case Var -> MetaInfo
metaTyVarInfo Var
tv of
TyVarTv -> TcType -> Bool
is_tyvar TcType
xi
_ -> Bool
True
| Bool
otherwise
= Bool
False
where
is_tyvar :: TcType -> Bool
is_tyvar xi :: TcType
xi
= case TcType -> Maybe Var
tcGetTyVar_maybe TcType
xi of
Nothing -> Bool
False
Just tv :: Var
tv -> case Var -> TcTyVarDetails
tcTyVarDetails Var
tv of
MetaTv { mtv_info :: TcTyVarDetails -> MetaInfo
mtv_info = MetaInfo
info }
-> case MetaInfo
info of
TyVarTv -> Bool
True
_ -> Bool
False
SkolemTv {} -> Bool
True
RuntimeUnk -> Bool
True
data LookupTyVarResult
= Unfilled TcTyVarDetails
| Filled TcType
lookupTcTyVar :: TcTyVar -> TcM LookupTyVarResult
lookupTcTyVar :: Var -> TcM LookupTyVarResult
lookupTcTyVar tyvar :: Var
tyvar
| MetaTv { mtv_ref :: TcTyVarDetails -> IORef MetaDetails
mtv_ref = IORef MetaDetails
ref } <- TcTyVarDetails
details
= do { MetaDetails
meta_details <- IORef MetaDetails -> TcM MetaDetails
forall a env. IORef a -> IOEnv env a
readMutVar IORef MetaDetails
ref
; case MetaDetails
meta_details of
Indirect ty :: TcType
ty -> LookupTyVarResult -> TcM LookupTyVarResult
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> LookupTyVarResult
Filled TcType
ty)
Flexi -> do { Bool
is_touchable <- Var -> TcM Bool
isTouchableTcM Var
tyvar
; if Bool
is_touchable then
LookupTyVarResult -> TcM LookupTyVarResult
forall (m :: * -> *) a. Monad m => a -> m a
return (TcTyVarDetails -> LookupTyVarResult
Unfilled TcTyVarDetails
details)
else
LookupTyVarResult -> TcM LookupTyVarResult
forall (m :: * -> *) a. Monad m => a -> m a
return (TcTyVarDetails -> LookupTyVarResult
Unfilled TcTyVarDetails
vanillaSkolemTv) } }
| Bool
otherwise
= LookupTyVarResult -> TcM LookupTyVarResult
forall (m :: * -> *) a. Monad m => a -> m a
return (TcTyVarDetails -> LookupTyVarResult
Unfilled TcTyVarDetails
details)
where
details :: TcTyVarDetails
details = Var -> TcTyVarDetails
tcTyVarDetails Var
tyvar
matchExpectedFunKind :: Outputable fun
=> fun
-> TcKind
-> TcM (Coercion, TcKind, TcKind)
matchExpectedFunKind :: fun -> TcType -> TcM (TcCoercionN, TcType, TcType)
matchExpectedFunKind hs_ty :: fun
hs_ty = TcType -> TcM (TcCoercionN, TcType, TcType)
go
where
go :: TcType -> TcM (TcCoercionN, TcType, TcType)
go k :: TcType
k | Just k' :: TcType
k' <- TcType -> Maybe TcType
tcView TcType
k = TcType -> TcM (TcCoercionN, TcType, TcType)
go TcType
k'
go k :: TcType
k@(TyVarTy kvar :: Var
kvar)
| Var -> Bool
isMetaTyVar Var
kvar
= do { MetaDetails
maybe_kind <- Var -> TcM MetaDetails
readMetaTyVar Var
kvar
; case MetaDetails
maybe_kind of
Indirect fun_kind :: TcType
fun_kind -> TcType -> TcM (TcCoercionN, TcType, TcType)
go TcType
fun_kind
Flexi -> TcType -> TcM (TcCoercionN, TcType, TcType)
defer TcType
k }
go k :: TcType
k@(FunTy arg :: TcType
arg res :: TcType
res) = (TcCoercionN, TcType, TcType) -> TcM (TcCoercionN, TcType, TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> TcCoercionN
mkNomReflCo TcType
k, TcType
arg, TcType
res)
go other :: TcType
other = TcType -> TcM (TcCoercionN, TcType, TcType)
defer TcType
other
defer :: TcType -> TcM (TcCoercionN, TcType, TcType)
defer k :: TcType
k
= do { TcType
arg_kind <- IOEnv (Env TcGblEnv TcLclEnv) TcType
newMetaKindVar
; TcType
res_kind <- IOEnv (Env TcGblEnv TcLclEnv) TcType
newMetaKindVar
; let new_fun :: TcType
new_fun = TcType -> TcType -> TcType
mkFunTy TcType
arg_kind TcType
res_kind
origin :: CtOrigin
origin = TypeEqOrigin :: TcType -> TcType -> Maybe SDoc -> Bool -> CtOrigin
TypeEqOrigin { uo_actual :: TcType
uo_actual = TcType
k
, uo_expected :: TcType
uo_expected = TcType
new_fun
, uo_thing :: Maybe SDoc
uo_thing = SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just (fun -> SDoc
forall a. Outputable a => a -> SDoc
ppr fun
hs_ty)
, uo_visible :: Bool
uo_visible = Bool
True
}
; TcCoercionN
co <- TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
KindLevel CtOrigin
origin TcType
k TcType
new_fun
; (TcCoercionN, TcType, TcType) -> TcM (TcCoercionN, TcType, TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercionN
co, TcType
arg_kind, TcType
res_kind) }
data OccCheckResult a
= OC_OK a
| OC_Bad
| OC_Occurs
instance Functor OccCheckResult where
fmap :: (a -> b) -> OccCheckResult a -> OccCheckResult b
fmap = (a -> b) -> OccCheckResult a -> OccCheckResult b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
instance Applicative OccCheckResult where
pure :: a -> OccCheckResult a
pure = a -> OccCheckResult a
forall a. a -> OccCheckResult a
OC_OK
<*> :: OccCheckResult (a -> b) -> OccCheckResult a -> OccCheckResult b
(<*>) = OccCheckResult (a -> b) -> OccCheckResult a -> OccCheckResult b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad OccCheckResult where
OC_OK x :: a
x >>= :: OccCheckResult a -> (a -> OccCheckResult b) -> OccCheckResult b
>>= k :: a -> OccCheckResult b
k = a -> OccCheckResult b
k a
x
OC_Bad >>= _ = OccCheckResult b
forall a. OccCheckResult a
OC_Bad
OC_Occurs >>= _ = OccCheckResult b
forall a. OccCheckResult a
OC_Occurs
occCheckForErrors :: DynFlags -> TcTyVar -> Type -> OccCheckResult ()
occCheckForErrors :: DynFlags -> Var -> TcType -> OccCheckResult ()
occCheckForErrors dflags :: DynFlags
dflags tv :: Var
tv ty :: TcType
ty
= case DynFlags -> Bool -> Var -> TcType -> OccCheckResult ()
preCheck DynFlags
dflags Bool
True Var
tv TcType
ty of
OC_OK _ -> () -> OccCheckResult ()
forall a. a -> OccCheckResult a
OC_OK ()
OC_Bad -> OccCheckResult ()
forall a. OccCheckResult a
OC_Bad
OC_Occurs -> case [Var] -> TcType -> Maybe TcType
occCheckExpand [Var
tv] TcType
ty of
Nothing -> OccCheckResult ()
forall a. OccCheckResult a
OC_Occurs
Just _ -> () -> OccCheckResult ()
forall a. a -> OccCheckResult a
OC_OK ()
metaTyVarUpdateOK :: DynFlags
-> TcTyVar
-> TcType
-> Maybe TcType
metaTyVarUpdateOK :: DynFlags -> Var -> TcType -> Maybe TcType
metaTyVarUpdateOK dflags :: DynFlags
dflags tv :: Var
tv ty :: TcType
ty
= case DynFlags -> Bool -> Var -> TcType -> OccCheckResult ()
preCheck DynFlags
dflags Bool
False Var
tv TcType
ty of
OC_OK _ -> TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
ty
OC_Bad -> Maybe TcType
forall a. Maybe a
Nothing
OC_Occurs -> [Var] -> TcType -> Maybe TcType
occCheckExpand [Var
tv] TcType
ty
preCheck :: DynFlags -> Bool -> TcTyVar -> TcType -> OccCheckResult ()
preCheck :: DynFlags -> Bool -> Var -> TcType -> OccCheckResult ()
preCheck dflags :: DynFlags
dflags ty_fam_ok :: Bool
ty_fam_ok tv :: Var
tv ty :: TcType
ty
= TcType -> OccCheckResult ()
fast_check TcType
ty
where
details :: TcTyVarDetails
details = Var -> TcTyVarDetails
tcTyVarDetails Var
tv
impredicative_ok :: Bool
impredicative_ok = DynFlags -> TcTyVarDetails -> Bool
canUnifyWithPolyType DynFlags
dflags TcTyVarDetails
details
ok :: OccCheckResult ()
ok :: OccCheckResult ()
ok = () -> OccCheckResult ()
forall a. a -> OccCheckResult a
OC_OK ()
fast_check :: TcType -> OccCheckResult ()
fast_check :: TcType -> OccCheckResult ()
fast_check (TyVarTy tv' :: Var
tv')
| Var
tv Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
tv' = OccCheckResult ()
forall a. OccCheckResult a
OC_Occurs
| Bool
otherwise = TcType -> OccCheckResult ()
fast_check_occ (Var -> TcType
tyVarKind Var
tv')
fast_check (TyConApp tc :: TyCon
tc tys :: [TcType]
tys)
| TyCon -> Bool
bad_tc TyCon
tc = OccCheckResult ()
forall a. OccCheckResult a
OC_Bad
| Bool
otherwise = (TcType -> OccCheckResult ()) -> [TcType] -> OccCheckResult [()]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM TcType -> OccCheckResult ()
fast_check [TcType]
tys OccCheckResult [()] -> OccCheckResult () -> OccCheckResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> OccCheckResult ()
ok
fast_check (LitTy {}) = OccCheckResult ()
ok
fast_check (FunTy a :: TcType
a r :: TcType
r) = TcType -> OccCheckResult ()
fast_check TcType
a OccCheckResult () -> OccCheckResult () -> OccCheckResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TcType -> OccCheckResult ()
fast_check TcType
r
fast_check (AppTy fun :: TcType
fun arg :: TcType
arg) = TcType -> OccCheckResult ()
fast_check TcType
fun OccCheckResult () -> OccCheckResult () -> OccCheckResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TcType -> OccCheckResult ()
fast_check TcType
arg
fast_check (CastTy ty :: TcType
ty co :: TcCoercionN
co) = TcType -> OccCheckResult ()
fast_check TcType
ty OccCheckResult () -> OccCheckResult () -> OccCheckResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TcCoercionN -> OccCheckResult ()
fast_check_co TcCoercionN
co
fast_check (CoercionTy co :: TcCoercionN
co) = TcCoercionN -> OccCheckResult ()
fast_check_co TcCoercionN
co
fast_check (ForAllTy (Bndr tv' :: Var
tv' _) ty :: TcType
ty)
| Bool -> Bool
not Bool
impredicative_ok = OccCheckResult ()
forall a. OccCheckResult a
OC_Bad
| Var
tv Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
tv' = OccCheckResult ()
ok
| Bool
otherwise = do { TcType -> OccCheckResult ()
fast_check_occ (Var -> TcType
tyVarKind Var
tv')
; TcType -> OccCheckResult ()
fast_check_occ TcType
ty }
fast_check_occ :: TcType -> OccCheckResult ()
fast_check_occ k :: TcType
k | Var
tv Var -> VarSet -> Bool
`elemVarSet` TcType -> VarSet
tyCoVarsOfType TcType
k = OccCheckResult ()
forall a. OccCheckResult a
OC_Occurs
| Bool
otherwise = OccCheckResult ()
ok
fast_check_co :: TcCoercionN -> OccCheckResult ()
fast_check_co co :: TcCoercionN
co | Var
tv Var -> VarSet -> Bool
`elemVarSet` TcCoercionN -> VarSet
tyCoVarsOfCo TcCoercionN
co = OccCheckResult ()
forall a. OccCheckResult a
OC_Occurs
| Bool
otherwise = OccCheckResult ()
ok
bad_tc :: TyCon -> Bool
bad_tc :: TyCon -> Bool
bad_tc tc :: TyCon
tc
| Bool -> Bool
not (Bool
impredicative_ok Bool -> Bool -> Bool
|| TyCon -> Bool
isTauTyCon TyCon
tc) = Bool
True
| Bool -> Bool
not (Bool
ty_fam_ok Bool -> Bool -> Bool
|| TyCon -> Bool
isFamFreeTyCon TyCon
tc) = Bool
True
| Bool
otherwise = Bool
False
canUnifyWithPolyType :: DynFlags -> TcTyVarDetails -> Bool
canUnifyWithPolyType :: DynFlags -> TcTyVarDetails -> Bool
canUnifyWithPolyType dflags :: DynFlags
dflags details :: TcTyVarDetails
details
= case TcTyVarDetails
details of
MetaTv { mtv_info :: TcTyVarDetails -> MetaInfo
mtv_info = MetaInfo
TyVarTv } -> Bool
False
MetaTv { mtv_info :: TcTyVarDetails -> MetaInfo
mtv_info = MetaInfo
TauTv } -> Extension -> DynFlags -> Bool
xopt Extension
LangExt.ImpredicativeTypes DynFlags
dflags
_other :: TcTyVarDetails
_other -> Bool
True