module TcBinds ( tcLocalBinds, tcTopBinds, tcRecSelBinds,
tcValBinds, tcHsBootSigs, tcPolyCheck,
tcSpecPrags, tcSpecWrapper,
tcVectDecls, addTypecheckedBinds,
TcSigInfo(..), TcSigFun,
TcPragEnv, mkPragEnv,
tcUserTypeSig, instTcTySig, chooseInferredQuantifiers,
instTcTySigFromId, tcExtendTyVarEnvFromSig,
badBootDeclErr ) where
import TcMatches ( tcGRHSsPat, tcMatchesFun )
import TcExpr ( tcMonoExpr )
import TcPatSyn ( tcInferPatSynDecl, tcCheckPatSynDecl
, tcPatSynBuilderBind, tcPatSynSig )
import DynFlags
import HsSyn
import HscTypes( isHsBootOrSig )
import TcRnMonad
import TcEnv
import TcUnify
import TcSimplify
import TcEvidence
import TcHsType
import TcPat
import TcMType
import Inst( topInstantiate, deeplyInstantiate )
import FamInstEnv( normaliseType )
import FamInst( tcGetFamInstEnvs )
import TyCon
import TcType
import TysPrim
import Id
import Var
import VarSet
import VarEnv( TidyEnv )
import Module
import Name
import NameSet
import NameEnv
import SrcLoc
import Bag
import ListSetOps
import ErrUtils
import Digraph
import Maybes
import Util
import BasicTypes
import Outputable
import Type(mkStrLitTy, tidyOpenType)
import PrelNames( mkUnboundName, gHC_PRIM, ipClassName )
import TcValidity (checkValidType)
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
#include "HsVersions.h"
addTypecheckedBinds :: TcGblEnv -> [LHsBinds Id] -> TcGblEnv
addTypecheckedBinds tcg_env binds
| isHsBootOrSig (tcg_src tcg_env) = tcg_env
| otherwise = tcg_env { tcg_binds = foldr unionBags
(tcg_binds tcg_env)
binds }
tcTopBinds :: [(RecFlag, LHsBinds Name)] -> [LSig Name] -> TcM (TcGblEnv, TcLclEnv)
tcTopBinds binds sigs
= do {
(binds', (tcg_env, tcl_env)) <- tcValBinds TopLevel binds sigs $
do { gbl <- getGblEnv
; lcl <- getLclEnv
; return (gbl, lcl) }
; specs <- tcImpPrags sigs
; let { tcg_env' = tcg_env { tcg_imp_specs = specs ++ tcg_imp_specs tcg_env }
`addTypecheckedBinds` map snd binds' }
; return (tcg_env', tcl_env) }
tcRecSelBinds :: HsValBinds Name -> TcM TcGblEnv
tcRecSelBinds (ValBindsOut binds sigs)
= tcExtendGlobalValEnv [sel_id | L _ (IdSig sel_id) <- sigs] $
do { (rec_sel_binds, tcg_env) <- discardWarnings $
tcValBinds TopLevel binds sigs getGblEnv
; let tcg_env' = tcg_env `addTypecheckedBinds` map snd rec_sel_binds
; return tcg_env' }
tcRecSelBinds (ValBindsIn {}) = panic "tcRecSelBinds"
tcHsBootSigs :: [(RecFlag, LHsBinds Name)] -> [LSig Name] -> TcM [Id]
tcHsBootSigs binds sigs
= do { checkTc (null binds) badBootDeclErr
; concat <$> mapM (addLocM tc_boot_sig) (filter isTypeLSig sigs) }
where
tc_boot_sig (TypeSig lnames hs_ty) = mapM f lnames
where
f (L _ name)
= do { sigma_ty <- solveEqualities $
tcHsSigWcType (FunSigCtxt name False) hs_ty
; return (mkVanillaGlobal name sigma_ty) }
tc_boot_sig s = pprPanic "tcHsBootSigs/tc_boot_sig" (ppr s)
badBootDeclErr :: MsgDoc
badBootDeclErr = text "Illegal declarations in an hs-boot file"
tcLocalBinds :: HsLocalBinds Name -> TcM thing
-> TcM (HsLocalBinds TcId, thing)
tcLocalBinds EmptyLocalBinds thing_inside
= do { thing <- thing_inside
; return (EmptyLocalBinds, thing) }
tcLocalBinds (HsValBinds (ValBindsOut binds sigs)) thing_inside
= do { (binds', thing) <- tcValBinds NotTopLevel binds sigs thing_inside
; return (HsValBinds (ValBindsOut binds' sigs), thing) }
tcLocalBinds (HsValBinds (ValBindsIn {})) _ = panic "tcLocalBinds"
tcLocalBinds (HsIPBinds (IPBinds ip_binds _)) thing_inside
= do { ipClass <- tcLookupClass ipClassName
; (given_ips, ip_binds') <-
mapAndUnzipM (wrapLocSndM (tc_ip_bind ipClass)) ip_binds
; (ev_binds, result) <- checkConstraints (IPSkol ips)
[] given_ips thing_inside
; return (HsIPBinds (IPBinds ip_binds' ev_binds), result) }
where
ips = [ip | L _ (IPBind (Left (L _ ip)) _) <- ip_binds]
tc_ip_bind ipClass (IPBind (Left (L _ ip)) expr)
= do { ty <- newOpenFlexiTyVarTy
; let p = mkStrLitTy $ hsIPNameFS ip
; ip_id <- newDict ipClass [ p, ty ]
; expr' <- tcMonoExpr expr (mkCheckExpType ty)
; let d = toDict ipClass p ty `fmap` expr'
; return (ip_id, (IPBind (Right ip_id) d)) }
tc_ip_bind _ (IPBind (Right {}) _) = panic "tc_ip_bind"
toDict ipClass x ty = HsWrap $ mkWpCastR $
wrapIP $ mkClassPred ipClass [x,ty]
tcValBinds :: TopLevelFlag
-> [(RecFlag, LHsBinds Name)] -> [LSig Name]
-> TcM thing
-> TcM ([(RecFlag, LHsBinds TcId)], thing)
tcValBinds top_lvl binds sigs thing_inside
= do { let patsyns = getPatSynBinds binds
; (poly_ids, sig_fn) <- tcAddPatSynPlaceholders patsyns $
tcTySigs sigs
; _self_boot <- tcSelfBootInfo
; let prag_fn = mkPragEnv sigs (foldr (unionBags . snd) emptyBag binds)
; tcExtendLetEnvIds top_lvl [(idName id, id) | id <- poly_ids] $ do
{ (binds', (extra_binds', thing)) <- tcBindGroups top_lvl sig_fn prag_fn binds $ do
{ thing <- thing_inside
; patsyn_builders <- mapM (tcPatSynBuilderBind sig_fn) patsyns
; let extra_binds = [ (NonRecursive, builder) | builder <- patsyn_builders ]
; return (extra_binds, thing) }
; return (binds' ++ extra_binds', thing) }}
tcBindGroups :: TopLevelFlag -> TcSigFun -> TcPragEnv
-> [(RecFlag, LHsBinds Name)] -> TcM thing
-> TcM ([(RecFlag, LHsBinds TcId)], thing)
tcBindGroups _ _ _ [] thing_inside
= do { thing <- thing_inside
; return ([], thing) }
tcBindGroups top_lvl sig_fn prag_fn (group : groups) thing_inside
= do { (group', (groups', thing))
<- tc_group top_lvl sig_fn prag_fn group $
tcBindGroups top_lvl sig_fn prag_fn groups thing_inside
; return (group' ++ groups', thing) }
tc_group :: forall thing.
TopLevelFlag -> TcSigFun -> TcPragEnv
-> (RecFlag, LHsBinds Name) -> TcM thing
-> TcM ([(RecFlag, LHsBinds TcId)], thing)
tc_group top_lvl sig_fn prag_fn (NonRecursive, binds) thing_inside
= do { let bind = case bagToList binds of
[bind] -> bind
[] -> panic "tc_group: empty list of binds"
_ -> panic "tc_group: NonRecursive binds is not a singleton bag"
; (bind', thing) <- tc_single top_lvl sig_fn prag_fn bind thing_inside
; return ( [(NonRecursive, bind')], thing) }
tc_group top_lvl sig_fn prag_fn (Recursive, binds) thing_inside
=
do { traceTc "tc_group rec" (pprLHsBinds binds)
; when hasPatSyn $ recursivePatSynErr binds
; (binds1, thing) <- go sccs
; return ([(Recursive, binds1)], thing) }
where
hasPatSyn = anyBag (isPatSyn . unLoc) binds
isPatSyn PatSynBind{} = True
isPatSyn _ = False
sccs :: [SCC (LHsBind Name)]
sccs = stronglyConnCompFromEdgedVertices (mkEdges sig_fn binds)
go :: [SCC (LHsBind Name)] -> TcM (LHsBinds TcId, thing)
go (scc:sccs) = do { (binds1, ids1) <- tc_scc scc
; (binds2, thing) <- tcExtendLetEnv top_lvl ids1 $
go sccs
; return (binds1 `unionBags` binds2, thing) }
go [] = do { thing <- thing_inside; return (emptyBag, thing) }
tc_scc (AcyclicSCC bind) = tc_sub_group NonRecursive [bind]
tc_scc (CyclicSCC binds) = tc_sub_group Recursive binds
tc_sub_group = tcPolyBinds top_lvl sig_fn prag_fn Recursive
recursivePatSynErr :: OutputableBndr name => LHsBinds name -> TcM a
recursivePatSynErr binds
= failWithTc $
hang (text "Recursive pattern synonym definition with following bindings:")
2 (vcat $ map pprLBind . bagToList $ binds)
where
pprLoc loc = parens (text "defined at" <+> ppr loc)
pprLBind (L loc bind) = pprWithCommas ppr (collectHsBindBinders bind) <+>
pprLoc loc
tc_single :: forall thing.
TopLevelFlag -> TcSigFun -> TcPragEnv
-> LHsBind Name -> TcM thing
-> TcM (LHsBinds TcId, thing)
tc_single _top_lvl sig_fn _prag_fn (L _ (PatSynBind psb@PSB{ psb_id = L _ name })) thing_inside
= do { (aux_binds, tcg_env) <- tc_pat_syn_decl
; thing <- setGblEnv tcg_env thing_inside
; return (aux_binds, thing)
}
where
tc_pat_syn_decl :: TcM (LHsBinds TcId, TcGblEnv)
tc_pat_syn_decl = case sig_fn name of
Nothing -> tcInferPatSynDecl psb
Just (TcPatSynSig tpsi) -> tcCheckPatSynDecl psb tpsi
Just _ -> panic "tc_single"
tc_single top_lvl sig_fn prag_fn lbind thing_inside
= do { (binds1, ids) <- tcPolyBinds top_lvl sig_fn prag_fn
NonRecursive NonRecursive
[lbind]
; thing <- tcExtendLetEnv top_lvl ids thing_inside
; return (binds1, thing) }
type BKey = Int
mkEdges :: TcSigFun -> LHsBinds Name -> [Node BKey (LHsBind Name)]
mkEdges sig_fn binds
= [ (bind, key, [key | n <- nameSetElems (bind_fvs (unLoc bind)),
Just key <- [lookupNameEnv key_map n], no_sig n ])
| (bind, key) <- keyd_binds
]
where
no_sig :: Name -> Bool
no_sig n = noCompleteSig (sig_fn n)
keyd_binds = bagToList binds `zip` [0::BKey ..]
key_map :: NameEnv BKey
key_map = mkNameEnv [(bndr, key) | (L _ bind, key) <- keyd_binds
, bndr <- collectHsBindBinders bind ]
tcPolyBinds :: TopLevelFlag -> TcSigFun -> TcPragEnv
-> RecFlag
-> RecFlag
-> [LHsBind Name]
-> TcM (LHsBinds TcId, [TcId])
tcPolyBinds top_lvl sig_fn prag_fn rec_group rec_tc bind_list
= setSrcSpan loc $
recoverM (recoveryCode binder_names sig_fn) $ do
{ traceTc "------------------------------------------------" Outputable.empty
; traceTc "Bindings for {" (ppr binder_names)
; dflags <- getDynFlags
; type_env <- getLclTypeEnv
; let plan = decideGeneralisationPlan dflags type_env
binder_names bind_list sig_fn
; traceTc "Generalisation plan" (ppr plan)
; result@(tc_binds, poly_ids) <- case plan of
NoGen -> tcPolyNoGen rec_tc prag_fn sig_fn bind_list
InferGen mn -> tcPolyInfer rec_tc prag_fn sig_fn mn bind_list
CheckGen lbind sig -> tcPolyCheck rec_tc prag_fn sig lbind
; checkStrictBinds top_lvl rec_group bind_list tc_binds poly_ids
; traceTc "} End of bindings for" (vcat [ ppr binder_names, ppr rec_group
, vcat [ppr id <+> ppr (idType id) | id <- poly_ids]
])
; return result }
where
binder_names = collectHsBindListBinders bind_list
loc = foldr1 combineSrcSpans (map getLoc bind_list)
tcPolyNoGen
:: RecFlag
-> TcPragEnv -> TcSigFun
-> [LHsBind Name]
-> TcM (LHsBinds TcId, [TcId])
tcPolyNoGen rec_tc prag_fn tc_sig_fn bind_list
= do { (binds', mono_infos) <- tcMonoBinds rec_tc tc_sig_fn
(LetGblBndr prag_fn)
bind_list
; mono_ids' <- mapM tc_mono_info mono_infos
; return (binds', mono_ids') }
where
tc_mono_info (MBI { mbi_poly_name = name, mbi_mono_id = mono_id })
= do { mono_ty' <- zonkTcType (idType mono_id)
; let mono_id' = setIdType mono_id mono_ty'
; _specs <- tcSpecPrags mono_id' (lookupPragEnv prag_fn name)
; return mono_id' }
tcPolyCheck :: RecFlag
-> TcPragEnv
-> TcIdSigInfo
-> LHsBind Name
-> TcM (LHsBinds TcId, [TcId])
tcPolyCheck rec_tc prag_fn
sig@(TISI { sig_bndr = CompleteSig poly_id
, sig_skols = skol_prs
, sig_theta = theta
, sig_tau = tau
, sig_ctxt = ctxt
, sig_loc = loc })
bind
= do { ev_vars <- newEvVars theta
; let skol_info = SigSkol ctxt (mkCheckExpType $ mkPhiTy theta tau)
prag_sigs = lookupPragEnv prag_fn name
skol_tvs = map snd skol_prs
name = idName poly_id
; (ev_binds, (binds', _))
<- setSrcSpan loc $
checkConstraints skol_info skol_tvs ev_vars $
tcMonoBinds rec_tc (\_ -> Just (TcIdSig sig)) LetLclBndr [bind]
; spec_prags <- tcSpecPrags poly_id prag_sigs
; poly_id <- addInlinePrags poly_id prag_sigs
; let bind' = case bagToList binds' of
[b] -> b
_ -> pprPanic "tcPolyCheck" (ppr binds')
abs_bind = L loc $ AbsBindsSig
{ abs_tvs = skol_tvs
, abs_ev_vars = ev_vars
, abs_sig_export = poly_id
, abs_sig_prags = SpecPrags spec_prags
, abs_sig_ev_bind = ev_binds
, abs_sig_bind = bind' }
; return (unitBag abs_bind, [poly_id]) }
tcPolyCheck _rec_tc _prag_fn sig _bind
= pprPanic "tcPolyCheck" (ppr sig)
tcPolyInfer
:: RecFlag
-> TcPragEnv -> TcSigFun
-> Bool
-> [LHsBind Name]
-> TcM (LHsBinds TcId, [TcId])
tcPolyInfer rec_tc prag_fn tc_sig_fn mono bind_list
= do { (tclvl, wanted, (binds', mono_infos))
<- pushLevelAndCaptureConstraints $
tcMonoBinds rec_tc tc_sig_fn LetLclBndr bind_list
; let name_taus = [ (mbi_poly_name info, idType (mbi_mono_id info))
| info <- mono_infos ]
sigs = [ sig | MBI { mbi_sig = Just sig } <- mono_infos ]
; traceTc "simplifyInfer call" (ppr tclvl $$ ppr name_taus $$ ppr wanted)
; (qtvs, givens, ev_binds)
<- simplifyInfer tclvl mono sigs name_taus wanted
; let inferred_theta = map evVarPred givens
; exports <- checkNoErrs $
mapM (mkExport prag_fn qtvs inferred_theta) mono_infos
; loc <- getSrcSpanM
; let poly_ids = map abe_poly exports
abs_bind = L loc $
AbsBinds { abs_tvs = qtvs
, abs_ev_vars = givens, abs_ev_binds = [ev_binds]
, abs_exports = exports, abs_binds = binds' }
; traceTc "Binding:" (ppr (poly_ids `zip` map idType poly_ids))
; return (unitBag abs_bind, poly_ids) }
mkExport :: TcPragEnv
-> [TyVar] -> TcThetaType
-> MonoBindInfo
-> TcM (ABExport Id)
mkExport prag_fn qtvs theta
mono_info@(MBI { mbi_poly_name = poly_name
, mbi_sig = mb_sig
, mbi_mono_id = mono_id })
= do { mono_ty <- zonkTcType (idType mono_id)
; poly_id <- case mb_sig of
Just sig | Just poly_id <- completeIdSigPolyId_maybe sig
-> return poly_id
_other -> checkNoErrs $
mkInferredPolyId qtvs theta
poly_name mb_sig mono_ty
; poly_id <- addInlinePrags poly_id prag_sigs
; spec_prags <- tcSpecPrags poly_id prag_sigs
; let sel_poly_ty = mkInvSigmaTy qtvs theta mono_ty
poly_ty = idType poly_id
; wrap <- if sel_poly_ty `eqType` poly_ty
then return idHsWrapper
else addErrCtxtM (mk_impedence_match_msg mono_info sel_poly_ty poly_ty) $
tcSubType_NC sig_ctxt sel_poly_ty (mkCheckExpType poly_ty)
; warn_missing_sigs <- woptM Opt_WarnMissingLocalSignatures
; when warn_missing_sigs $
localSigWarn Opt_WarnMissingLocalSignatures poly_id mb_sig
; return (ABE { abe_wrap = wrap
, abe_poly = poly_id
, abe_mono = mono_id
, abe_prags = SpecPrags spec_prags}) }
where
prag_sigs = lookupPragEnv prag_fn poly_name
sig_ctxt = InfSigCtxt poly_name
mkInferredPolyId :: [TyVar] -> TcThetaType
-> Name -> Maybe TcIdSigInfo -> TcType
-> TcM TcId
mkInferredPolyId qtvs inferred_theta poly_name mb_sig mono_ty
= do { fam_envs <- tcGetFamInstEnvs
; let (_co, mono_ty') = normaliseType fam_envs Nominal mono_ty
; (binders, theta') <- chooseInferredQuantifiers inferred_theta
(tyCoVarsOfType mono_ty') qtvs mb_sig
; let inferred_poly_ty = mkForAllTys binders (mkPhiTy theta' mono_ty')
; traceTc "mkInferredPolyId" (vcat [ppr poly_name, ppr qtvs, ppr theta'
, ppr inferred_poly_ty])
; addErrCtxtM (mk_inf_msg poly_name inferred_poly_ty) $
checkValidType (InfSigCtxt poly_name) inferred_poly_ty
; return (mkLocalIdOrCoVar poly_name inferred_poly_ty) }
chooseInferredQuantifiers :: TcThetaType
-> TcTyVarSet
-> [TcTyVar]
-> Maybe TcIdSigInfo
-> TcM ([TcTyBinder], TcThetaType)
chooseInferredQuantifiers inferred_theta tau_tvs qtvs Nothing
= do { let free_tvs = closeOverKinds (growThetaTyVars inferred_theta tau_tvs)
my_theta = pickQuantifiablePreds free_tvs [] inferred_theta
binders = [ mkNamedBinder Invisible tv
| tv <- qtvs
, tv `elemVarSet` free_tvs ]
; return (binders, my_theta) }
chooseInferredQuantifiers inferred_theta tau_tvs qtvs
(Just (TISI { sig_bndr = bndr_info
, sig_ctxt = ctxt
, sig_theta = annotated_theta
, sig_skols = annotated_tvs }))
| PartialSig { sig_cts = extra } <- bndr_info
, Nothing <- extra
= do { annotated_theta <- zonkTcTypes annotated_theta
; let free_tvs = closeOverKinds (tyCoVarsOfTypes annotated_theta
`unionVarSet` tau_tvs)
; traceTc "ciq" (vcat [ ppr bndr_info, ppr annotated_theta, ppr free_tvs])
; return (mk_binders free_tvs, annotated_theta) }
| PartialSig { sig_cts = extra } <- bndr_info
, Just loc <- extra
= do { annotated_theta <- zonkTcTypes annotated_theta
; let free_tvs = closeOverKinds (growThetaTyVars inferred_theta seed_tvs)
seed_tvs = tyCoVarsOfTypes annotated_theta
`unionVarSet` tau_tvs
my_theta = pickQuantifiablePreds free_tvs annotated_theta inferred_theta
inferred_diff = [ pred
| pred <- my_theta
, all (not . (`eqType` pred)) annotated_theta ]
final_theta = annotated_theta ++ inferred_diff
; partial_sigs <- xoptM LangExt.PartialTypeSignatures
; warn_partial_sigs <- woptM Opt_WarnPartialTypeSignatures
; msg <- mkLongErrAt loc (mk_msg inferred_diff partial_sigs) empty
; traceTc "completeTheta" $
vcat [ ppr bndr_info
, ppr annotated_theta, ppr inferred_theta
, ppr inferred_diff ]
; case partial_sigs of
True | warn_partial_sigs ->
reportWarning (Reason Opt_WarnPartialTypeSignatures) msg
| otherwise -> return ()
False -> reportError msg
; return (mk_binders free_tvs, final_theta) }
| otherwise = pprPanic "chooseInferredQuantifiers" (ppr bndr_info)
where
pts_hint = text "To use the inferred type, enable PartialTypeSignatures"
mk_msg inferred_diff suppress_hint
= vcat [ hang ((text "Found constraint wildcard") <+> quotes (char '_'))
2 (text "standing for") <+> quotes (pprTheta inferred_diff)
, if suppress_hint then empty else pts_hint
, typeSigCtxt ctxt bndr_info ]
spec_tv_set = mkVarSet $ map snd annotated_tvs
mk_binders free_tvs
= [ mkNamedBinder vis tv
| tv <- qtvs
, tv `elemVarSet` free_tvs
, let vis | tv `elemVarSet` spec_tv_set = Specified
| otherwise = Invisible ]
mk_impedence_match_msg :: MonoBindInfo
-> TcType -> TcType
-> TidyEnv -> TcM (TidyEnv, SDoc)
mk_impedence_match_msg (MBI { mbi_poly_name = name, mbi_sig = mb_sig })
inf_ty sig_ty tidy_env
= do { (tidy_env1, inf_ty) <- zonkTidyTcType tidy_env inf_ty
; (tidy_env2, sig_ty) <- zonkTidyTcType tidy_env1 sig_ty
; let msg = vcat [ text "When checking that the inferred type"
, nest 2 $ ppr name <+> dcolon <+> ppr inf_ty
, text "is as general as its" <+> what <+> text "signature"
, nest 2 $ ppr name <+> dcolon <+> ppr sig_ty ]
; return (tidy_env2, msg) }
where
what = case mb_sig of
Nothing -> text "inferred"
Just sig | isPartialSig sig -> text "(partial)"
| otherwise -> empty
mk_inf_msg :: Name -> TcType -> TidyEnv -> TcM (TidyEnv, SDoc)
mk_inf_msg poly_name poly_ty tidy_env
= do { (tidy_env1, poly_ty) <- zonkTidyTcType tidy_env poly_ty
; let msg = vcat [ text "When checking the inferred type"
, nest 2 $ ppr poly_name <+> dcolon <+> ppr poly_ty ]
; return (tidy_env1, msg) }
localSigWarn :: WarningFlag -> Id -> Maybe TcIdSigInfo -> TcM ()
localSigWarn flag id mb_sig
| Just _ <- mb_sig = return ()
| not (isSigmaTy (idType id)) = return ()
| otherwise = warnMissingSignatures flag msg id
where
msg = text "Polymorphic local binding with no type signature:"
warnMissingSignatures :: WarningFlag -> SDoc -> Id -> TcM ()
warnMissingSignatures flag msg id
= do { env0 <- tcInitTidyEnv
; let (env1, tidy_ty) = tidyOpenType env0 (idType id)
; addWarnTcM (Reason flag) (env1, mk_msg tidy_ty) }
where
mk_msg ty = sep [ msg, nest 2 $ pprPrefixName (idName id) <+> dcolon <+> ppr ty ]
recoveryCode :: [Name] -> TcSigFun -> TcM (LHsBinds TcId, [Id])
recoveryCode binder_names sig_fn
= do { traceTc "tcBindsWithSigs: error recovery" (ppr binder_names)
; let poly_ids = map mk_dummy binder_names
; return (emptyBag, poly_ids) }
where
mk_dummy name
| Just sig <- sig_fn name
, Just poly_id <- completeSigPolyId_maybe sig
= poly_id
| otherwise
= mkLocalId name forall_a_a
forall_a_a :: TcType
forall_a_a = mkSpecForAllTys [runtimeRep1TyVar, openAlphaTyVar] openAlphaTy
mkPragEnv :: [LSig Name] -> LHsBinds Name -> TcPragEnv
mkPragEnv sigs binds
= foldl extendPragEnv emptyNameEnv prs
where
prs = mapMaybe get_sig sigs
get_sig :: LSig Name -> Maybe (Name, LSig Name)
get_sig (L l (SpecSig lnm@(L _ nm) ty inl)) = Just (nm, L l $ SpecSig lnm ty (add_arity nm inl))
get_sig (L l (InlineSig lnm@(L _ nm) inl)) = Just (nm, L l $ InlineSig lnm (add_arity nm inl))
get_sig _ = Nothing
add_arity n inl_prag
| Inline <- inl_inline inl_prag
= case lookupNameEnv ar_env n of
Just ar -> inl_prag { inl_sat = Just ar }
Nothing -> WARN( True, text "mkPragEnv no arity" <+> ppr n )
inl_prag
| otherwise
= inl_prag
ar_env :: NameEnv Arity
ar_env = foldrBag lhsBindArity emptyNameEnv binds
extendPragEnv :: TcPragEnv -> (Name, LSig Name) -> TcPragEnv
extendPragEnv prag_fn (n, sig) = extendNameEnv_Acc (:) singleton prag_fn n sig
lhsBindArity :: LHsBind Name -> NameEnv Arity -> NameEnv Arity
lhsBindArity (L _ (FunBind { fun_id = id, fun_matches = ms })) env
= extendNameEnv env (unLoc id) (matchGroupArity ms)
lhsBindArity _ env = env
tcSpecPrags :: Id -> [LSig Name]
-> TcM [LTcSpecPrag]
tcSpecPrags poly_id prag_sigs
= do { traceTc "tcSpecPrags" (ppr poly_id <+> ppr spec_sigs)
; unless (null bad_sigs) warn_discarded_sigs
; pss <- mapAndRecoverM (wrapLocM (tcSpecPrag poly_id)) spec_sigs
; return $ concatMap (\(L l ps) -> map (L l) ps) pss }
where
spec_sigs = filter isSpecLSig prag_sigs
bad_sigs = filter is_bad_sig prag_sigs
is_bad_sig s = not (isSpecLSig s || isInlineLSig s)
warn_discarded_sigs
= addWarnTc NoReason
(hang (text "Discarding unexpected pragmas for" <+> ppr poly_id)
2 (vcat (map (ppr . getLoc) bad_sigs)))
tcSpecPrag :: TcId -> Sig Name -> TcM [TcSpecPrag]
tcSpecPrag poly_id prag@(SpecSig fun_name hs_tys inl)
= addErrCtxt (spec_ctxt prag) $
do { warnIf NoReason (not (isOverloadedTy poly_ty || isInlinePragma inl))
(text "SPECIALISE pragma for non-overloaded function"
<+> quotes (ppr fun_name))
; spec_prags <- mapM tc_one hs_tys
; traceTc "tcSpecPrag" (ppr poly_id $$ nest 2 (vcat (map ppr spec_prags)))
; return spec_prags }
where
name = idName poly_id
poly_ty = idType poly_id
spec_ctxt prag = hang (text "In the SPECIALISE pragma") 2 (ppr prag)
tc_one hs_ty
= do { spec_ty <- tcHsSigType (FunSigCtxt name False) hs_ty
; wrap <- tcSpecWrapper (FunSigCtxt name True) poly_ty spec_ty
; return (SpecPrag poly_id wrap inl) }
tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag)
tcSpecWrapper :: UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tcSpecWrapper ctxt poly_ty spec_ty
= do { (sk_wrap, inst_wrap)
<- tcSkolemise ctxt spec_ty $ \ _ spec_tau ->
do { (inst_wrap, tau) <- topInstantiate orig poly_ty
; _ <- unifyType noThing spec_tau tau
; return inst_wrap }
; return (sk_wrap <.> inst_wrap) }
where
orig = SpecPragOrigin ctxt
tcImpPrags :: [LSig Name] -> TcM [LTcSpecPrag]
tcImpPrags prags
= do { this_mod <- getModule
; dflags <- getDynFlags
; if (not_specialising dflags) then
return []
else do
{ pss <- mapAndRecoverM (wrapLocM tcImpSpec)
[L loc (name,prag)
| (L loc prag@(SpecSig (L _ name) _ _)) <- prags
, not (nameIsLocalOrFrom this_mod name) ]
; return $ concatMap (\(L l ps) -> map (L l) ps) pss } }
where
not_specialising dflags
| not (gopt Opt_Specialise dflags) = True
| otherwise = case hscTarget dflags of
HscNothing -> True
HscInterpreted -> True
_other -> False
tcImpSpec :: (Name, Sig Name) -> TcM [TcSpecPrag]
tcImpSpec (name, prag)
= do { id <- tcLookupId name
; unless (isAnyInlinePragma (idInlinePragma id))
(addWarnTc NoReason (impSpecErr name))
; tcSpecPrag id prag }
impSpecErr :: Name -> SDoc
impSpecErr name
= hang (text "You cannot SPECIALISE" <+> quotes (ppr name))
2 (vcat [ text "because its definition has no INLINE/INLINABLE pragma"
, parens $ sep
[ text "or its defining module" <+> quotes (ppr mod)
, text "was compiled without -O"]])
where
mod = nameModule name
tcVectDecls :: [LVectDecl Name] -> TcM ([LVectDecl TcId])
tcVectDecls decls
= do { decls' <- mapM (wrapLocM tcVect) decls
; let ids = [lvectDeclName decl | decl <- decls', not $ lvectInstDecl decl]
dups = findDupsEq (==) ids
; mapM_ reportVectDups dups
; traceTcConstraints "End of tcVectDecls"
; return decls'
}
where
reportVectDups (first:_second:_more)
= addErrAt (getSrcSpan first) $
text "Duplicate vectorisation declarations for" <+> ppr first
reportVectDups _ = return ()
tcVect :: VectDecl Name -> TcM (VectDecl TcId)
tcVect (HsVect s name rhs)
= addErrCtxt (vectCtxt name) $
do { var <- wrapLocM tcLookupId name
; let L rhs_loc (HsVar (L lv rhs_var_name)) = rhs
; rhs_id <- tcLookupId rhs_var_name
; return $ HsVect s var (L rhs_loc (HsVar (L lv rhs_id)))
}
tcVect (HsNoVect s name)
= addErrCtxt (vectCtxt name) $
do { var <- wrapLocM tcLookupId name
; return $ HsNoVect s var
}
tcVect (HsVectTypeIn _ isScalar lname rhs_name)
= addErrCtxt (vectCtxt lname) $
do { tycon <- tcLookupLocatedTyCon lname
; checkTc ( not isScalar
|| isJust rhs_name
|| tyConArity tycon == 0
)
scalarTyConMustBeNullary
; rhs_tycon <- fmapMaybeM (tcLookupTyCon . unLoc) rhs_name
; return $ HsVectTypeOut isScalar tycon rhs_tycon
}
tcVect (HsVectTypeOut _ _ _)
= panic "TcBinds.tcVect: Unexpected 'HsVectTypeOut'"
tcVect (HsVectClassIn _ lname)
= addErrCtxt (vectCtxt lname) $
do { cls <- tcLookupLocatedClass lname
; return $ HsVectClassOut cls
}
tcVect (HsVectClassOut _)
= panic "TcBinds.tcVect: Unexpected 'HsVectClassOut'"
tcVect (HsVectInstIn linstTy)
= addErrCtxt (vectCtxt linstTy) $
do { (cls, tys) <- tcHsVectInst linstTy
; inst <- tcLookupInstance cls tys
; return $ HsVectInstOut inst
}
tcVect (HsVectInstOut _)
= panic "TcBinds.tcVect: Unexpected 'HsVectInstOut'"
vectCtxt :: Outputable thing => thing -> SDoc
vectCtxt thing = text "When checking the vectorisation declaration for" <+> ppr thing
scalarTyConMustBeNullary :: MsgDoc
scalarTyConMustBeNullary = text "VECTORISE SCALAR type constructor must be nullary"
tcMonoBinds :: RecFlag
-> TcSigFun -> LetBndrSpec
-> [LHsBind Name]
-> TcM (LHsBinds TcId, [MonoBindInfo])
tcMonoBinds is_rec sig_fn no_gen
[ L b_loc (FunBind { fun_id = L nm_loc name,
fun_matches = matches, bind_fvs = fvs })]
| NonRecursive <- is_rec
, Nothing <- sig_fn name
=
setSrcSpan b_loc $
do { rhs_ty <- newOpenInferExpType
; (co_fn, matches')
<- tcExtendIdBndrs [TcIdBndr_ExpType name rhs_ty NotTopLevel] $
tcMatchesFun name matches rhs_ty
; rhs_ty <- readExpType rhs_ty
; let orig = matchesCtOrigin matches
; rhs_ty <- zonkTcType rhs_ty
; (inst_wrap, rhs_ty) <- addErrCtxtM (instErrCtxt name rhs_ty) $
deeplyInstantiate orig rhs_ty
; mono_id <- newNoSigLetBndr no_gen name rhs_ty
; return (unitBag $ L b_loc $
FunBind { fun_id = L nm_loc mono_id,
fun_matches = matches', bind_fvs = fvs,
fun_co_fn = inst_wrap <.> co_fn, fun_tick = [] },
[MBI { mbi_poly_name = name
, mbi_sig = Nothing
, mbi_mono_id = mono_id }]) }
tcMonoBinds _ sig_fn no_gen binds
= do { tc_binds <- mapM (wrapLocM (tcLhs sig_fn no_gen)) binds
; let mono_infos = getMonoBindInfo tc_binds
rhs_id_env = [(name, mono_id) | MBI { mbi_poly_name = name
, mbi_sig = mb_sig
, mbi_mono_id = mono_id }
<- mono_infos
, case mb_sig of
Just sig -> isPartialSig sig
Nothing -> True ]
; traceTc "tcMonoBinds" $ vcat [ ppr n <+> ppr id <+> ppr (idType id)
| (n,id) <- rhs_id_env]
; binds' <- tcExtendLetEnvIds NotTopLevel rhs_id_env $
mapM (wrapLocM tcRhs) tc_binds
; return (listToBag binds', mono_infos) }
data TcMonoBind
= TcFunBind MonoBindInfo SrcSpan (MatchGroup Name (LHsExpr Name))
| TcPatBind [MonoBindInfo] (LPat TcId) (GRHSs Name (LHsExpr Name)) TcSigmaType
data MonoBindInfo = MBI { mbi_poly_name :: Name
, mbi_sig :: Maybe TcIdSigInfo
, mbi_mono_id :: TcId }
tcLhs :: TcSigFun -> LetBndrSpec -> HsBind Name -> TcM TcMonoBind
tcLhs sig_fn no_gen (FunBind { fun_id = L nm_loc name, fun_matches = matches })
| Just (TcIdSig sig) <- sig_fn name
, TISI { sig_tau = tau } <- sig
= ASSERT2( case no_gen of { LetLclBndr -> True; LetGblBndr {} -> False }
, ppr name )
do { mono_name <- newLocalName name
; let mono_id = mkLocalIdOrCoVar mono_name tau
; return (TcFunBind (MBI { mbi_poly_name = name
, mbi_sig = Just sig
, mbi_mono_id = mono_id })
nm_loc matches) }
| otherwise
= do { mono_ty <- newOpenFlexiTyVarTy
; mono_id <- newNoSigLetBndr no_gen name mono_ty
; return (TcFunBind (MBI { mbi_poly_name = name
, mbi_sig = Nothing
, mbi_mono_id = mono_id })
nm_loc matches) }
tcLhs sig_fn no_gen (PatBind { pat_lhs = pat, pat_rhs = grhss })
= do { let tc_pat exp_ty = tcLetPat sig_fn no_gen pat exp_ty $
mapM lookup_info (collectPatBinders pat)
lookup_info :: Name -> TcM MonoBindInfo
lookup_info name
= do { mono_id <- tcLookupId name
; let mb_sig = case sig_fn name of
Just (TcIdSig sig) -> Just sig
_ -> Nothing
; return (MBI { mbi_poly_name = name
, mbi_sig = mb_sig
, mbi_mono_id = mono_id }) }
; ((pat', infos), pat_ty) <- addErrCtxt (patMonoBindsCtxt pat grhss) $
tcInfer tc_pat
; return (TcPatBind infos pat' grhss pat_ty) }
tcLhs _ _ other_bind = pprPanic "tcLhs" (ppr other_bind)
tcRhs :: TcMonoBind -> TcM (HsBind TcId)
tcRhs (TcFunBind info@(MBI { mbi_sig = mb_sig, mbi_mono_id = mono_id })
loc matches)
= tcExtendIdBinderStackForRhs [info] $
tcExtendTyVarEnvForRhs mb_sig $
do { traceTc "tcRhs: fun bind" (ppr mono_id $$ ppr (idType mono_id))
; (co_fn, matches') <- tcMatchesFun (idName mono_id)
matches (mkCheckExpType $ idType mono_id)
; return ( FunBind { fun_id = L loc mono_id
, fun_matches = matches'
, fun_co_fn = co_fn
, bind_fvs = placeHolderNamesTc
, fun_tick = [] } ) }
tcRhs (TcPatBind infos pat' grhss pat_ty)
=
tcExtendIdBinderStackForRhs infos $
do { traceTc "tcRhs: pat bind" (ppr pat' $$ ppr pat_ty)
; grhss' <- addErrCtxt (patMonoBindsCtxt pat' grhss) $
tcGRHSsPat grhss pat_ty
; return ( PatBind { pat_lhs = pat', pat_rhs = grhss'
, pat_rhs_ty = pat_ty
, bind_fvs = placeHolderNamesTc
, pat_ticks = ([],[]) } )}
tcExtendTyVarEnvForRhs :: Maybe TcIdSigInfo -> TcM a -> TcM a
tcExtendTyVarEnvForRhs Nothing thing_inside
= thing_inside
tcExtendTyVarEnvForRhs (Just sig) thing_inside
= tcExtendTyVarEnvFromSig sig thing_inside
tcExtendTyVarEnvFromSig :: TcIdSigInfo -> TcM a -> TcM a
tcExtendTyVarEnvFromSig sig thing_inside
| TISI { sig_bndr = s_bndr, sig_skols = skol_prs, sig_ctxt = ctxt } <- sig
= tcExtendTyVarEnv2 skol_prs $
case s_bndr of
CompleteSig {} -> thing_inside
PartialSig { sig_wcs = wc_prs }
-> tcExtendTyVarEnv2 wc_prs $
do { addErrCtxt (typeSigCtxt ctxt s_bndr) $
emitWildCardHoleConstraints wc_prs
; thing_inside }
tcExtendIdBinderStackForRhs :: [MonoBindInfo] -> TcM a -> TcM a
tcExtendIdBinderStackForRhs infos thing_inside
= tcExtendIdBndrs [ TcIdBndr mono_id NotTopLevel
| MBI { mbi_mono_id = mono_id } <- infos ]
thing_inside
getMonoBindInfo :: [Located TcMonoBind] -> [MonoBindInfo]
getMonoBindInfo tc_binds
= foldr (get_info . unLoc) [] tc_binds
where
get_info (TcFunBind info _ _) rest = info : rest
get_info (TcPatBind infos _ _ _) rest = infos ++ rest
tcTySigs :: [LSig Name] -> TcM ([TcId], TcSigFun)
tcTySigs hs_sigs
= checkNoErrs $
do { ty_sigs_s <- mapAndRecoverM tcTySig hs_sigs
; let ty_sigs = concat ty_sigs_s
poly_ids = mapMaybe completeSigPolyId_maybe ty_sigs
env = mkNameEnv [(tcSigInfoName sig, sig) | sig <- ty_sigs]
; return (poly_ids, lookupNameEnv env) }
tcTySig :: LSig Name -> TcM [TcSigInfo]
tcTySig (L _ (IdSig id))
= do { sig <- instTcTySigFromId id
; return [TcIdSig sig] }
tcTySig (L loc (TypeSig names sig_ty))
= setSrcSpan loc $
do { sigs <- sequence [ tcUserTypeSig sig_ty (Just name)
| L _ name <- names ]
; return (map TcIdSig sigs) }
tcTySig (L loc (PatSynSig (L _ name) sig_ty))
= setSrcSpan loc $
do { tpsi <- tcPatSynSig name sig_ty
; return [TcPatSynSig tpsi] }
tcTySig _ = return []
isCompleteHsSig :: LHsSigWcType Name -> Bool
isCompleteHsSig sig_ty
| HsWC { hswc_wcs = wcs, hswc_ctx = extra } <- hsib_body sig_ty
, null wcs
, Nothing <- extra
= True
| otherwise
= False
tcUserTypeSig :: LHsSigWcType Name -> Maybe Name -> TcM TcIdSigInfo
tcUserTypeSig hs_sig_ty mb_name
| isCompleteHsSig hs_sig_ty
= pushTcLevelM_ $
do { sigma_ty <- tcHsSigWcType ctxt_F hs_sig_ty
; (inst_tvs, theta, tau) <- tcInstType tcInstSigTyVars sigma_ty
; loc <- getSrcSpanM
; return $
TISI { sig_bndr = CompleteSig (mkLocalId name sigma_ty)
, sig_skols = findScopedTyVars sigma_ty inst_tvs
, sig_theta = theta
, sig_tau = tau
, sig_ctxt = ctxt_T
, sig_loc = loc } }
| HsIB { hsib_vars = vars, hsib_body = wc_ty } <- hs_sig_ty
, HsWC { hswc_wcs = wcs, hswc_ctx = extra, hswc_body = hs_ty } <- wc_ty
, (hs_tvs, L _ hs_ctxt, hs_tau) <- splitLHsSigmaTy hs_ty
= do { (vars1, (wcs, tvs2, theta, tau))
<- pushTcLevelM_ $
solveEqualities $
tcImplicitTKBndrs vars $
tcWildCardBinders wcs $ \ wcs ->
tcExplicitTKBndrs hs_tvs $ \ tvs2 ->
do {
traceTc "tcPartial" (ppr name $$ ppr vars $$ ppr wcs)
; theta <- mapM tcLHsPredType $
case extra of
Nothing -> hs_ctxt
Just _ -> dropTail 1 hs_ctxt
; tau <- tcHsOpenType hs_tau
; theta <- zonkTcTypes theta
; tau <- zonkTcType tau
; let bound_tvs
= unionVarSets [ allBoundVariabless theta
, allBoundVariables tau
, mkVarSet (map snd wcs) ]
; return ((wcs, tvs2, theta, tau), bound_tvs) }
; loc <- getSrcSpanM
; return $
TISI { sig_bndr = PartialSig { sig_name = name, sig_hs_ty = hs_ty
, sig_cts = extra, sig_wcs = wcs }
, sig_skols = [ (tyVarName tv, tv) | tv <- vars1 ++ tvs2 ]
, sig_theta = theta
, sig_tau = tau
, sig_ctxt = ctxt_F
, sig_loc = loc } }
where
name = case mb_name of
Just n -> n
Nothing -> mkUnboundName (mkVarOcc "<expression>")
ctxt_F = case mb_name of
Just n -> FunSigCtxt n False
Nothing -> ExprSigCtxt
ctxt_T = case mb_name of
Just n -> FunSigCtxt n True
Nothing -> ExprSigCtxt
instTcTySigFromId :: Id -> TcM TcIdSigInfo
instTcTySigFromId id
= do { let name = idName id
loc = getSrcSpan name
; (tvs, theta, tau) <- tcInstType (tcInstSigTyVarsLoc loc)
(idType id)
; return $ TISI { sig_bndr = CompleteSig id
, sig_skols = [(tyVarName tv, tv) | tv <- tvs]
, sig_theta = theta
, sig_tau = tau
, sig_ctxt = FunSigCtxt name False
, sig_loc = loc } }
instTcTySig :: UserTypeCtxt
-> LHsSigType Name
-> TcType
-> Name
-> TcM TcIdSigInfo
instTcTySig ctxt hs_ty sigma_ty name
= do { (inst_tvs, theta, tau) <- tcInstType tcInstSigTyVars sigma_ty
; return (TISI { sig_bndr = CompleteSig (mkLocalIdOrCoVar name sigma_ty)
, sig_skols = findScopedTyVars sigma_ty inst_tvs
, sig_theta = theta
, sig_tau = tau
, sig_ctxt = ctxt
, sig_loc = getLoc (hsSigType hs_ty)
}) }
data GeneralisationPlan
= NoGen
| InferGen
Bool
| CheckGen (LHsBind Name) TcIdSigInfo
instance Outputable GeneralisationPlan where
ppr NoGen = text "NoGen"
ppr (InferGen b) = text "InferGen" <+> ppr b
ppr (CheckGen _ s) = text "CheckGen" <+> ppr s
decideGeneralisationPlan
:: DynFlags -> TcTypeEnv -> [Name]
-> [LHsBind Name] -> TcSigFun -> GeneralisationPlan
decideGeneralisationPlan dflags type_env bndr_names lbinds sig_fn
| unlifted_pat_binds = NoGen
| Just bind_sig <- one_funbind_with_sig = sig_plan bind_sig
| mono_local_binds = NoGen
| otherwise = InferGen mono_restriction
where
bndr_set = mkNameSet bndr_names
binds = map unLoc lbinds
sig_plan :: (LHsBind Name, TcIdSigInfo) -> GeneralisationPlan
sig_plan (lbind, sig@(TISI { sig_bndr = s_bndr, sig_theta = theta }))
= case s_bndr of
CompleteSig {} -> CheckGen lbind sig
PartialSig { sig_cts = extra_constraints }
| Nothing <- extra_constraints
, [] <- theta
-> InferGen True
| otherwise
-> InferGen False
unlifted_pat_binds = any isUnliftedHsBind binds
mono_restriction = xopt LangExt.MonomorphismRestriction dflags
&& any restricted binds
is_closed_ns :: NameSet -> Bool -> Bool
is_closed_ns ns b = foldNameSet ((&&) . is_closed_id) b ns
is_closed_id :: Name -> Bool
is_closed_id name
| name `elemNameSet` bndr_set
= True
| Just thing <- lookupNameEnv type_env name
= case thing of
ATcId { tct_closed = cl } -> isTopLevel cl
ATyVar {} -> False
AGlobal {} -> True
_ -> pprPanic "is_closed_id" (ppr name)
| otherwise
= WARN( isInternalName name, ppr name ) True
mono_local_binds = xopt LangExt.MonoLocalBinds dflags
&& not closed_flag
closed_flag = foldr (is_closed_ns . bind_fvs) True binds
no_sig n = noCompleteSig (sig_fn n)
one_funbind_with_sig
| [lbind@(L _ (FunBind { fun_id = v }))] <- lbinds
, Just (TcIdSig sig) <- sig_fn (unLoc v)
= Just (lbind, sig)
| otherwise
= Nothing
restricted (PatBind {}) = True
restricted (VarBind { var_id = v }) = no_sig v
restricted (FunBind { fun_id = v, fun_matches = m }) = restricted_match m
&& no_sig (unLoc v)
restricted (PatSynBind {}) = panic "isRestrictedGroup/unrestricted PatSynBind"
restricted (AbsBinds {}) = panic "isRestrictedGroup/unrestricted AbsBinds"
restricted (AbsBindsSig {}) = panic "isRestrictedGroup/unrestricted AbsBindsSig"
restricted_match (MG { mg_alts = L _ (L _ (Match _ [] _ _) : _ )}) = True
restricted_match _ = False
checkStrictBinds :: TopLevelFlag -> RecFlag
-> [LHsBind Name]
-> LHsBinds TcId -> [Id]
-> TcM ()
checkStrictBinds top_lvl rec_group orig_binds tc_binds poly_ids
| any_unlifted_bndr || any_strict_pat
= do { check (isNotTopLevel top_lvl)
(strictBindErr "Top-level" any_unlifted_bndr orig_binds)
; check (isNonRec rec_group)
(strictBindErr "Recursive" any_unlifted_bndr orig_binds)
; check (all is_monomorphic (bagToList tc_binds))
(polyBindErr orig_binds)
; check (isSingleton orig_binds)
(strictBindErr "Multiple" any_unlifted_bndr orig_binds)
; check (not any_pat_looks_lazy)
(unliftedMustBeBang orig_binds) }
| otherwise
= traceTc "csb2" (ppr [(id, idType id) | id <- poly_ids]) >>
return ()
where
any_unlifted_bndr = any is_unlifted poly_ids
any_strict_pat = any (isUnliftedHsBind . unLoc) orig_binds
any_pat_looks_lazy = any (looksLazyPatBind . unLoc) orig_binds
is_unlifted id = case tcSplitSigmaTy (idType id) of
(_, _, rho) -> isUnliftedType rho
is_monomorphic (L _ (AbsBinds { abs_tvs = tvs, abs_ev_vars = evs }))
= null tvs && null evs
is_monomorphic (L _ (AbsBindsSig { abs_tvs = tvs, abs_ev_vars = evs }))
= null tvs && null evs
is_monomorphic _ = True
check :: Bool -> MsgDoc -> TcM ()
check True _ = return ()
check False err = do { mod <- getModule
; checkTc (mod == gHC_PRIM) err }
unliftedMustBeBang :: [LHsBind Name] -> SDoc
unliftedMustBeBang binds
= hang (text "Pattern bindings containing unlifted types should use an outermost bang pattern:")
2 (vcat (map ppr binds))
polyBindErr :: [LHsBind Name] -> SDoc
polyBindErr binds
= hang (text "You can't mix polymorphic and unlifted bindings")
2 (vcat [vcat (map ppr binds),
text "Probable fix: add a type signature"])
strictBindErr :: String -> Bool -> [LHsBind Name] -> SDoc
strictBindErr flavour any_unlifted_bndr binds
= hang (text flavour <+> msg <+> text "aren't allowed:")
2 (vcat (map ppr binds))
where
msg | any_unlifted_bndr = text "bindings for unlifted types"
| otherwise = text "bang-pattern or unboxed-tuple bindings"
patMonoBindsCtxt :: (OutputableBndr id, Outputable body) => LPat id -> GRHSs Name body -> SDoc
patMonoBindsCtxt pat grhss
= hang (text "In a pattern binding:") 2 (pprPatBind pat grhss)
typeSigCtxt :: UserTypeCtxt -> TcIdSigBndr -> SDoc
typeSigCtxt ctxt (PartialSig { sig_hs_ty = hs_ty })
= pprSigCtxt ctxt empty (ppr hs_ty)
typeSigCtxt ctxt (CompleteSig id)
= pprSigCtxt ctxt empty (ppr (idType id))
instErrCtxt :: Name -> TcType -> TidyEnv -> TcM (TidyEnv, SDoc)
instErrCtxt name ty env
= do { let (env', ty') = tidyOpenType env ty
; return (env', hang (text "When instantiating" <+> quotes (ppr name) <>
text ", initially inferred to have" $$
text "this overly-general type:")
2 (ppr ty') $$
extra) }
where
extra = sdocWithDynFlags $ \dflags ->
ppWhen (xopt LangExt.MonomorphismRestriction dflags) $
text "NB: This instantiation can be caused by the" <+>
text "monomorphism restriction."