module TcHsType (
tcHsSigType, tcHsSigTypeNC, tcHsDeriv, tcHsVectInst,
tcHsInstHead,
UserTypeCtxt(..),
kcLookupKind, kcTyClTyVars, tcTyClTyVars,
tcHsConArgType, tcDataKindSig,
tcClassSigType,
kcHsTyVarBndrs, tcHsTyVarBndrs,
tcHsLiftedType, tcHsOpenType,
tcLHsType, tcCheckLHsType,
tcHsContext, tcInferApps, tcHsArgTys,
kindGeneralize, checkKind,
tcLHsKind,
tcHsPatSigType, tcPatSig
) where
#include "HsVersions.h"
import HsSyn
import TcRnMonad
import TcEvidence( HsWrapper )
import TcEnv
import TcMType
import TcValidity
import TcUnify
import TcIface
import TcType
import Type
import TypeRep( Type(..) )
import Kind
import RdrName( lookupLocalRdrOcc )
import Var
import VarSet
import TyCon
import ConLike
import DataCon
import TysPrim ( liftedTypeKindTyConName, constraintKindTyConName )
import Class
import Name
import NameEnv
import TysWiredIn
import BasicTypes
import SrcLoc
import DynFlags ( ExtensionFlag( Opt_DataKinds ), getDynFlags )
import Unique
import UniqSupply
import Outputable
import FastString
import Util
import Data.Maybe( isNothing )
import Control.Monad ( unless, when, zipWithM )
import PrelNames( ipClassName, funTyConKey, allNameStrings )
tcHsSigType, tcHsSigTypeNC :: UserTypeCtxt -> LHsType Name -> TcM Type
tcHsSigType ctxt hs_ty
= addErrCtxt (pprSigCtxt ctxt empty (ppr hs_ty)) $
tcHsSigTypeNC ctxt hs_ty
tcHsSigTypeNC ctxt (L loc hs_ty)
= setSrcSpan loc $
do { kind <- case expectedKindInCtxt ctxt of
Nothing -> newMetaKindVar
Just k -> return k
; ty <- tcCheckHsTypeAndGen hs_ty kind
; ty <- zonkSigType ty
; checkValidType ctxt ty
; return ty }
tcHsInstHead :: UserTypeCtxt -> LHsType Name -> TcM ([TyVar], ThetaType, Class, [Type])
tcHsInstHead user_ctxt lhs_ty@(L loc hs_ty)
= setSrcSpan loc $
do { inst_ty <- tc_inst_head hs_ty
; kvs <- zonkTcTypeAndFV inst_ty
; kvs <- kindGeneralize kvs
; inst_ty <- zonkSigType (mkForAllTys kvs inst_ty)
; checkValidInstance user_ctxt lhs_ty inst_ty }
tc_inst_head :: HsType Name -> TcM TcType
tc_inst_head (HsForAllTy _ _ hs_tvs hs_ctxt hs_ty)
= tcHsTyVarBndrs hs_tvs $ \ tvs ->
do { ctxt <- tcHsContext hs_ctxt
; ty <- tc_lhs_type hs_ty ekConstraint
; return (mkSigmaTy tvs ctxt ty) }
tc_inst_head hs_ty
= tc_hs_type hs_ty ekConstraint
tcHsDeriv :: HsType Name -> TcM ([TyVar], Class, [Type], Kind)
tcHsDeriv hs_ty
= do { arg_kind <- newMetaKindVar
; ty <- tcCheckHsTypeAndGen hs_ty (mkArrowKind arg_kind constraintKind)
; ty <- zonkSigType ty
; arg_kind <- zonkSigType arg_kind
; let (tvs, pred) = splitForAllTys ty
; case getClassPredTys_maybe pred of
Just (cls, tys) -> return (tvs, cls, tys, arg_kind)
Nothing -> failWithTc (ptext (sLit "Illegal deriving item") <+> quotes (ppr hs_ty)) }
tcHsVectInst :: LHsType Name -> TcM (Class, [Type])
tcHsVectInst ty
| Just (L _ cls_name, tys) <- splitLHsClassTy_maybe ty
= do { (cls, cls_kind) <- tcClass cls_name
; (arg_tys, _res_kind) <- tcInferApps cls_name cls_kind tys
; return (cls, arg_tys) }
| otherwise
= failWithTc $ ptext (sLit "Malformed instance type")
tcClassSigType :: LHsType Name -> TcM Type
tcClassSigType lhs_ty@(L _ hs_ty)
= addTypeCtxt lhs_ty $
do { ty <- tcCheckHsTypeAndGen hs_ty liftedTypeKind
; zonkSigType ty }
tcHsConArgType :: NewOrData -> LHsType Name -> TcM Type
tcHsConArgType NewType bty = tcHsLiftedType (getBangType bty)
tcHsConArgType DataType bty = tcHsOpenType (getBangType bty)
tcHsArgTys :: SDoc -> [LHsType Name] -> [Kind] -> TcM [TcType]
tcHsArgTys what tys kinds
= sequence [ addTypeCtxt ty $
tc_lhs_type ty (expArgKind what kind n)
| (ty,kind,n) <- zip3 tys kinds [1..] ]
tc_hs_arg_tys :: SDoc -> [LHsType Name] -> [Kind] -> TcM [TcType]
tc_hs_arg_tys what tys kinds
= sequence [ tc_lhs_type ty (expArgKind what kind n)
| (ty,kind,n) <- zip3 tys kinds [1..] ]
tcHsOpenType, tcHsLiftedType :: LHsType Name -> TcM TcType
tcHsOpenType ty = addTypeCtxt ty $ tc_lhs_type ty ekOpen
tcHsLiftedType ty = addTypeCtxt ty $ tc_lhs_type ty ekLifted
tcCheckLHsType :: LHsType Name -> Kind -> TcM Type
tcCheckLHsType hs_ty exp_kind
= addTypeCtxt hs_ty $
tc_lhs_type hs_ty (EK exp_kind expectedKindMsg)
tcLHsType :: LHsType Name -> TcM (TcType, TcKind)
tcLHsType ty = addTypeCtxt ty (tc_infer_lhs_type ty)
tcCheckHsTypeAndGen :: HsType Name -> Kind -> TcM Type
tcCheckHsTypeAndGen hs_ty kind
= do { ty <- tc_hs_type hs_ty (EK kind expectedKindMsg)
; traceTc "tcCheckHsTypeAndGen" (ppr hs_ty)
; kvs <- zonkTcTypeAndFV ty
; kvs <- kindGeneralize kvs
; return (mkForAllTys kvs ty) }
tc_infer_lhs_type :: LHsType Name -> TcM (TcType, TcKind)
tc_infer_lhs_type ty =
do { kv <- newMetaKindVar
; r <- tc_lhs_type ty (EK kv expectedKindMsg)
; return (r, kv) }
tc_lhs_type :: LHsType Name -> ExpKind -> TcM TcType
tc_lhs_type (L span ty) exp_kind
= setSrcSpan span $
do { traceTc "tc_lhs_type:" (ppr ty $$ ppr exp_kind)
; tc_hs_type ty exp_kind }
tc_lhs_types :: [(LHsType Name, ExpKind)] -> TcM [TcType]
tc_lhs_types tys_w_kinds = mapM (uncurry tc_lhs_type) tys_w_kinds
tc_fun_type :: HsType Name -> LHsType Name -> LHsType Name -> ExpKind -> TcM TcType
tc_fun_type ty ty1 ty2 exp_kind@(EK _ ctxt)
= do { ty1' <- tc_lhs_type ty1 (EK openTypeKind ctxt)
; ty2' <- tc_lhs_type ty2 (EK openTypeKind ctxt)
; checkExpectedKind ty liftedTypeKind exp_kind
; return (mkFunTy ty1' ty2') }
tc_hs_type :: HsType Name -> ExpKind -> TcM TcType
tc_hs_type (HsParTy ty) exp_kind = tc_lhs_type ty exp_kind
tc_hs_type (HsDocTy ty _) exp_kind = tc_lhs_type ty exp_kind
tc_hs_type (HsQuasiQuoteTy {}) _ = panic "tc_hs_type: qq"
tc_hs_type ty@(HsBangTy {}) _
= failWithTc (ptext (sLit "Unexpected strictness annotation:") <+> ppr ty)
tc_hs_type (HsRecTy _) _ = panic "tc_hs_type: record"
tc_hs_type hs_ty@(HsTyVar name) exp_kind
= do { (ty, k) <- tcTyVar name
; checkExpectedKind hs_ty k exp_kind
; return ty }
tc_hs_type ty@(HsFunTy ty1 ty2) exp_kind
= tc_fun_type ty ty1 ty2 exp_kind
tc_hs_type hs_ty@(HsOpTy ty1 (_, l_op@(L _ op)) ty2) exp_kind
| op `hasKey` funTyConKey
= tc_fun_type hs_ty ty1 ty2 exp_kind
| otherwise
= do { (op', op_kind) <- tcTyVar op
; tys' <- tcCheckApps hs_ty l_op op_kind [ty1,ty2] exp_kind
; return (mkNakedAppTys op' tys') }
tc_hs_type hs_ty@(HsAppTy ty1 ty2) exp_kind
= do { (fun_ty', fun_kind) <- tc_infer_lhs_type fun_ty
; arg_tys' <- tcCheckApps hs_ty fun_ty fun_kind arg_tys exp_kind
; return (mkNakedAppTys fun_ty' arg_tys') }
where
(fun_ty, arg_tys) = splitHsAppTys ty1 [ty2]
tc_hs_type hs_ty@(HsForAllTy _ _ hs_tvs context ty) exp_kind@(EK exp_k _)
| isConstraintKind exp_k
= failWithTc (hang (ptext (sLit "Illegal constraint:")) 2 (ppr hs_ty))
| otherwise
= tcHsTyVarBndrs hs_tvs $ \ tvs' ->
do { ctxt' <- tcHsContext context
; ty' <- if null (unLoc context) then
tc_lhs_type ty exp_kind
else
do { checkExpectedKind hs_ty liftedTypeKind exp_kind
; tc_lhs_type ty ekOpen }
; return (mkSigmaTy tvs' ctxt' ty') }
tc_hs_type hs_ty@(HsListTy elt_ty) exp_kind
= do { tau_ty <- tc_lhs_type elt_ty ekLifted
; checkExpectedKind hs_ty liftedTypeKind exp_kind
; checkWiredInTyCon listTyCon
; return (mkListTy tau_ty) }
tc_hs_type hs_ty@(HsPArrTy elt_ty) exp_kind
= do { tau_ty <- tc_lhs_type elt_ty ekLifted
; checkExpectedKind hs_ty liftedTypeKind exp_kind
; checkWiredInTyCon parrTyCon
; return (mkPArrTy tau_ty) }
tc_hs_type hs_ty@(HsTupleTy HsBoxedOrConstraintTuple hs_tys) exp_kind@(EK exp_k _ctxt)
| Just tup_sort <- tupKindSort_maybe exp_k
= traceTc "tc_hs_type tuple" (ppr hs_tys) >>
tc_tuple hs_ty tup_sort hs_tys exp_kind
| otherwise
= do { traceTc "tc_hs_type tuple 2" (ppr hs_tys)
; (tys, kinds) <- mapAndUnzipM tc_infer_lhs_type hs_tys
; kinds <- mapM zonkTcKind kinds
; let (arg_kind, tup_sort)
= case [ (k,s) | k <- kinds
, Just s <- [tupKindSort_maybe k] ] of
((k,s) : _) -> (k,s)
[] -> (liftedTypeKind, BoxedTuple)
; sequence_ [ setSrcSpan loc $
checkExpectedKind ty kind
(expArgKind (ptext (sLit "a tuple")) arg_kind n)
| (ty@(L loc _),kind,n) <- zip3 hs_tys kinds [1..] ]
; finish_tuple hs_ty tup_sort tys exp_kind }
tc_hs_type hs_ty@(HsTupleTy hs_tup_sort tys) exp_kind
= tc_tuple hs_ty tup_sort tys exp_kind
where
tup_sort = case hs_tup_sort of
HsUnboxedTuple -> UnboxedTuple
HsBoxedTuple -> BoxedTuple
HsConstraintTuple -> ConstraintTuple
_ -> panic "tc_hs_type HsTupleTy"
tc_hs_type hs_ty@(HsExplicitListTy _k tys) exp_kind
= do { tks <- mapM tc_infer_lhs_type tys
; let taus = map fst tks
; kind <- unifyKinds (ptext (sLit "In a promoted list")) tks
; checkExpectedKind hs_ty (mkPromotedListTy kind) exp_kind
; return (foldr (mk_cons kind) (mk_nil kind) taus) }
where
mk_cons k a b = mkTyConApp (promoteDataCon consDataCon) [k, a, b]
mk_nil k = mkTyConApp (promoteDataCon nilDataCon) [k]
tc_hs_type hs_ty@(HsExplicitTupleTy _ tys) exp_kind
= do { tks <- mapM tc_infer_lhs_type tys
; let n = length tys
kind_con = promotedTupleTyCon BoxedTuple n
ty_con = promotedTupleDataCon BoxedTuple n
(taus, ks) = unzip tks
tup_k = mkTyConApp kind_con ks
; checkExpectedKind hs_ty tup_k exp_kind
; return (mkTyConApp ty_con (ks ++ taus)) }
tc_hs_type ipTy@(HsIParamTy n ty) exp_kind
= do { ty' <- tc_lhs_type ty ekLifted
; checkExpectedKind ipTy constraintKind exp_kind
; ipClass <- tcLookupClass ipClassName
; let n' = mkStrLitTy $ hsIPNameFS n
; return (mkClassPred ipClass [n',ty'])
}
tc_hs_type ty@(HsEqTy ty1 ty2) exp_kind
= do { (ty1', kind1) <- tc_infer_lhs_type ty1
; (ty2', kind2) <- tc_infer_lhs_type ty2
; checkExpectedKind ty2 kind2
(EK kind1 msg_fn)
; checkExpectedKind ty constraintKind exp_kind
; return (mkNakedTyConApp eqTyCon [kind1, ty1', ty2']) }
where
msg_fn pkind = ptext (sLit "The left argument of the equality had kind")
<+> quotes (pprKind pkind)
tc_hs_type (HsKindSig ty sig_k) exp_kind
= do { sig_k' <- tcLHsKind sig_k
; checkExpectedKind ty sig_k' exp_kind
; tc_lhs_type ty (EK sig_k' msg_fn) }
where
msg_fn pkind = ptext (sLit "The signature specified kind")
<+> quotes (pprKind pkind)
tc_hs_type (HsCoreTy ty) exp_kind
= do { checkExpectedKind ty (typeKind ty) exp_kind
; return ty }
tc_hs_type ty@(HsSpliceTy {}) _exp_kind
= failWithTc (ptext (sLit "Unexpected type splice:") <+> ppr ty)
tc_hs_type (HsWrapTy {}) _exp_kind
= panic "tc_hs_type HsWrapTy"
tc_hs_type hs_ty@(HsTyLit (HsNumTy _ n)) exp_kind
= do { checkExpectedKind hs_ty typeNatKind exp_kind
; checkWiredInTyCon typeNatKindCon
; return (mkNumLitTy n) }
tc_hs_type hs_ty@(HsTyLit (HsStrTy _ s)) exp_kind
= do { checkExpectedKind hs_ty typeSymbolKind exp_kind
; checkWiredInTyCon typeSymbolKindCon
; return (mkStrLitTy s) }
tc_hs_type HsWildcardTy _ = panic "tc_hs_type HsWildcardTy"
tc_hs_type hs_ty@(HsNamedWildcardTy name) exp_kind
= do { (ty, k) <- tcTyVar name
; checkExpectedKind hs_ty k exp_kind
; return ty }
tupKindSort_maybe :: TcKind -> Maybe TupleSort
tupKindSort_maybe k
| isConstraintKind k = Just ConstraintTuple
| isLiftedTypeKind k = Just BoxedTuple
| otherwise = Nothing
tc_tuple :: HsType Name -> TupleSort -> [LHsType Name] -> ExpKind -> TcM TcType
tc_tuple hs_ty tup_sort tys exp_kind
= do { tau_tys <- tc_hs_arg_tys cxt_doc tys (repeat arg_kind)
; finish_tuple hs_ty tup_sort tau_tys exp_kind }
where
arg_kind = case tup_sort of
BoxedTuple -> liftedTypeKind
UnboxedTuple -> openTypeKind
ConstraintTuple -> constraintKind
cxt_doc = case tup_sort of
BoxedTuple -> ptext (sLit "a tuple")
UnboxedTuple -> ptext (sLit "an unboxed tuple")
ConstraintTuple -> ptext (sLit "a constraint tuple")
finish_tuple :: HsType Name -> TupleSort -> [TcType] -> ExpKind -> TcM TcType
finish_tuple hs_ty tup_sort tau_tys exp_kind
= do { traceTc "finish_tuple" (ppr res_kind $$ ppr exp_kind $$ ppr exp_kind)
; checkExpectedKind hs_ty res_kind exp_kind
; checkWiredInTyCon tycon
; return (mkTyConApp tycon tau_tys) }
where
tycon = tupleTyCon tup_sort (length tau_tys)
res_kind = case tup_sort of
UnboxedTuple -> unliftedTypeKind
BoxedTuple -> liftedTypeKind
ConstraintTuple -> constraintKind
tcInferApps :: Outputable a
=> a
-> TcKind
-> [LHsType Name]
-> TcM ([TcType], TcKind)
tcInferApps the_fun fun_kind args
= do { (args_w_kinds, res_kind) <- splitFunKind (ppr the_fun) fun_kind args
; args' <- tc_lhs_types args_w_kinds
; return (args', res_kind) }
tcCheckApps :: Outputable a
=> HsType Name
-> a
-> TcKind -> [LHsType Name]
-> ExpKind
-> TcM [TcType]
tcCheckApps hs_ty the_fun fun_kind args exp_kind
= do { (arg_tys, res_kind) <- tcInferApps the_fun fun_kind args
; checkExpectedKind hs_ty res_kind exp_kind
; return arg_tys }
splitFunKind :: SDoc -> TcKind -> [b] -> TcM ([(b,ExpKind)], TcKind)
splitFunKind the_fun fun_kind args
= go 1 fun_kind args
where
go _ fk [] = return ([], fk)
go arg_no fk (arg:args)
= do { mb_fk <- matchExpectedFunKind fk
; case mb_fk of
Nothing -> failWithTc too_many_args
Just (ak,fk') -> do { (aks, rk) <- go (arg_no+1) fk' args
; let exp_kind = expArgKind (quotes the_fun) ak arg_no
; return ((arg, exp_kind) : aks, rk) } }
too_many_args = quotes the_fun <+>
ptext (sLit "is applied to too many type arguments")
tcHsContext :: LHsContext Name -> TcM [PredType]
tcHsContext ctxt = mapM tcHsLPredType (unLoc ctxt)
tcHsLPredType :: LHsType Name -> TcM PredType
tcHsLPredType pred = tc_lhs_type pred ekConstraint
tcTyVar :: Name -> TcM (TcType, TcKind)
tcTyVar name
= do { traceTc "lk1" (ppr name)
; thing <- tcLookup name
; case thing of
ATyVar _ tv
| isKindVar tv
-> failWithTc (ptext (sLit "Kind variable") <+> quotes (ppr tv)
<+> ptext (sLit "used as a type"))
| otherwise
-> return (mkTyVarTy tv, tyVarKind tv)
AThing kind -> do { tc <- get_loopy_tc name
; inst_tycon (mkNakedTyConApp tc) kind }
AGlobal (ATyCon tc) -> inst_tycon (mkTyConApp tc) (tyConKind tc)
AGlobal (AConLike (RealDataCon dc))
| Just tc <- promoteDataCon_maybe dc
-> do { data_kinds <- xoptM Opt_DataKinds
; unless data_kinds $ promotionErr name NoDataKinds
; inst_tycon (mkTyConApp tc) (tyConKind tc) }
| otherwise -> failWithTc (ptext (sLit "Data constructor") <+> quotes (ppr dc)
<+> ptext (sLit "comes from an un-promotable type")
<+> quotes (ppr (dataConTyCon dc)))
APromotionErr err -> promotionErr name err
_ -> wrongThingErr "type" thing name }
where
get_loopy_tc name
= do { env <- getGblEnv
; case lookupNameEnv (tcg_type_env env) name of
Just (ATyCon tc) -> return tc
_ -> return (aThingErr "tcTyVar" name) }
inst_tycon :: ([Type] -> Type) -> Kind -> TcM (Type, Kind)
inst_tycon mk_tc_app kind
| null kvs
= return (mk_tc_app [], ki_body)
| otherwise
= do { traceTc "lk4" (ppr name <+> dcolon <+> ppr kind)
; ks <- mapM (const newMetaKindVar) kvs
; return (mk_tc_app ks, substKiWith kvs ks ki_body) }
where
(kvs, ki_body) = splitForAllTys kind
tcClass :: Name -> TcM (Class, TcKind)
tcClass cls
= do { thing <- tcLookup cls
; case thing of
AThing kind -> return (aThingErr "tcClass" cls, kind)
AGlobal (ATyCon tc)
| Just cls <- tyConClass_maybe tc
-> return (cls, tyConKind tc)
_ -> wrongThingErr "class" thing cls }
aThingErr :: String -> Name -> b
aThingErr str x = pprPanic "AThing evaluated unexpectedly" (text str <+> ppr x)
mkNakedTyConApp :: TyCon -> [Type] -> Type
mkNakedTyConApp tc tys = TyConApp tc tys
mkNakedAppTys :: Type -> [Type] -> Type
mkNakedAppTys ty1 [] = ty1
mkNakedAppTys (TyConApp tc tys1) tys2 = mkNakedTyConApp tc (tys1 ++ tys2)
mkNakedAppTys ty1 tys2 = foldl AppTy ty1 tys2
zonkSigType :: TcType -> TcM TcType
zonkSigType ty
= go ty
where
go (TyConApp tc tys) = do tys' <- mapM go tys
return (mkTyConApp tc tys')
go (LitTy n) = return (LitTy n)
go (FunTy arg res) = do arg' <- go arg
res' <- go res
return (FunTy arg' res')
go (AppTy fun arg) = do fun' <- go fun
arg' <- go arg
return (mkAppTy fun' arg')
go (TyVarTy tyvar) | isTcTyVar tyvar = zonkTcTyVar tyvar
| otherwise = TyVarTy <$> updateTyVarKindM go tyvar
go (ForAllTy tv ty) = do { tv' <- zonkTcTyVarBndr tv
; ty' <- go ty
; return (ForAllTy tv' ty') }
addTypeCtxt :: LHsType Name -> TcM a -> TcM a
addTypeCtxt (L _ ty) thing
= addErrCtxt doc thing
where
doc = ptext (sLit "In the type") <+> quotes (ppr ty)
mkKindSigVar :: Name -> TcM KindVar
mkKindSigVar n
= do { mb_thing <- tcLookupLcl_maybe n
; case mb_thing of
Just (AThing k)
| Just kvar <- getTyVar_maybe k
-> return kvar
_ -> return $ mkTcTyVar n superKind (SkolemTv False) }
kcScopedKindVars :: [Name] -> TcM a -> TcM a
kcScopedKindVars kv_ns thing_inside
= do { kvs <- mapM (\n -> newSigTyVar n superKind) kv_ns
; tcExtendTyVarEnv2 (kv_ns `zip` kvs) thing_inside }
kcHsTyVarBndrs :: Bool
-> LHsTyVarBndrs Name
-> TcM (Kind, r)
-> TcM (Kind, r)
kcHsTyVarBndrs cusk (HsQTvs { hsq_kvs = kv_ns, hsq_tvs = hs_tvs }) thing_inside
= do { kvs <- if cusk
then mapM mkKindSigVar kv_ns
else mapM (\n -> newSigTyVar n superKind) kv_ns
; tcExtendTyVarEnv2 (kv_ns `zip` kvs) $
do { nks <- mapM (kc_hs_tv . unLoc) hs_tvs
; (res_kind, stuff) <- tcExtendKindEnv nks thing_inside
; let full_kind = mkArrowKinds (map snd nks) res_kind
kvs = filter (not . isMetaTyVar) $
varSetElems $ tyVarsOfType full_kind
gen_kind = if cusk
then mkForAllTys kvs full_kind
else full_kind
; return (gen_kind, stuff) } }
where
kc_hs_tv :: HsTyVarBndr Name -> TcM (Name, TcKind)
kc_hs_tv (UserTyVar n)
= do { mb_thing <- tcLookupLcl_maybe n
; kind <- case mb_thing of
Just (AThing k) -> return k
_ | cusk -> return liftedTypeKind
| otherwise -> newMetaKindVar
; return (n, kind) }
kc_hs_tv (KindedTyVar (L _ n) k)
= do { kind <- tcLHsKind k
; mb_thing <- tcLookupLcl_maybe n
; case mb_thing of
Nothing -> return ()
Just (AThing ks) -> checkKind kind ks
Just thing -> pprPanic "check_in_scope" (ppr thing)
; return (n, kind) }
tcHsTyVarBndrs :: LHsTyVarBndrs Name
-> ([TcTyVar] -> TcM r)
-> TcM r
tcHsTyVarBndrs (HsQTvs { hsq_kvs = kv_ns, hsq_tvs = hs_tvs }) thing_inside
= do { kvs <- mapM mkKindSigVar kv_ns
; tcExtendTyVarEnv kvs $ do
{ tvs <- mapM tcHsTyVarBndr hs_tvs
; traceTc "tcHsTyVarBndrs {" (vcat [ text "Hs kind vars:" <+> ppr kv_ns
, text "Hs type vars:" <+> ppr hs_tvs
, text "Kind vars:" <+> ppr kvs
, text "Type vars:" <+> ppr tvs ])
; res <- tcExtendTyVarEnv tvs (thing_inside (kvs ++ tvs))
; traceTc "tcHsTyVarBndrs }" (vcat [ text "Hs kind vars:" <+> ppr kv_ns
, text "Hs type vars:" <+> ppr hs_tvs
, text "Kind vars:" <+> ppr kvs
, text "Type vars:" <+> ppr tvs ])
; return res } }
tcHsTyVarBndr :: LHsTyVarBndr Name -> TcM TcTyVar
tcHsTyVarBndr (L _ hs_tv)
= do { let name = hsTyVarName hs_tv
; mb_tv <- tcLookupLcl_maybe name
; case mb_tv of {
Just (ATyVar _ tv) -> return tv ;
_ -> do
{ kind <- case hs_tv of
UserTyVar {} -> newMetaKindVar
KindedTyVar _ kind -> tcLHsKind kind
; return ( mkTcTyVar name kind (SkolemTv False)) } } }
kindGeneralize :: TyVarSet -> TcM [KindVar]
kindGeneralize tkvs
= do { gbl_tvs <- tcGetGlobalTyVars
; quantifyTyVars gbl_tvs (filterVarSet isKindVar tkvs) }
kcLookupKind :: Name -> TcM Kind
kcLookupKind nm
= do { tc_ty_thing <- tcLookup nm
; case tc_ty_thing of
AThing k -> return k
AGlobal (ATyCon tc) -> return (tyConKind tc)
_ -> pprPanic "kcLookupKind" (ppr tc_ty_thing) }
kcTyClTyVars :: Name -> LHsTyVarBndrs Name -> TcM a -> TcM a
kcTyClTyVars name (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
= kcScopedKindVars kvs $
do { tc_kind <- kcLookupKind name
; let (_, mono_kind) = splitForAllTys tc_kind
(arg_ks, _res_k) = splitKindFunTysN (length hs_tvs) mono_kind
; name_ks <- zipWithM kc_tv hs_tvs arg_ks
; tcExtendKindEnv name_ks thing_inside }
where
kc_tv :: LHsTyVarBndr Name -> Kind -> TcM (Name, Kind)
kc_tv (L _ (UserTyVar n)) exp_k
= return (n, exp_k)
kc_tv (L _ (KindedTyVar (L _ n) hs_k)) exp_k
= do { k <- tcLHsKind hs_k
; checkKind k exp_k
; return (n, exp_k) }
tcTyClTyVars :: Name -> LHsTyVarBndrs Name
-> ([TyVar] -> Kind -> TcM a) -> TcM a
tcTyClTyVars tycon (HsQTvs { hsq_kvs = hs_kvs, hsq_tvs = hs_tvs }) thing_inside
= kcScopedKindVars hs_kvs $
do { thing <- tcLookup tycon
; let { kind = case thing of
AThing kind -> kind
_ -> panic "tcTyClTyVars"
; (kvs, body) = splitForAllTys kind
; (kinds, res) = splitKindFunTysN (length hs_tvs) body }
; tvs <- zipWithM tc_hs_tv hs_tvs kinds
; tcExtendTyVarEnv tvs (thing_inside (kvs ++ tvs) res) }
where
tc_hs_tv (L _ (UserTyVar n)) kind = return (mkTyVar n kind)
tc_hs_tv (L _ (KindedTyVar (L _ n) hs_k)) kind
= do { tc_kind <- tcLHsKind hs_k
; checkKind kind tc_kind
; return (mkTyVar n kind) }
tcDataKindSig :: Kind -> TcM [TyVar]
tcDataKindSig kind
= do { checkTc (isLiftedTypeKind res_kind) (badKindSig kind)
; span <- getSrcSpanM
; us <- newUniqueSupply
; rdr_env <- getLocalRdrEnv
; let uniqs = uniqsFromSupply us
occs = [ occ | str <- allNameStrings
, let occ = mkOccName tvName str
, isNothing (lookupLocalRdrOcc rdr_env occ) ]
; return [ mk_tv span uniq occ kind
| ((kind, occ), uniq) <- arg_kinds `zip` occs `zip` uniqs ] }
where
(arg_kinds, res_kind) = splitKindFunTys kind
mk_tv loc uniq occ kind
= mkTyVar (mkInternalName uniq occ loc) kind
badKindSig :: Kind -> SDoc
badKindSig kind
= hang (ptext (sLit "Kind signature on data type declaration has non-* return kind"))
2 (ppr kind)
tcHsPatSigType :: UserTypeCtxt
-> HsWithBndrs Name (LHsType Name)
-> TcM ( Type
, [(Name, TcTyVar)]
, [(Name, TcTyVar)] )
tcHsPatSigType ctxt (HsWB { hswb_cts = hs_ty, hswb_kvs = sig_kvs,
hswb_tvs = sig_tvs, hswb_wcs = sig_wcs })
= addErrCtxt (pprSigCtxt ctxt empty (ppr hs_ty)) $
do { kvs <- mapM new_kv sig_kvs
; tvs <- mapM new_tv sig_tvs
; nwc_tvs <- mapM newWildcardVarMetaKind sig_wcs
; let nwc_binds = sig_wcs `zip` nwc_tvs
ktv_binds = (sig_kvs `zip` kvs) ++ (sig_tvs `zip` tvs)
; sig_ty <- tcExtendTyVarEnv2 (ktv_binds ++ nwc_binds) $
tcHsLiftedType hs_ty
; sig_ty <- zonkSigType sig_ty
; checkValidType ctxt sig_ty
; emitWildcardHoleConstraints (zip sig_wcs nwc_tvs)
; return (sig_ty, ktv_binds, nwc_binds) }
where
new_kv name = new_tkv name superKind
new_tv name = do { kind <- newMetaKindVar
; new_tkv name kind }
new_tkv name kind
= case ctxt of
RuleSigCtxt {} -> return (mkTcTyVar name kind (SkolemTv False))
_ -> newSigTyVar name kind
tcPatSig :: Bool
-> HsWithBndrs Name (LHsType Name)
-> TcSigmaType
-> TcM (TcType,
[(Name, TcTyVar)],
[(Name, TcTyVar)],
HsWrapper)
tcPatSig in_pat_bind sig res_ty
= do { (sig_ty, sig_tvs, sig_nwcs) <- tcHsPatSigType PatSigCtxt sig
; if null sig_tvs then do {
wrap <- addErrCtxtM (mk_msg sig_ty) $
tcSubType_NC PatSigCtxt res_ty sig_ty
; return (sig_ty, [], sig_nwcs, wrap)
} else do
{ when in_pat_bind (addErr (patBindSigErr sig_tvs))
; let bad_tvs = [ tv | (_, tv) <- sig_tvs
, not (tv `elemVarSet` exactTyVarsOfType sig_ty) ]
; checkTc (null bad_tvs) (badPatSigTvs sig_ty bad_tvs)
; wrap <- addErrCtxtM (mk_msg sig_ty) $
tcSubType_NC PatSigCtxt res_ty sig_ty
; return (sig_ty, sig_tvs, sig_nwcs, wrap)
} }
where
mk_msg sig_ty tidy_env
= do { (tidy_env, sig_ty) <- zonkTidyTcType tidy_env sig_ty
; (tidy_env, res_ty) <- zonkTidyTcType tidy_env res_ty
; let msg = vcat [ hang (ptext (sLit "When checking that the pattern signature:"))
4 (ppr sig_ty)
, nest 2 (hang (ptext (sLit "fits the type of its context:"))
2 (ppr res_ty)) ]
; return (tidy_env, msg) }
patBindSigErr :: [(Name, TcTyVar)] -> SDoc
patBindSigErr sig_tvs
= hang (ptext (sLit "You cannot bind scoped type variable") <> plural sig_tvs
<+> pprQuotedList (map fst sig_tvs))
2 (ptext (sLit "in a pattern binding signature"))
data ExpKind = EK TcKind (TcKind -> SDoc)
instance Outputable ExpKind where
ppr (EK k f) = f k
ekLifted, ekOpen, ekConstraint :: ExpKind
ekLifted = EK liftedTypeKind expectedKindMsg
ekOpen = EK openTypeKind expectedKindMsg
ekConstraint = EK constraintKind expectedKindMsg
expectedKindMsg :: TcKind -> SDoc
expectedKindMsg pkind
| isConstraintKind pkind = ptext (sLit "Expected a constraint")
| isOpenTypeKind pkind = ptext (sLit "Expected a type")
| otherwise = ptext (sLit "Expected kind") <+> quotes (pprKind pkind)
expArgKind :: SDoc -> TcKind -> Int -> ExpKind
expArgKind exp kind arg_no = EK kind msg_fn
where
msg_fn pkind
= sep [ ptext (sLit "The") <+> speakNth arg_no
<+> ptext (sLit "argument of") <+> exp
, nest 2 $ ptext (sLit "should have kind")
<+> quotes (pprKind pkind) ]
unifyKinds :: SDoc -> [(TcType, TcKind)] -> TcM TcKind
unifyKinds fun act_kinds
= do { kind <- newMetaKindVar
; let check (arg_no, (ty, act_kind))
= checkExpectedKind ty act_kind (expArgKind (quotes fun) kind arg_no)
; mapM_ check (zip [1..] act_kinds)
; return kind }
checkKind :: TcKind -> TcKind -> TcM ()
checkKind act_kind exp_kind
= do { mb_subk <- unifyKindX act_kind exp_kind
; case mb_subk of
Just EQ -> return ()
_ -> unifyKindMisMatch act_kind exp_kind }
checkExpectedKind :: Outputable a => a -> TcKind -> ExpKind -> TcM ()
checkExpectedKind ty act_kind (EK exp_kind ek_ctxt)
= do { mb_subk <- unifyKindX act_kind exp_kind
; case mb_subk of {
Just LT -> return () ;
Just EQ -> return () ;
_other -> do
{
exp_kind <- zonkTcKind exp_kind
; act_kind <- zonkTcKind act_kind
; traceTc "checkExpectedKind" (ppr ty $$ ppr act_kind $$ ppr exp_kind)
; env0 <- tcInitTidyEnv
; dflags <- getDynFlags
; let (exp_as, _) = splitKindFunTys exp_kind
(act_as, _) = splitKindFunTys act_kind
n_exp_as = length exp_as
n_act_as = length act_as
n_diff_as = n_act_as n_exp_as
(env1, tidy_exp_kind) = tidyOpenKind env0 exp_kind
(env2, tidy_act_kind) = tidyOpenKind env1 act_kind
occurs_check
| Just act_tv <- tcGetTyVar_maybe act_kind
= check_occ act_tv exp_kind
| Just exp_tv <- tcGetTyVar_maybe exp_kind
= check_occ exp_tv act_kind
| otherwise
= False
check_occ tv k = case occurCheckExpand dflags tv k of
OC_Occurs -> True
_bad -> False
err | isLiftedTypeKind exp_kind && isUnliftedTypeKind act_kind
= ptext (sLit "Expecting a lifted type, but") <+> quotes (ppr ty)
<+> ptext (sLit "is unlifted")
| isUnliftedTypeKind exp_kind && isLiftedTypeKind act_kind
= ptext (sLit "Expecting an unlifted type, but") <+> quotes (ppr ty)
<+> ptext (sLit "is lifted")
| occurs_check
= ptext (sLit "Kind occurs check") $$ more_info
| n_exp_as < n_act_as
= vcat [ ptext (sLit "Expecting") <+>
speakN n_diff_as <+> ptext (sLit "more argument")
<> (if n_diff_as > 1 then char 's' else empty)
<+> ptext (sLit "to") <+> quotes (ppr ty)
, more_info ]
| otherwise
= more_info
more_info = sep [ ek_ctxt tidy_exp_kind <> comma
, nest 2 $ ptext (sLit "but") <+> quotes (ppr ty)
<+> ptext (sLit "has kind") <+> quotes (pprKind tidy_act_kind)]
; traceTc "checkExpectedKind 1" (ppr ty $$ ppr tidy_act_kind $$ ppr tidy_exp_kind $$ ppr env1 $$ ppr env2)
; failWithTcM (env2, err) } } }
tcLHsKind :: LHsKind Name -> TcM Kind
tcLHsKind k = addErrCtxt (ptext (sLit "In the kind") <+> quotes (ppr k)) $
tc_lhs_kind k
tc_lhs_kind :: LHsKind Name -> TcM Kind
tc_lhs_kind (L span ki) = setSrcSpan span (tc_hs_kind ki)
tc_hs_kind :: HsKind Name -> TcM Kind
tc_hs_kind (HsTyVar tc) = tc_kind_var_app tc []
tc_hs_kind k@(HsAppTy _ _) = tc_kind_app k []
tc_hs_kind (HsParTy ki) = tc_lhs_kind ki
tc_hs_kind (HsFunTy ki1 ki2) =
do kappa_ki1 <- tc_lhs_kind ki1
kappa_ki2 <- tc_lhs_kind ki2
return (mkArrowKind kappa_ki1 kappa_ki2)
tc_hs_kind (HsListTy ki) =
do kappa <- tc_lhs_kind ki
checkWiredInTyCon listTyCon
return $ mkPromotedListTy kappa
tc_hs_kind (HsTupleTy _ kis) =
do kappas <- mapM tc_lhs_kind kis
checkWiredInTyCon tycon
return $ mkTyConApp tycon kappas
where
tycon = promotedTupleTyCon BoxedTuple (length kis)
tc_hs_kind k = pprPanic "tc_hs_kind" (ppr k)
tc_kind_app :: HsKind Name -> [LHsKind Name] -> TcM Kind
tc_kind_app (HsAppTy ki1 ki2) kis = tc_kind_app (unLoc ki1) (ki2:kis)
tc_kind_app (HsTyVar tc) kis = do { arg_kis <- mapM tc_lhs_kind kis
; tc_kind_var_app tc arg_kis }
tc_kind_app ki _ = failWithTc (quotes (ppr ki) <+>
ptext (sLit "is not a kind constructor"))
tc_kind_var_app :: Name -> [Kind] -> TcM Kind
tc_kind_var_app name arg_kis
| name == liftedTypeKindTyConName
|| name == constraintKindTyConName
= do { unless (null arg_kis)
(failWithTc (text "Kind" <+> ppr name <+> text "cannot be applied"))
; thing <- tcLookup name
; case thing of
AGlobal (ATyCon tc) -> return (mkTyConApp tc [])
_ -> panic "tc_kind_var_app 1" }
tc_kind_var_app name arg_kis
= do { thing <- tcLookup name
; case thing of
AGlobal (ATyCon tc)
-> do { data_kinds <- xoptM Opt_DataKinds
; unless data_kinds $ addErr (dataKindsErr name)
; case promotableTyCon_maybe tc of
Just prom_tc | arg_kis `lengthIs` tyConArity prom_tc
-> return (mkTyConApp prom_tc arg_kis)
Just _ -> tycon_err tc "is not fully applied"
Nothing -> tycon_err tc "is not promotable" }
ATyVar _ kind_var
| not (isKindVar kind_var)
-> failWithTc (ptext (sLit "Type variable") <+> quotes (ppr kind_var)
<+> ptext (sLit "used as a kind"))
| not (null arg_kis)
-> failWithTc (ptext (sLit "Kind variable") <+> quotes (ppr name)
<+> ptext (sLit "cannot appear in a function position"))
| otherwise
-> return (mkAppTys (mkTyVarTy kind_var) arg_kis)
AThing _
| isTyVarName name
-> failWithTc (ptext (sLit "Type variable") <+> quotes (ppr name)
<+> ptext (sLit "used in a kind"))
| otherwise
-> failWithTc (hang (ptext (sLit "Type constructor") <+> quotes (ppr name)
<+> ptext (sLit "used in a kind"))
2 (ptext (sLit "inside its own recursive group")))
APromotionErr err -> promotionErr name err
_ -> wrongThingErr "promoted type" thing name
}
where
tycon_err tc msg = failWithTc (quotes (ppr tc) <+> ptext (sLit "of kind")
<+> quotes (ppr (tyConKind tc)) <+> ptext (sLit msg))
dataKindsErr :: Name -> SDoc
dataKindsErr name
= hang (ptext (sLit "Illegal kind:") <+> quotes (ppr name))
2 (ptext (sLit "Perhaps you intended to use DataKinds"))
promotionErr :: Name -> PromotionErr -> TcM a
promotionErr name err
= failWithTc (hang (pprPECategory err <+> quotes (ppr name) <+> ptext (sLit "cannot be used here"))
2 (parens reason))
where
reason = case err of
FamDataConPE -> ptext (sLit "it comes from a data family instance")
NoDataKinds -> ptext (sLit "Perhaps you intended to use DataKinds")
_ -> ptext (sLit "it is defined and used in the same recursive group")
badPatSigTvs :: TcType -> [TyVar] -> SDoc
badPatSigTvs sig_ty bad_tvs
= vcat [ fsep [ptext (sLit "The type variable") <> plural bad_tvs,
quotes (pprWithCommas ppr bad_tvs),
ptext (sLit "should be bound by the pattern signature") <+> quotes (ppr sig_ty),
ptext (sLit "but are actually discarded by a type synonym") ]
, ptext (sLit "To fix this, expand the type synonym")
, ptext (sLit "[Note: I hope to lift this restriction in due course]") ]
unifyKindMisMatch :: TcKind -> TcKind -> TcM a
unifyKindMisMatch ki1 ki2 = do
ki1' <- zonkTcKind ki1
ki2' <- zonkTcKind ki2
let msg = hang (ptext (sLit "Couldn't match kind"))
2 (sep [quotes (ppr ki1'),
ptext (sLit "against"),
quotes (ppr ki2')])
failWithTc msg