{-# LANGUAGE CPP, DeriveFunctor, 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, MetaTyVarUpdateResult(..)
) where
#include "HsVersions.h"
import GhcPrelude
import GHC.Hs
import TyCoRep
import TyCoPpr( debugPprType )
import TcMType
import TcRnMonad
import TcType
import Type
import Coercion
import TcEvidence
import Constraint
import Predicate
import TcOrigin
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 Data.Maybe( isNothing )
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 SDoc
herald Arity
arity ExpRhoType
orig_ty [ExpRhoType] -> ExpRhoType -> TcM a
thing_inside
= case ExpRhoType
orig_ty of
Check TcType
ty -> [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go [] Arity
arity TcType
ty
ExpRhoType
_ -> [ExpRhoType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper)
defer [] Arity
arity ExpRhoType
orig_ty
where
go :: [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go [ExpRhoType]
acc_arg_tys Arity
0 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 [ExpRhoType]
acc_arg_tys Arity
n TcType
ty
| Just TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty = [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go [ExpRhoType]
acc_arg_tys Arity
n TcType
ty'
go [ExpRhoType]
acc_arg_tys Arity
n (FunTy { ft_af :: TcType -> AnonArgFlag
ft_af = AnonArgFlag
af, ft_arg :: TcType -> TcType
ft_arg = TcType
arg_ty, ft_res :: TcType -> TcType
ft_res = TcType
res_ty })
= ASSERT( af == VisArg )
do { (a
result, 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
-Arity
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 String
"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 [ExpRhoType]
acc_arg_tys Arity
n ty :: TcType
ty@(TyVarTy Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect TcType
ty' -> [ExpRhoType] -> Arity -> TcType -> TcM (a, HsWrapper)
go [ExpRhoType]
acc_arg_tys Arity
n TcType
ty'
MetaDetails
Flexi -> [ExpRhoType] -> Arity -> ExpRhoType -> TcM (a, HsWrapper)
defer [ExpRhoType]
acc_arg_tys Arity
n (TcType -> ExpRhoType
mkCheckExpType TcType
ty) }
go [ExpRhoType]
acc_arg_tys Arity
n 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 [ExpRhoType]
acc_arg_tys Arity
n 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
mkVisFunTys [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 TidyEnv
env = do { (TidyEnv
env', TcType
ty) <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
env TcType
orig_tc_ty
; let ([TcType]
args, TcType
_) = TcType -> ([TcType], TcType)
tcSplitFunTys TcType
ty
n_actual :: Arity
n_actual = [TcType] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [TcType]
args
(TidyEnv
env'', 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 String
"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 SDoc
herald CtOrigin
ct_orig Maybe (HsExpr GhcRn)
mb_thing Arity
arity 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 SDoc
herald CtOrigin
ct_orig Maybe (HsExpr GhcRn)
mb_thing Arity
arity TcType
orig_ty
[TcType]
orig_old_args 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 Arity
0 [TcType]
_ TcType
ty = (HsWrapper, [TcType], TcType) -> TcM (HsWrapper, [TcType], TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (HsWrapper
idHsWrapper, [], TcType
ty)
go Arity
n [TcType]
acc_args 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 { (HsWrapper
wrap1, TcType
rho) <- CtOrigin -> TcType -> TcM (HsWrapper, TcType)
topInstantiate CtOrigin
ct_orig TcType
ty
; (HsWrapper
wrap2, [TcType]
arg_tys, 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
([Var]
tvs, [TcType]
theta, TcType
_) = TcType -> ([Var], [TcType], TcType)
tcSplitSigmaTy TcType
ty
go Arity
n [TcType]
acc_args TcType
ty
| Just TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty = Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go Arity
n [TcType]
acc_args TcType
ty'
go Arity
n [TcType]
acc_args (FunTy { ft_af :: TcType -> AnonArgFlag
ft_af = AnonArgFlag
af, ft_arg :: TcType -> TcType
ft_arg = TcType
arg_ty, ft_res :: TcType -> TcType
ft_res = TcType
res_ty })
= ASSERT( af == VisArg )
do { (HsWrapper
wrap_res, [TcType]
tys, TcType
ty_r) <- Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go (Arity
nArity -> Arity -> Arity
forall a. Num a => a -> a -> a
-Arity
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 String
"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 Arity
n [TcType]
acc_args ty :: TcType
ty@(TyVarTy Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect TcType
ty' -> Arity -> [TcType] -> TcType -> TcM (HsWrapper, [TcType], TcType)
go Arity
n [TcType]
acc_args TcType
ty'
MetaDetails
Flexi -> Arity -> TcType -> TcM (HsWrapper, [TcType], TcType)
defer Arity
n TcType
ty }
go Arity
n [TcType]
acc_args 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 Arity
n 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
mkVisFunTys [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 [TcType]
arg_tys TcType
res_ty TidyEnv
env
= do { let ty :: TcType
ty = [TcType] -> TcType -> TcType
mkVisFunTys [TcType]
arg_tys TcType
res_ty
; (TidyEnv
env1, TcType
zonked) <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
env TcType
ty
; let ([TcType]
zonked_args, TcType
_) = 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
(TidyEnv
env2, 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 TcType
full_ty TcType
ty Arity
n_args Arity
full_arity SDoc
herald
= SDoc
herald SDoc -> SDoc -> SDoc
<+> Arity -> SDoc -> SDoc
speakNOf Arity
full_arity (String -> SDoc
text String
"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 String
"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 String
"it is specialized to" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TcType -> SDoc
pprType TcType
ty)
else [SDoc] -> SDoc
sep [String -> SDoc
text String
"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
== Arity
0 then String -> SDoc
text String
"has none"
else String -> SDoc
text String
"has only" SDoc -> SDoc -> SDoc
<+> Arity -> SDoc
speakN Arity
n_args]
matchExpectedListTy :: TcRhoType -> TcM (TcCoercionN, TcRhoType)
matchExpectedListTy :: TcType -> TcM (TcCoercionN, TcType)
matchExpectedListTy TcType
exp_ty
= do { (TcCoercionN
co, [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 TyCon
tc TcType
orig_ty
= ASSERT(tc /= funTyCon) go orig_ty
where
go :: TcType -> TcM (TcCoercionN, [TcType])
go TcType
ty
| Just TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty
= TcType -> TcM (TcCoercionN, [TcType])
go TcType
ty'
go ty :: TcType
ty@(TyConApp TyCon
tycon [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 Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect TcType
ty -> TcType -> TcM (TcCoercionN, [TcType])
go TcType
ty
MetaDetails
Flexi -> TcM (TcCoercionN, [TcType])
defer }
go TcType
_ = TcM (TcCoercionN, [TcType])
defer
defer :: TcM (TcCoercionN, [TcType])
defer
= do { (TCvSubst
_, [Var]
arg_tvs) <- [Var] -> TcM (TCvSubst, [Var])
newMetaTyVars (TyCon -> [Var]
tyConTyVars TyCon
tc)
; String -> SDoc -> TcRn ()
traceTc String
"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 TcType
orig_ty
= TcType -> TcM (TcCoercionN, (TcType, TcType))
go TcType
orig_ty
where
go :: TcType -> TcM (TcCoercionN, (TcType, TcType))
go TcType
ty
| Just TcType
ty' <- TcType -> Maybe TcType
tcView TcType
ty = TcType -> TcM (TcCoercionN, (TcType, TcType))
go TcType
ty'
| Just (TcType
fun_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 Var
tv)
| Var -> Bool
isMetaTyVar Var
tv
= do { MetaDetails
cts <- Var -> TcM MetaDetails
readMetaTyVar Var
tv
; case MetaDetails
cts of
Indirect TcType
ty -> TcType -> TcM (TcCoercionN, (TcType, TcType))
go TcType
ty
MetaDetails
Flexi -> TcM (TcCoercionN, (TcType, TcType))
defer }
go TcType
_ = 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
mkVisFunTy 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 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 CtOrigin
orig UserTypeCtxt
ctxt (Check TcType
ty_actual) 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 CtOrigin
_ UserTypeCtxt
_ (Infer InferResult
inf_res) 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 CtOrigin
orig UserTypeCtxt
ctxt TcType
ty_actual 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 String
"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 TcType
ty_actual ExpRhoType
ty_expected 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 TidyEnv
tidy_env
= do { (TidyEnv
tidy_env, 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
; (TidyEnv
tidy_env, ExpRhoType
ty_expected) <- case Maybe TcType
mb_ty_expected of
Just 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
Maybe TcType
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
; (TidyEnv
tidy_env, 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 String
"When checking that:")
Arity
4 (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual)
, Arity -> SDoc -> SDoc
nest Arity
2 (SDoc -> Arity -> SDoc -> SDoc
hang (String -> SDoc
text String
"is more polymorphic than:")
Arity
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 UserTypeCtxt
ctxt TcType
ty_actual TcType
ty_expected
= do { String -> SDoc -> TcRn ()
traceTc String
"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 CtOrigin
orig UserTypeCtxt
ctxt TcType
ty_actual 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 String
"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 CtOrigin
inst_orig UserTypeCtxt
ctxt Maybe (HsExpr GhcRn)
m_thing TcType
ty_actual ExpRhoType
ty_expected
= case ExpRhoType
ty_expected of
Infer InferResult
inf_res -> CtOrigin -> TcType -> InferResult -> TcM HsWrapper
fillInferResult CtOrigin
inst_orig TcType
ty_actual InferResult
inf_res
Check 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 CtOrigin
eq_orig CtOrigin
inst_orig UserTypeCtxt
ctxt TcType
ty_actual 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 String
"tc_sub_tc_type (drop to equality)" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text String
"ty_actual =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual
, String -> SDoc
text String
"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 String
"tc_sub_tc_type (general case)" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text String
"ty_actual =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual
, String -> SDoc
text String
"ty_expected =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected ]
; (HsWrapper
sk_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
$
\ [Var]
_ 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 TcType
ty
| TcType -> Bool
isForAllTy TcType
ty = Bool
True
| Just (TcType
_, 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 TcType
ty
| ([Var]
tvs, [TcType]
theta, TcType
tau) <- TcType -> ([Var], [TcType], TcType)
tcSplitSigmaTy TcType
ty
, (Var
tv:[Var]
_) <- [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 CtOrigin
eq_orig CtOrigin
inst_orig UserTypeCtxt
ctxt TcType
ty_actual TcType
ty_expected
= do { String -> SDoc -> TcRn ()
traceTc String
"tc_sub_type_ds" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text String
"ty_actual =" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_actual
, String -> SDoc
text String
"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 TcType
ty_a TcType
ty_e | Just TcType
ty_a' <- TcType -> Maybe TcType
tcView TcType
ty_a = TcType -> TcType -> TcM HsWrapper
go TcType
ty_a' TcType
ty_e
| Just TcType
ty_e' <- TcType -> Maybe TcType
tcView TcType
ty_e = TcType -> TcType -> TcM HsWrapper
go TcType
ty_a TcType
ty_e'
go (TyVarTy Var
tv_a) TcType
ty_e
= do { LookupTyVarResult
lookup_res <- Var -> TcM LookupTyVarResult
lookupTcTyVar Var
tv_a
; case LookupTyVarResult
lookup_res of
Filled TcType
ty_a' ->
do { String -> SDoc -> TcRn ()
traceTc String
"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 String
"-->" 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 TcTyVarDetails
_ -> TcM HsWrapper
unify }
go (FunTy { ft_af :: TcType -> AnonArgFlag
ft_af = AnonArgFlag
VisArg, ft_arg :: TcType -> TcType
ft_arg = TcType
act_arg, ft_res :: TcType -> TcType
ft_res = TcType
act_res })
(FunTy { ft_af :: TcType -> AnonArgFlag
ft_af = AnonArgFlag
VisArg, ft_arg :: TcType -> TcType
ft_arg = TcType
exp_arg, ft_res :: TcType -> TcType
ft_res = TcType
exp_res })
=
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 String
"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 String
"is more polymorphic than" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty_expected)
go TcType
ty_a TcType
ty_e
| let ([Var]
tvs, [TcType]
theta, TcType
_) = 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 { (HsWrapper
in_wrap, 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 { (HsWrapper
wrap, 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
_ -> 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 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 CtOrigin
orig HsExpr GhcRn
rn_expr HsExpr GhcTcId
expr TcType
actual_ty ExpRhoType
res_ty
= do { String -> SDoc -> TcRn ()
traceTc String
"tcWrapResult" ([SDoc] -> SDoc
vcat [ String -> SDoc
text String
"Actual: " SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
actual_ty
, String -> SDoc
text String
"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 Bool
instantiate 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 CtOrigin
orig TcType
ty inf_res :: InferResult
inf_res@(IR { ir_inst :: InferResult -> Bool
ir_inst = Bool
instantiate_me })
| Bool
instantiate_me
= do { (HsWrapper
wrap, 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 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 { (TcCoercionN
ty_co, TcType
ty_to_fill_with) <- TcLevel -> TcType -> TcM (TcCoercionN, TcType)
promoteTcType TcLevel
res_lvl TcType
orig_ty
; String -> SDoc -> TcRn ()
traceTc String
"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 String
":=" 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 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 TcType
already_there -> String -> SDoc -> IOEnv (Env gbl lcl) ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"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 ])
Maybe TcType
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 TcLevel
dest_lvl 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 UserTypeCtxt
ctxt TcType
expected_ty [Var] -> TcType -> TcM result
thing_inside
= do { String -> SDoc -> TcRn ()
traceTc String
"tcSkolemise" SDoc
Outputable.empty
; (HsWrapper
wrap, [(Name, Var)]
tv_prs, [Var]
given, 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 String
"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 String
"expected_ty" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
expected_ty,
String -> SDoc
text String
"inst tyvars" SDoc -> SDoc -> SDoc
<+> [(Name, Var)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Name, Var)]
tv_prs,
String -> SDoc
text String
"given" SDoc -> SDoc -> SDoc
<+> [Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Var]
given,
String -> SDoc
text String
"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
; (TcEvBinds
ev_binds, 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 UserTypeCtxt
_ et :: ExpRhoType
et@(Infer {}) 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 UserTypeCtxt
ctxt (Check TcType
ty) 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
$ \[Var]
_ -> 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 SkolemInfo
skol_info [Var]
skol_tvs [Var]
given 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 { (TcLevel
tclvl, WantedConstraints
wanted, result
result) <- TcM result -> TcM (TcLevel, WantedConstraints, result)
forall a. TcM a -> TcM (TcLevel, WantedConstraints, a)
pushLevelAndCaptureConstraints TcM result
thing_inside
; (Bag Implication
implics, 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 String
"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 SkolemInfo
skol_info Maybe SDoc
m_telescope TcM ([Var], result)
thing_inside
= do { (TcLevel
tclvl, WantedConstraints
wanted, ([Var]
skol_tvs, 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 SkolemInfo
skol_info Maybe SDoc
m_telescope [Var]
skol_tvs TcLevel
tclvl WantedConstraints
wanted
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanted
, Maybe SDoc -> Bool
forall a. Maybe a -> Bool
isNothing Maybe SDoc
m_telescope Bool -> Bool -> Bool
|| [Var]
skol_tvs [Var] -> Arity -> Bool
forall a. [a] -> Arity -> Bool
`lengthAtMost` Arity
1
= () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= do { EvBindsVar
ev_binds <- TcM EvBindsVar
newNoTcEvBinds
; Implication
implic <- TcM Implication
newImplication
; let status :: ImplicStatus
status | WantedConstraints -> Bool
insolubleWC WantedConstraints
wanted = ImplicStatus
IC_Insoluble
| Bool
otherwise = ImplicStatus
IC_Unsolved
; Implication -> TcRn ()
emitImplication (Implication -> TcRn ()) -> Implication -> TcRn ()
forall a b. (a -> b) -> a -> b
$
Implication
implic { ic_status :: ImplicStatus
ic_status = ImplicStatus
status
, 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 SkolemInfo
skol_info [Var]
skol_tvs [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 SkolemInfo
_ = Bool
False
buildImplicationFor :: TcLevel -> SkolemInfo -> [TcTyVar]
-> [EvVar] -> WantedConstraints
-> TcM (Bag Implication, TcEvBinds)
buildImplicationFor :: TcLevel
-> SkolemInfo
-> [Var]
-> [Var]
-> WantedConstraints
-> TcM (Bag Implication, TcEvBinds)
buildImplicationFor TcLevel
tclvl SkolemInfo
skol_info [Var]
skol_tvs [Var]
given 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 Maybe (HsExpr GhcRn)
thing TcType
ty1 TcType
ty2 = String -> SDoc -> TcRn ()
traceTc String
"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 Maybe (HsType GhcRn)
thing TcType
ty1 TcType
ty2 = String -> SDoc -> TcRn ()
traceTc String
"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 TypeOrKind
t_or_k CtOrigin
origin TcType
ty1 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 String
"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 String
"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 TypeOrKind
t_or_k CtOrigin
origin TcType
orig_ty1 TcType
orig_ty2
= do { TcLevel
tclvl <- TcM TcLevel
getTcLevel
; String -> SDoc -> TcRn ()
traceTc String
"u_tys" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
vcat
[ String -> SDoc
text String
"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 String
"~", 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 String
"u_tys yields no coercion" SDoc
Outputable.empty
else String -> SDoc -> TcRn ()
traceTc String
"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 TcType
t1 TcCoercionN
co1) 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 TcType
t1 (CastTy TcType
t2 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 Var
tv1) TcType
ty2
= do { LookupTyVarResult
lookup_res <- Var -> TcM LookupTyVarResult
lookupTcTyVar Var
tv1
; case LookupTyVarResult
lookup_res of
Filled TcType
ty1 -> do { String -> SDoc -> TcRn ()
traceTc String
"found filled tyvar" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv1 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
":->" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1)
; TcType -> TcType -> TcM TcCoercionN
go TcType
ty1 TcType
ty2 }
Unfilled TcTyVarDetails
_ -> CtOrigin
-> TypeOrKind -> SwapFlag -> Var -> TcType -> TcM TcCoercionN
uUnfilledVar CtOrigin
origin TypeOrKind
t_or_k SwapFlag
NotSwapped Var
tv1 TcType
ty2 }
go TcType
ty1 (TyVarTy Var
tv2)
= do { LookupTyVarResult
lookup_res <- Var -> TcM LookupTyVarResult
lookupTcTyVar Var
tv2
; case LookupTyVarResult
lookup_res of
Filled TcType
ty2 -> do { String -> SDoc -> TcRn ()
traceTc String
"found filled tyvar" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv2 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
":->" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2)
; TcType -> TcType -> TcM TcCoercionN
go TcType
ty1 TcType
ty2 }
Unfilled TcTyVarDetails
_ -> 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 TyCon
tc1 []) (TyConApp 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 TcType
ty1 TcType
ty2
| Just TcType
ty1' <- TcType -> Maybe TcType
tcView TcType
ty1 = TcType -> TcType -> TcM TcCoercionN
go TcType
ty1' TcType
ty2
| Just TcType
ty2' <- TcType -> Maybe TcType
tcView TcType
ty2 = TcType -> TcType -> TcM TcCoercionN
go TcType
ty1 TcType
ty2'
go (FunTy AnonArgFlag
_ TcType
fun1 TcType
arg1) (FunTy AnonArgFlag
_ TcType
fun2 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 TyCon
tc1 [TcType]
_) TcType
ty2
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc1 = TcType -> TcType -> TcM TcCoercionN
defer TcType
ty1 TcType
ty2
go TcType
ty1 ty2 :: TcType
ty2@(TyConApp TyCon
tc2 [TcType]
_)
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc2 = TcType -> TcType -> TcM TcCoercionN
defer TcType
ty1 TcType
ty2
go (TyConApp TyCon
tc1 [TcType]
tys1) (TyConApp TyCon
tc2 [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 (\Bool
is_vis -> if Bool
is_vis then CtOrigin
origin else CtOrigin -> CtOrigin
toInvisibleOrigin CtOrigin
origin)
(TyCon -> [Bool]
tcTyConVisibilities TyCon
tc1)
go (LitTy TyLit
m) ty :: TcType
ty@(LitTy 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 TcType
s1 TcType
t1) (AppTy TcType
s2 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 TcType
s1 TcType
t1) (TyConApp TyCon
tc2 [TcType]
ts2)
| Just ([TcType]
ts2', TcType
t2') <- [TcType] -> Maybe ([TcType], TcType)
forall a. [a] -> Maybe ([a], a)
snocView [TcType]
ts2
= ASSERT( not (mustBeSaturated 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 TyCon
tc1 [TcType]
ts1) (AppTy TcType
s2 TcType
t2)
| Just ([TcType]
ts1', TcType
t1') <- [TcType] -> Maybe ([TcType], TcType)
forall a. [a] -> Maybe ([a], a)
snocView [TcType]
ts1
= ASSERT( not (mustBeSaturated 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 TcCoercionN
co1) (CoercionTy 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 TcType
ty1 TcType
ty2 = TcType -> TcType -> TcM TcCoercionN
defer TcType
ty1 TcType
ty2
defer :: TcType -> TcType -> TcM TcCoercionN
defer TcType
ty1 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 Bool
vis TcType
s1 TcType
t1 TcType
s2 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 CtOrigin
origin TypeOrKind
t_or_k SwapFlag
swapped Var
tv1 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 CtOrigin
origin TypeOrKind
t_or_k SwapFlag
swapped Var
tv1 TcType
ty2
| Just 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 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
= do { Var
tv1 <- Var -> TcM Var
zonkTyCoVarKind Var
tv1
; 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 CtOrigin
origin TypeOrKind
t_or_k SwapFlag
swapped Var
tv1 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 DynFlags
dflags TcLevel
cur_lvl
| TcLevel -> Var -> TcType -> Bool
canSolveByUnification TcLevel
cur_lvl Var
tv1 TcType
ty2
, Just 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 String
"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 String
"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 Var
tv1 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 Var
tv
= ASSERT2( isTyVar tv, ppr tv)
case Var -> TcTyVarDetails
tcTyVarDetails Var
tv of
TcTyVarDetails
RuntimeUnk -> Arity
0
SkolemTv {} -> Arity
0
MetaTv { mtv_info :: TcTyVarDetails -> MetaInfo
mtv_info = MetaInfo
info } -> case MetaInfo
info of
MetaInfo
FlatSkolTv -> Arity
1
MetaInfo
TyVarTv -> Arity
2
MetaInfo
TauTv -> Arity
3
MetaInfo
FlatMetaTv -> Arity
4
canSolveByUnification :: TcLevel -> TcTyVar -> TcType -> Bool
canSolveByUnification :: TcLevel -> Var -> TcType -> Bool
canSolveByUnification TcLevel
tclvl Var
tv TcType
xi
| TcLevel -> Var -> Bool
isTouchableMetaTyVar TcLevel
tclvl Var
tv
= case Var -> MetaInfo
metaTyVarInfo Var
tv of
MetaInfo
TyVarTv -> TcType -> Bool
is_tyvar TcType
xi
MetaInfo
_ -> Bool
True
| Bool
otherwise
= Bool
False
where
is_tyvar :: TcType -> Bool
is_tyvar TcType
xi
= case TcType -> Maybe Var
tcGetTyVar_maybe TcType
xi of
Maybe Var
Nothing -> Bool
False
Just Var
tv -> case Var -> TcTyVarDetails
tcTyVarDetails Var
tv of
MetaTv { mtv_info :: TcTyVarDetails -> MetaInfo
mtv_info = MetaInfo
info }
-> case MetaInfo
info of
MetaInfo
TyVarTv -> Bool
True
MetaInfo
_ -> Bool
False
SkolemTv {} -> Bool
True
TcTyVarDetails
RuntimeUnk -> Bool
True
data LookupTyVarResult
= Unfilled TcTyVarDetails
| Filled TcType
lookupTcTyVar :: TcTyVar -> TcM LookupTyVarResult
lookupTcTyVar :: Var -> TcM LookupTyVarResult
lookupTcTyVar 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 TcType
ty -> LookupTyVarResult -> TcM LookupTyVarResult
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> LookupTyVarResult
Filled TcType
ty)
MetaDetails
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
-> Arity
-> TcKind
-> TcM Coercion
matchExpectedFunKind :: fun -> Arity -> TcType -> TcM TcCoercionN
matchExpectedFunKind fun
hs_ty Arity
n TcType
k = Arity -> TcType -> TcM TcCoercionN
go Arity
n TcType
k
where
go :: Arity -> TcType -> TcM TcCoercionN
go Arity
0 TcType
k = TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> TcCoercionN
mkNomReflCo TcType
k)
go Arity
n TcType
k | Just TcType
k' <- TcType -> Maybe TcType
tcView TcType
k = Arity -> TcType -> TcM TcCoercionN
go Arity
n TcType
k'
go Arity
n k :: TcType
k@(TyVarTy Var
kvar)
| Var -> Bool
isMetaTyVar Var
kvar
= do { MetaDetails
maybe_kind <- Var -> TcM MetaDetails
readMetaTyVar Var
kvar
; case MetaDetails
maybe_kind of
Indirect TcType
fun_kind -> Arity -> TcType -> TcM TcCoercionN
go Arity
n TcType
fun_kind
MetaDetails
Flexi -> Arity -> TcType -> TcM TcCoercionN
defer Arity
n TcType
k }
go Arity
n (FunTy AnonArgFlag
_ TcType
arg TcType
res)
= do { TcCoercionN
co <- Arity -> TcType -> TcM TcCoercionN
go (Arity
nArity -> Arity -> Arity
forall a. Num a => a -> a -> a
-Arity
1) TcType
res
; TcCoercionN -> TcM TcCoercionN
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcCoercionN -> TcCoercionN -> TcCoercionN
mkTcFunCo Role
Nominal (TcType -> TcCoercionN
mkTcNomReflCo TcType
arg) TcCoercionN
co) }
go Arity
n TcType
other
= Arity -> TcType -> TcM TcCoercionN
defer Arity
n TcType
other
defer :: Arity -> TcType -> TcM TcCoercionN
defer Arity
n TcType
k
= do { [TcType]
arg_kinds <- Arity -> IOEnv (Env TcGblEnv TcLclEnv) [TcType]
newMetaKindVars Arity
n
; TcType
res_kind <- IOEnv (Env TcGblEnv TcLclEnv) TcType
newMetaKindVar
; let new_fun :: TcType
new_fun = [TcType] -> TcType -> TcType
mkVisFunTys [TcType]
arg_kinds 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
}
; TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM TcCoercionN
uType TypeOrKind
KindLevel CtOrigin
origin TcType
k TcType
new_fun }
data MetaTyVarUpdateResult a
= MTVU_OK a
| MTVU_Bad
| MTVU_Occurs
deriving (a -> MetaTyVarUpdateResult b -> MetaTyVarUpdateResult a
(a -> b) -> MetaTyVarUpdateResult a -> MetaTyVarUpdateResult b
(forall a b.
(a -> b) -> MetaTyVarUpdateResult a -> MetaTyVarUpdateResult b)
-> (forall a b.
a -> MetaTyVarUpdateResult b -> MetaTyVarUpdateResult a)
-> Functor MetaTyVarUpdateResult
forall a b. a -> MetaTyVarUpdateResult b -> MetaTyVarUpdateResult a
forall a b.
(a -> b) -> MetaTyVarUpdateResult a -> MetaTyVarUpdateResult b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> MetaTyVarUpdateResult b -> MetaTyVarUpdateResult a
$c<$ :: forall a b. a -> MetaTyVarUpdateResult b -> MetaTyVarUpdateResult a
fmap :: (a -> b) -> MetaTyVarUpdateResult a -> MetaTyVarUpdateResult b
$cfmap :: forall a b.
(a -> b) -> MetaTyVarUpdateResult a -> MetaTyVarUpdateResult b
Functor)
instance Applicative MetaTyVarUpdateResult where
pure :: a -> MetaTyVarUpdateResult a
pure = a -> MetaTyVarUpdateResult a
forall a. a -> MetaTyVarUpdateResult a
MTVU_OK
<*> :: MetaTyVarUpdateResult (a -> b)
-> MetaTyVarUpdateResult a -> MetaTyVarUpdateResult b
(<*>) = MetaTyVarUpdateResult (a -> b)
-> MetaTyVarUpdateResult a -> MetaTyVarUpdateResult b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad MetaTyVarUpdateResult where
MTVU_OK a
x >>= :: MetaTyVarUpdateResult a
-> (a -> MetaTyVarUpdateResult b) -> MetaTyVarUpdateResult b
>>= a -> MetaTyVarUpdateResult b
k = a -> MetaTyVarUpdateResult b
k a
x
MetaTyVarUpdateResult a
MTVU_Bad >>= a -> MetaTyVarUpdateResult b
_ = MetaTyVarUpdateResult b
forall a. MetaTyVarUpdateResult a
MTVU_Bad
MetaTyVarUpdateResult a
MTVU_Occurs >>= a -> MetaTyVarUpdateResult b
_ = MetaTyVarUpdateResult b
forall a. MetaTyVarUpdateResult a
MTVU_Occurs
occCheckForErrors :: DynFlags -> TcTyVar -> Type -> MetaTyVarUpdateResult ()
occCheckForErrors :: DynFlags -> Var -> TcType -> MetaTyVarUpdateResult ()
occCheckForErrors DynFlags
dflags Var
tv TcType
ty
= case DynFlags -> Bool -> Var -> TcType -> MetaTyVarUpdateResult ()
preCheck DynFlags
dflags Bool
True Var
tv TcType
ty of
MTVU_OK ()
_ -> () -> MetaTyVarUpdateResult ()
forall a. a -> MetaTyVarUpdateResult a
MTVU_OK ()
MetaTyVarUpdateResult ()
MTVU_Bad -> MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Bad
MetaTyVarUpdateResult ()
MTVU_Occurs -> case [Var] -> TcType -> Maybe TcType
occCheckExpand [Var
tv] TcType
ty of
Maybe TcType
Nothing -> MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Occurs
Just TcType
_ -> () -> MetaTyVarUpdateResult ()
forall a. a -> MetaTyVarUpdateResult a
MTVU_OK ()
metaTyVarUpdateOK :: DynFlags
-> TcTyVar
-> TcType
-> Maybe TcType
metaTyVarUpdateOK :: DynFlags -> Var -> TcType -> Maybe TcType
metaTyVarUpdateOK DynFlags
dflags Var
tv TcType
ty
= case DynFlags -> Bool -> Var -> TcType -> MetaTyVarUpdateResult ()
preCheck DynFlags
dflags Bool
False Var
tv TcType
ty of
MTVU_OK ()
_ -> TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
ty
MetaTyVarUpdateResult ()
MTVU_Bad -> Maybe TcType
forall a. Maybe a
Nothing
MetaTyVarUpdateResult ()
MTVU_Occurs -> [Var] -> TcType -> Maybe TcType
occCheckExpand [Var
tv] TcType
ty
preCheck :: DynFlags -> Bool -> TcTyVar -> TcType -> MetaTyVarUpdateResult ()
preCheck :: DynFlags -> Bool -> Var -> TcType -> MetaTyVarUpdateResult ()
preCheck DynFlags
dflags Bool
ty_fam_ok Var
tv TcType
ty
= TcType -> MetaTyVarUpdateResult ()
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 :: MetaTyVarUpdateResult ()
ok :: MetaTyVarUpdateResult ()
ok = () -> MetaTyVarUpdateResult ()
forall a. a -> MetaTyVarUpdateResult a
MTVU_OK ()
fast_check :: TcType -> MetaTyVarUpdateResult ()
fast_check :: TcType -> MetaTyVarUpdateResult ()
fast_check (TyVarTy Var
tv')
| Var
tv Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
tv' = MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Occurs
| Bool
otherwise = TcType -> MetaTyVarUpdateResult ()
fast_check_occ (Var -> TcType
tyVarKind Var
tv')
fast_check (TyConApp TyCon
tc [TcType]
tys)
| TyCon -> Bool
bad_tc TyCon
tc = MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Bad
| Bool
otherwise = (TcType -> MetaTyVarUpdateResult ())
-> [TcType] -> MetaTyVarUpdateResult [()]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM TcType -> MetaTyVarUpdateResult ()
fast_check [TcType]
tys MetaTyVarUpdateResult [()]
-> MetaTyVarUpdateResult () -> MetaTyVarUpdateResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MetaTyVarUpdateResult ()
ok
fast_check (LitTy {}) = MetaTyVarUpdateResult ()
ok
fast_check (FunTy{ft_af :: TcType -> AnonArgFlag
ft_af = AnonArgFlag
af, ft_arg :: TcType -> TcType
ft_arg = TcType
a, ft_res :: TcType -> TcType
ft_res = TcType
r})
| AnonArgFlag
InvisArg <- AnonArgFlag
af
, Bool -> Bool
not Bool
impredicative_ok = MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Bad
| Bool
otherwise = TcType -> MetaTyVarUpdateResult ()
fast_check TcType
a MetaTyVarUpdateResult ()
-> MetaTyVarUpdateResult () -> MetaTyVarUpdateResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TcType -> MetaTyVarUpdateResult ()
fast_check TcType
r
fast_check (AppTy TcType
fun TcType
arg) = TcType -> MetaTyVarUpdateResult ()
fast_check TcType
fun MetaTyVarUpdateResult ()
-> MetaTyVarUpdateResult () -> MetaTyVarUpdateResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TcType -> MetaTyVarUpdateResult ()
fast_check TcType
arg
fast_check (CastTy TcType
ty TcCoercionN
co) = TcType -> MetaTyVarUpdateResult ()
fast_check TcType
ty MetaTyVarUpdateResult ()
-> MetaTyVarUpdateResult () -> MetaTyVarUpdateResult ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TcCoercionN -> MetaTyVarUpdateResult ()
fast_check_co TcCoercionN
co
fast_check (CoercionTy TcCoercionN
co) = TcCoercionN -> MetaTyVarUpdateResult ()
fast_check_co TcCoercionN
co
fast_check (ForAllTy (Bndr Var
tv' ArgFlag
_) TcType
ty)
| Bool -> Bool
not Bool
impredicative_ok = MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Bad
| Var
tv Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
tv' = MetaTyVarUpdateResult ()
ok
| Bool
otherwise = do { TcType -> MetaTyVarUpdateResult ()
fast_check_occ (Var -> TcType
tyVarKind Var
tv')
; TcType -> MetaTyVarUpdateResult ()
fast_check_occ TcType
ty }
fast_check_occ :: TcType -> MetaTyVarUpdateResult ()
fast_check_occ TcType
k | Var
tv Var -> VarSet -> Bool
`elemVarSet` TcType -> VarSet
tyCoVarsOfType TcType
k = MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Occurs
| Bool
otherwise = MetaTyVarUpdateResult ()
ok
fast_check_co :: TcCoercionN -> MetaTyVarUpdateResult ()
fast_check_co TcCoercionN
co | Var
tv Var -> VarSet -> Bool
`elemVarSet` TcCoercionN -> VarSet
tyCoVarsOfCo TcCoercionN
co = MetaTyVarUpdateResult ()
forall a. MetaTyVarUpdateResult a
MTVU_Occurs
| Bool
otherwise = MetaTyVarUpdateResult ()
ok
bad_tc :: TyCon -> Bool
bad_tc :: TyCon -> Bool
bad_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 DynFlags
dflags 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
TcTyVarDetails
_other -> Bool
True