{-# LANGUAGE ScopedTypeVariables, BangPatterns #-}
module RnBinds (
rnTopBindsLHS, rnTopBindsBoot, rnValBindsRHS,
rnLocalBindsAndThen, rnLocalValBindsLHS, rnLocalValBindsRHS,
rnMethodBinds, renameSigs,
rnMatchGroup, rnGRHSs, rnGRHS,
makeMiniFixityEnv, MiniFixityEnv,
HsSigCtxt(..)
) where
import {-# SOURCE #-} RnExpr( rnLExpr, rnStmts )
import HsSyn
import TcRnMonad
import TcEvidence ( emptyTcEvBinds )
import RnTypes
import RnPat
import RnNames
import RnEnv
import DynFlags
import Module
import Name
import NameEnv
import NameSet
import RdrName ( RdrName, rdrNameOcc )
import SrcLoc
import ListSetOps ( findDupsEq )
import BasicTypes ( RecFlag(..), LexicalFixity(..) )
import Digraph ( SCC(..) )
import Bag
import Util
import Outputable
import FastString
import UniqSet
import Maybes ( orElse )
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
import Data.List ( partition, sort )
rnTopBindsLHS :: MiniFixityEnv
-> HsValBinds RdrName
-> RnM (HsValBindsLR Name RdrName)
rnTopBindsLHS fix_env binds
= rnValBindsLHS (topRecNameMaker fix_env) binds
rnTopBindsBoot :: NameSet -> HsValBindsLR Name RdrName -> RnM (HsValBinds Name, DefUses)
rnTopBindsBoot bound_names (ValBindsIn mbinds sigs)
= do { checkErr (isEmptyLHsBinds mbinds) (bindsInHsBootFile mbinds)
; (sigs', fvs) <- renameSigs (HsBootCtxt bound_names) sigs
; return (ValBindsOut [] sigs', usesOnly fvs) }
rnTopBindsBoot _ b = pprPanic "rnTopBindsBoot" (ppr b)
rnLocalBindsAndThen :: HsLocalBinds RdrName
-> (HsLocalBinds Name -> FreeVars -> RnM (result, FreeVars))
-> RnM (result, FreeVars)
rnLocalBindsAndThen EmptyLocalBinds thing_inside =
thing_inside EmptyLocalBinds emptyNameSet
rnLocalBindsAndThen (HsValBinds val_binds) thing_inside
= rnLocalValBindsAndThen val_binds $ \ val_binds' ->
thing_inside (HsValBinds val_binds')
rnLocalBindsAndThen (HsIPBinds binds) thing_inside = do
(binds',fv_binds) <- rnIPBinds binds
(thing, fvs_thing) <- thing_inside (HsIPBinds binds') fv_binds
return (thing, fvs_thing `plusFV` fv_binds)
rnIPBinds :: HsIPBinds RdrName -> RnM (HsIPBinds Name, FreeVars)
rnIPBinds (IPBinds ip_binds _no_dict_binds) = do
(ip_binds', fvs_s) <- mapAndUnzipM (wrapLocFstM rnIPBind) ip_binds
return (IPBinds ip_binds' emptyTcEvBinds, plusFVs fvs_s)
rnIPBind :: IPBind RdrName -> RnM (IPBind Name, FreeVars)
rnIPBind (IPBind ~(Left n) expr) = do
(expr',fvExpr) <- rnLExpr expr
return (IPBind (Left n) expr', fvExpr)
rnLocalValBindsLHS :: MiniFixityEnv
-> HsValBinds RdrName
-> RnM ([Name], HsValBindsLR Name RdrName)
rnLocalValBindsLHS fix_env binds
= do { binds' <- rnValBindsLHS (localRecNameMaker fix_env) binds
; let bound_names = collectHsValBinders binds'
; envs <- getRdrEnvs
; checkDupAndShadowedNames envs bound_names
; return (bound_names, binds') }
rnValBindsLHS :: NameMaker
-> HsValBinds RdrName
-> RnM (HsValBindsLR Name RdrName)
rnValBindsLHS topP (ValBindsIn mbinds sigs)
= do { mbinds' <- mapBagM (wrapLocM (rnBindLHS topP doc)) mbinds
; return $ ValBindsIn mbinds' sigs }
where
bndrs = collectHsBindsBinders mbinds
doc = text "In the binding group for:" <+> pprWithCommas ppr bndrs
rnValBindsLHS _ b = pprPanic "rnValBindsLHSFromDoc" (ppr b)
rnValBindsRHS :: HsSigCtxt
-> HsValBindsLR Name RdrName
-> RnM (HsValBinds Name, DefUses)
rnValBindsRHS ctxt (ValBindsIn mbinds sigs)
= do { (sigs', sig_fvs) <- renameSigs ctxt sigs
; binds_w_dus <- mapBagM (rnLBind (mkSigTvFn sigs')) mbinds
; let !(anal_binds, anal_dus) = depAnalBinds binds_w_dus
; let patsyn_fvs = foldr (unionNameSet . psb_fvs) emptyNameSet $
getPatSynBinds anal_binds
valbind'_dus = anal_dus `plusDU` usesOnly sig_fvs
`plusDU` usesOnly patsyn_fvs
; return (ValBindsOut anal_binds sigs', valbind'_dus) }
rnValBindsRHS _ b = pprPanic "rnValBindsRHS" (ppr b)
rnLocalValBindsRHS :: NameSet
-> HsValBindsLR Name RdrName
-> RnM (HsValBinds Name, DefUses)
rnLocalValBindsRHS bound_names binds
= rnValBindsRHS (LocalBindCtxt bound_names) binds
rnLocalValBindsAndThen
:: HsValBinds RdrName
-> (HsValBinds Name -> FreeVars -> RnM (result, FreeVars))
-> RnM (result, FreeVars)
rnLocalValBindsAndThen binds@(ValBindsIn _ sigs) thing_inside
= do {
new_fixities <- makeMiniFixityEnv [L loc sig
| L loc (FixSig sig) <- sigs]
; (bound_names, new_lhs) <- rnLocalValBindsLHS new_fixities binds
; bindLocalNamesFV bound_names $
addLocalFixities new_fixities bound_names $ do
{
(binds', dus) <- rnLocalValBindsRHS (mkNameSet bound_names) new_lhs
; (result, result_fvs) <- thing_inside binds' (allUses dus)
; let real_uses = findUses dus result_fvs
implicit_uses = hsValBindsImplicits binds'
; warnUnusedLocalBinds bound_names
(real_uses `unionNameSet` implicit_uses)
; let
all_uses = allUses dus `plusFV` result_fvs
; return (result, all_uses) }}
rnLocalValBindsAndThen bs _ = pprPanic "rnLocalValBindsAndThen" (ppr bs)
rnBindLHS :: NameMaker
-> SDoc
-> HsBind RdrName
-> RnM (HsBindLR Name RdrName)
rnBindLHS name_maker _ bind@(PatBind { pat_lhs = pat })
= do
(pat',pat'_fvs) <- rnBindPat name_maker pat
return (bind { pat_lhs = pat', bind_fvs = pat'_fvs })
rnBindLHS name_maker _ bind@(FunBind { fun_id = rdr_name })
= do { name <- applyNameMaker name_maker rdr_name
; return (bind { fun_id = name
, bind_fvs = placeHolderNamesTc }) }
rnBindLHS name_maker _ (PatSynBind psb@PSB{ psb_id = rdrname })
| isTopRecNameMaker name_maker
= do { addLocM checkConName rdrname
; name <- lookupLocatedTopBndrRn rdrname
; return (PatSynBind psb{ psb_id = name }) }
| otherwise
= do { addErr localPatternSynonymErr
; name <- applyNameMaker name_maker rdrname
; return (PatSynBind psb{ psb_id = name }) }
where
localPatternSynonymErr :: SDoc
localPatternSynonymErr
= hang (text "Illegal pattern synonym declaration for" <+> quotes (ppr rdrname))
2 (text "Pattern synonym declarations are only valid at top level")
rnBindLHS _ _ b = pprPanic "rnBindHS" (ppr b)
rnLBind :: (Name -> [Name])
-> LHsBindLR Name RdrName
-> RnM (LHsBind Name, [Name], Uses)
rnLBind sig_fn (L loc bind)
= setSrcSpan loc $
do { (bind', bndrs, dus) <- rnBind sig_fn bind
; return (L loc bind', bndrs, dus) }
rnBind :: (Name -> [Name])
-> HsBindLR Name RdrName
-> RnM (HsBind Name, [Name], Uses)
rnBind _ bind@(PatBind { pat_lhs = pat
, pat_rhs = grhss
, bind_fvs = pat_fvs })
= do { mod <- getModule
; (grhss', rhs_fvs) <- rnGRHSs PatBindRhs rnLExpr grhss
; let all_fvs = pat_fvs `plusFV` rhs_fvs
fvs' = filterNameSet (nameIsLocalOrFrom mod) all_fvs
bndrs = collectPatBinders pat
bind' = bind { pat_rhs = grhss',
pat_rhs_ty = placeHolderType, bind_fvs = fvs' }
is_wild_pat = case pat of
L _ (WildPat {}) -> True
L _ (BangPat (L _ (WildPat {}))) -> True
_ -> False
; whenWOptM Opt_WarnUnusedPatternBinds $
when (null bndrs && not is_wild_pat) $
addWarn (Reason Opt_WarnUnusedPatternBinds) $ unusedPatBindWarn bind'
; fvs' `seq`
return (bind', bndrs, all_fvs) }
rnBind sig_fn bind@(FunBind { fun_id = name
, fun_matches = matches })
= do { let plain_name = unLoc name
; (matches', rhs_fvs) <- bindSigTyVarsFV (sig_fn plain_name) $
rnMatchGroup (mkPrefixFunRhs name)
rnLExpr matches
; let is_infix = isInfixFunBind bind
; when is_infix $ checkPrecMatch plain_name matches'
; mod <- getModule
; let fvs' = filterNameSet (nameIsLocalOrFrom mod) rhs_fvs
; fvs' `seq`
return (bind { fun_matches = matches'
, bind_fvs = fvs' },
[plain_name], rhs_fvs)
}
rnBind sig_fn (PatSynBind bind)
= do { (bind', name, fvs) <- rnPatSynBind sig_fn bind
; return (PatSynBind bind', name, fvs) }
rnBind _ b = pprPanic "rnBind" (ppr b)
depAnalBinds :: Bag (LHsBind Name, [Name], Uses)
-> ([(RecFlag, LHsBinds Name)], DefUses)
depAnalBinds binds_w_dus
= (map get_binds sccs, map get_du sccs)
where
sccs = depAnal (\(_, defs, _) -> defs)
(\(_, _, uses) -> nonDetEltsUniqSet uses)
(bagToList binds_w_dus)
get_binds (AcyclicSCC (bind, _, _)) = (NonRecursive, unitBag bind)
get_binds (CyclicSCC binds_w_dus) = (Recursive, listToBag [b | (b,_,_) <- binds_w_dus])
get_du (AcyclicSCC (_, bndrs, uses)) = (Just (mkNameSet bndrs), uses)
get_du (CyclicSCC binds_w_dus) = (Just defs, uses)
where
defs = mkNameSet [b | (_,bs,_) <- binds_w_dus, b <- bs]
uses = unionNameSets [u | (_,_,u) <- binds_w_dus]
mkSigTvFn :: [LSig Name] -> (Name -> [Name])
mkSigTvFn sigs = \n -> lookupNameEnv env n `orElse` []
where
env = mkHsSigEnv get_scoped_tvs sigs
get_scoped_tvs :: LSig Name -> Maybe ([Located Name], [Name])
get_scoped_tvs (L _ (ClassOpSig _ names sig_ty))
= Just (names, hsScopedTvs sig_ty)
get_scoped_tvs (L _ (TypeSig names sig_ty))
= Just (names, hsWcScopedTvs sig_ty)
get_scoped_tvs (L _ (PatSynSig names sig_ty))
= Just (names, hsScopedTvs sig_ty)
get_scoped_tvs _ = Nothing
makeMiniFixityEnv :: [LFixitySig RdrName] -> RnM MiniFixityEnv
makeMiniFixityEnv decls = foldlM add_one_sig emptyFsEnv decls
where
add_one_sig env (L loc (FixitySig names fixity)) =
foldlM add_one env [ (loc,name_loc,name,fixity)
| L name_loc name <- names ]
add_one env (loc, name_loc, name,fixity) = do
{
let { fs = occNameFS (rdrNameOcc name)
; fix_item = L loc fixity };
case lookupFsEnv env fs of
Nothing -> return $ extendFsEnv env fs fix_item
Just (L loc' _) -> do
{ setSrcSpan loc $
addErrAt name_loc (dupFixityDecl loc' name)
; return env}
}
dupFixityDecl :: SrcSpan -> RdrName -> SDoc
dupFixityDecl loc rdr_name
= vcat [text "Multiple fixity declarations for" <+> quotes (ppr rdr_name),
text "also at " <+> ppr loc]
rnPatSynBind :: (Name -> [Name])
-> PatSynBind Name RdrName
-> RnM (PatSynBind Name Name, [Name], Uses)
rnPatSynBind sig_fn bind@(PSB { psb_id = L l name
, psb_args = details
, psb_def = pat
, psb_dir = dir })
= do { pattern_synonym_ok <- xoptM LangExt.PatternSynonyms
; unless pattern_synonym_ok (addErr patternSynonymErr)
; let sig_tvs = sig_fn name
; ((pat', details'), fvs1) <- bindSigTyVarsFV sig_tvs $
rnPat PatSyn pat $ \pat' ->
case details of
PrefixPatSyn vars ->
do { checkDupRdrNames vars
; names <- mapM lookupVar vars
; return ( (pat', PrefixPatSyn names)
, mkFVs (map unLoc names)) }
InfixPatSyn var1 var2 ->
do { checkDupRdrNames [var1, var2]
; name1 <- lookupVar var1
; name2 <- lookupVar var2
; return ( (pat', InfixPatSyn name1 name2)
, mkFVs (map unLoc [name1, name2])) }
RecordPatSyn vars ->
do { checkDupRdrNames (map recordPatSynSelectorId vars)
; let rnRecordPatSynField
(RecordPatSynField { recordPatSynSelectorId = visible
, recordPatSynPatVar = hidden })
= do { visible' <- lookupLocatedTopBndrRn visible
; hidden' <- lookupVar hidden
; return $ RecordPatSynField { recordPatSynSelectorId = visible'
, recordPatSynPatVar = hidden' } }
; names <- mapM rnRecordPatSynField vars
; return ( (pat', RecordPatSyn names)
, mkFVs (map (unLoc . recordPatSynPatVar) names)) }
; (dir', fvs2) <- case dir of
Unidirectional -> return (Unidirectional, emptyFVs)
ImplicitBidirectional -> return (ImplicitBidirectional, emptyFVs)
ExplicitBidirectional mg ->
do { (mg', fvs) <- bindSigTyVarsFV sig_tvs $
rnMatchGroup (mkPrefixFunRhs (L l name))
rnLExpr mg
; return (ExplicitBidirectional mg', fvs) }
; mod <- getModule
; let fvs = fvs1 `plusFV` fvs2
fvs' = filterNameSet (nameIsLocalOrFrom mod) fvs
bind' = bind{ psb_args = details'
, psb_def = pat'
, psb_dir = dir'
, psb_fvs = fvs' }
selector_names = case details' of
RecordPatSyn names ->
map (unLoc . recordPatSynSelectorId) names
_ -> []
; fvs' `seq`
return (bind', name : selector_names , fvs1)
}
where
lookupVar = wrapLocM lookupOccRn
patternSynonymErr :: SDoc
patternSynonymErr
= hang (text "Illegal pattern synonym declaration")
2 (text "Use -XPatternSynonyms to enable this extension")
rnMethodBinds :: Bool
-> Name
-> [Name]
-> LHsBinds RdrName
-> [LSig RdrName]
-> RnM (LHsBinds Name, [LSig Name], FreeVars)
rnMethodBinds is_cls_decl cls ktv_names binds sigs
= do { checkDupRdrNames (collectMethodBinders binds)
; binds' <- foldrBagM (rnMethodBindLHS is_cls_decl cls) emptyBag binds
; let (spec_inst_prags, other_sigs) = partition isSpecInstLSig sigs
bound_nms = mkNameSet (collectHsBindsBinders binds')
sig_ctxt | is_cls_decl = ClsDeclCtxt cls
| otherwise = InstDeclCtxt bound_nms
; (spec_inst_prags', sip_fvs) <- renameSigs sig_ctxt spec_inst_prags
; (other_sigs', sig_fvs) <- extendTyVarEnvFVRn ktv_names $
renameSigs sig_ctxt other_sigs
; scoped_tvs <- xoptM LangExt.ScopedTypeVariables
; (binds'', bind_fvs) <- maybe_extend_tyvar_env scoped_tvs $
do { binds_w_dus <- mapBagM (rnLBind (mkSigTvFn other_sigs')) binds'
; let bind_fvs = foldrBag (\(_,_,fv1) fv2 -> fv1 `plusFV` fv2)
emptyFVs binds_w_dus
; return (mapBag fstOf3 binds_w_dus, bind_fvs) }
; return ( binds'', spec_inst_prags' ++ other_sigs'
, sig_fvs `plusFV` sip_fvs `plusFV` bind_fvs) }
where
maybe_extend_tyvar_env scoped_tvs thing_inside
| scoped_tvs = extendTyVarEnvFVRn ktv_names thing_inside
| otherwise = thing_inside
rnMethodBindLHS :: Bool -> Name
-> LHsBindLR RdrName RdrName
-> LHsBindsLR Name RdrName
-> RnM (LHsBindsLR Name RdrName)
rnMethodBindLHS _ cls (L loc bind@(FunBind { fun_id = name })) rest
= setSrcSpan loc $ do
do { sel_name <- wrapLocM (lookupInstDeclBndr cls (text "method")) name
; let bind' = bind { fun_id = sel_name
, bind_fvs = placeHolderNamesTc }
; return (L loc bind' `consBag` rest ) }
rnMethodBindLHS is_cls_decl _ (L loc bind) rest
= do { addErrAt loc $
vcat [ what <+> text "not allowed in" <+> decl_sort
, nest 2 (ppr bind) ]
; return rest }
where
decl_sort | is_cls_decl = text "class declaration:"
| otherwise = text "instance declaration:"
what = case bind of
PatBind {} -> text "Pattern bindings (except simple variables)"
PatSynBind {} -> text "Pattern synonyms"
_ -> pprPanic "rnMethodBind" (ppr bind)
renameSigs :: HsSigCtxt
-> [LSig RdrName]
-> RnM ([LSig Name], FreeVars)
renameSigs ctxt sigs
= do { mapM_ dupSigDeclErr (findDupSigs sigs)
; checkDupMinimalSigs sigs
; (sigs', sig_fvs) <- mapFvRn (wrapLocFstM (renameSig ctxt)) sigs
; let (good_sigs, bad_sigs) = partition (okHsSig ctxt) sigs'
; mapM_ misplacedSigErr bad_sigs
; return (good_sigs, sig_fvs) }
renameSig :: HsSigCtxt -> Sig RdrName -> RnM (Sig Name, FreeVars)
renameSig _ (IdSig x)
= return (IdSig x, emptyFVs)
renameSig ctxt sig@(TypeSig vs ty)
= do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs
; let doc = TypeSigCtx (ppr_sig_bndrs vs)
; (new_ty, fvs) <- rnHsSigWcType doc ty
; return (TypeSig new_vs new_ty, fvs) }
renameSig ctxt sig@(ClassOpSig is_deflt vs ty)
= do { defaultSigs_on <- xoptM LangExt.DefaultSignatures
; when (is_deflt && not defaultSigs_on) $
addErr (defaultSigErr sig)
; new_v <- mapM (lookupSigOccRn ctxt sig) vs
; (new_ty, fvs) <- rnHsSigType ty_ctxt ty
; return (ClassOpSig is_deflt new_v new_ty, fvs) }
where
(v1:_) = vs
ty_ctxt = GenericCtx (text "a class method signature for"
<+> quotes (ppr v1))
renameSig _ (SpecInstSig src ty)
= do { (new_ty, fvs) <- rnHsSigType SpecInstSigCtx ty
; return (SpecInstSig src new_ty,fvs) }
renameSig ctxt sig@(SpecSig v tys inl)
= do { new_v <- case ctxt of
TopSigCtxt {} -> lookupLocatedOccRn v
_ -> lookupSigOccRn ctxt sig v
; (new_ty, fvs) <- foldM do_one ([],emptyFVs) tys
; return (SpecSig new_v new_ty inl, fvs) }
where
ty_ctxt = GenericCtx (text "a SPECIALISE signature for"
<+> quotes (ppr v))
do_one (tys,fvs) ty
= do { (new_ty, fvs_ty) <- rnHsSigType ty_ctxt ty
; return ( new_ty:tys, fvs_ty `plusFV` fvs) }
renameSig ctxt sig@(InlineSig v s)
= do { new_v <- lookupSigOccRn ctxt sig v
; return (InlineSig new_v s, emptyFVs) }
renameSig ctxt sig@(FixSig (FixitySig vs f))
= do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs
; return (FixSig (FixitySig new_vs f), emptyFVs) }
renameSig ctxt sig@(MinimalSig s (L l bf))
= do new_bf <- traverse (lookupSigOccRn ctxt sig) bf
return (MinimalSig s (L l new_bf), emptyFVs)
renameSig ctxt sig@(PatSynSig vs ty)
= do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs
; (ty', fvs) <- rnHsSigType ty_ctxt ty
; return (PatSynSig new_vs ty', fvs) }
where
ty_ctxt = GenericCtx (text "a pattern synonym signature for"
<+> ppr_sig_bndrs vs)
renameSig ctxt sig@(SCCFunSig st v s)
= do { new_v <- lookupSigOccRn ctxt sig v
; return (SCCFunSig st new_v s, emptyFVs) }
renameSig _ctxt sig@(CompleteMatchSig s (L l bf) mty)
= do new_bf <- traverse lookupLocatedOccRn bf
new_mty <- traverse lookupLocatedOccRn mty
this_mod <- fmap tcg_mod getGblEnv
unless (any (nameIsLocalOrFrom this_mod . unLoc) new_bf) $ do
addErrCtxt (text "In" <+> ppr sig) $ failWithTc orphanError
return (CompleteMatchSig s (L l new_bf) new_mty, emptyFVs)
where
orphanError :: SDoc
orphanError =
text "Orphan COMPLETE pragmas not supported" $$
text "A COMPLETE pragma must mention at least one data constructor" $$
text "or pattern synonym defined in the same module."
ppr_sig_bndrs :: [Located RdrName] -> SDoc
ppr_sig_bndrs bs = quotes (pprWithCommas ppr bs)
okHsSig :: HsSigCtxt -> LSig a -> Bool
okHsSig ctxt (L _ sig)
= case (sig, ctxt) of
(ClassOpSig {}, ClsDeclCtxt {}) -> True
(ClassOpSig {}, InstDeclCtxt {}) -> True
(ClassOpSig {}, _) -> False
(TypeSig {}, ClsDeclCtxt {}) -> False
(TypeSig {}, InstDeclCtxt {}) -> False
(TypeSig {}, _) -> True
(PatSynSig {}, TopSigCtxt{}) -> True
(PatSynSig {}, _) -> False
(FixSig {}, InstDeclCtxt {}) -> False
(FixSig {}, _) -> True
(IdSig {}, TopSigCtxt {}) -> True
(IdSig {}, InstDeclCtxt {}) -> True
(IdSig {}, _) -> False
(InlineSig {}, HsBootCtxt {}) -> False
(InlineSig {}, _) -> True
(SpecSig {}, TopSigCtxt {}) -> True
(SpecSig {}, LocalBindCtxt {}) -> True
(SpecSig {}, InstDeclCtxt {}) -> True
(SpecSig {}, _) -> False
(SpecInstSig {}, InstDeclCtxt {}) -> True
(SpecInstSig {}, _) -> False
(MinimalSig {}, ClsDeclCtxt {}) -> True
(MinimalSig {}, _) -> False
(SCCFunSig {}, HsBootCtxt {}) -> False
(SCCFunSig {}, _) -> True
(CompleteMatchSig {}, TopSigCtxt {} ) -> True
(CompleteMatchSig {}, _) -> False
findDupSigs :: [LSig RdrName] -> [[(Located RdrName, Sig RdrName)]]
findDupSigs sigs
= findDupsEq matching_sig (concatMap (expand_sig . unLoc) sigs)
where
expand_sig sig@(FixSig (FixitySig ns _)) = zip ns (repeat sig)
expand_sig sig@(InlineSig n _) = [(n,sig)]
expand_sig sig@(TypeSig ns _) = [(n,sig) | n <- ns]
expand_sig sig@(ClassOpSig _ ns _) = [(n,sig) | n <- ns]
expand_sig sig@(PatSynSig ns _ ) = [(n,sig) | n <- ns]
expand_sig sig@(SCCFunSig _ n _) = [(n,sig)]
expand_sig _ = []
matching_sig (L _ n1,sig1) (L _ n2,sig2) = n1 == n2 && mtch sig1 sig2
mtch (FixSig {}) (FixSig {}) = True
mtch (InlineSig {}) (InlineSig {}) = True
mtch (TypeSig {}) (TypeSig {}) = True
mtch (ClassOpSig d1 _ _) (ClassOpSig d2 _ _) = d1 == d2
mtch (PatSynSig _ _) (PatSynSig _ _) = True
mtch (SCCFunSig{}) (SCCFunSig{}) = True
mtch _ _ = False
checkDupMinimalSigs :: [LSig RdrName] -> RnM ()
checkDupMinimalSigs sigs
= case filter isMinimalLSig sigs of
minSigs@(_:_:_) -> dupMinimalSigErr minSigs
_ -> return ()
rnMatchGroup :: Outputable (body RdrName) => HsMatchContext Name
-> (Located (body RdrName) -> RnM (Located (body Name), FreeVars))
-> MatchGroup RdrName (Located (body RdrName))
-> RnM (MatchGroup Name (Located (body Name)), FreeVars)
rnMatchGroup ctxt rnBody (MG { mg_alts = L _ ms, mg_origin = origin })
= do { empty_case_ok <- xoptM LangExt.EmptyCase
; when (null ms && not empty_case_ok) (addErr (emptyCaseErr ctxt))
; (new_ms, ms_fvs) <- mapFvRn (rnMatch ctxt rnBody) ms
; return (mkMatchGroup origin new_ms, ms_fvs) }
rnMatch :: Outputable (body RdrName) => HsMatchContext Name
-> (Located (body RdrName) -> RnM (Located (body Name), FreeVars))
-> LMatch RdrName (Located (body RdrName))
-> RnM (LMatch Name (Located (body Name)), FreeVars)
rnMatch ctxt rnBody = wrapLocFstM (rnMatch' ctxt rnBody)
rnMatch' :: Outputable (body RdrName) => HsMatchContext Name
-> (Located (body RdrName) -> RnM (Located (body Name), FreeVars))
-> Match RdrName (Located (body RdrName))
-> RnM (Match Name (Located (body Name)), FreeVars)
rnMatch' ctxt rnBody match@(Match { m_ctxt = mf, m_pats = pats
, m_type = maybe_rhs_sig, m_grhss = grhss })
= do {
case maybe_rhs_sig of
Nothing -> return ()
Just (L loc ty) -> addErrAt loc (resSigErr match ty)
; let fixity = if isInfixMatch match then Infix else Prefix
; rnPats ctxt pats $ \ pats' -> do
{ (grhss', grhss_fvs) <- rnGRHSs ctxt rnBody grhss
; let mf' = case (ctxt,mf) of
(FunRhs (L _ funid) _ _,FunRhs (L lf _) _ strict)
-> FunRhs (L lf funid) fixity strict
_ -> ctxt
; return (Match { m_ctxt = mf', m_pats = pats'
, m_type = Nothing, m_grhss = grhss'}, grhss_fvs ) }}
emptyCaseErr :: HsMatchContext Name -> SDoc
emptyCaseErr ctxt = hang (text "Empty list of alternatives in" <+> pp_ctxt)
2 (text "Use EmptyCase to allow this")
where
pp_ctxt = case ctxt of
CaseAlt -> text "case expression"
LambdaExpr -> text "\\case expression"
_ -> text "(unexpected)" <+> pprMatchContextNoun ctxt
resSigErr :: Outputable body
=> Match RdrName body -> HsType RdrName -> SDoc
resSigErr match ty
= vcat [ text "Illegal result type signature" <+> quotes (ppr ty)
, nest 2 $ ptext (sLit
"Result signatures are no longer supported in pattern matches")
, pprMatchInCtxt match ]
rnGRHSs :: HsMatchContext Name
-> (Located (body RdrName) -> RnM (Located (body Name), FreeVars))
-> GRHSs RdrName (Located (body RdrName))
-> RnM (GRHSs Name (Located (body Name)), FreeVars)
rnGRHSs ctxt rnBody (GRHSs grhss (L l binds))
= rnLocalBindsAndThen binds $ \ binds' _ -> do
(grhss', fvGRHSs) <- mapFvRn (rnGRHS ctxt rnBody) grhss
return (GRHSs grhss' (L l binds'), fvGRHSs)
rnGRHS :: HsMatchContext Name
-> (Located (body RdrName) -> RnM (Located (body Name), FreeVars))
-> LGRHS RdrName (Located (body RdrName))
-> RnM (LGRHS Name (Located (body Name)), FreeVars)
rnGRHS ctxt rnBody = wrapLocFstM (rnGRHS' ctxt rnBody)
rnGRHS' :: HsMatchContext Name
-> (Located (body RdrName) -> RnM (Located (body Name), FreeVars))
-> GRHS RdrName (Located (body RdrName))
-> RnM (GRHS Name (Located (body Name)), FreeVars)
rnGRHS' ctxt rnBody (GRHS guards rhs)
= do { pattern_guards_allowed <- xoptM LangExt.PatternGuards
; ((guards', rhs'), fvs) <- rnStmts (PatGuard ctxt) rnLExpr guards $ \ _ ->
rnBody rhs
; unless (pattern_guards_allowed || is_standard_guard guards')
(addWarn NoReason (nonStdGuardErr guards'))
; return (GRHS guards' rhs', fvs) }
where
is_standard_guard [] = True
is_standard_guard [L _ (BodyStmt _ _ _ _)] = True
is_standard_guard _ = False
dupSigDeclErr :: [(Located RdrName, Sig RdrName)] -> RnM ()
dupSigDeclErr pairs@((L loc name, sig) : _)
= addErrAt loc $
vcat [ text "Duplicate" <+> what_it_is
<> text "s for" <+> quotes (ppr name)
, text "at" <+> vcat (map ppr $ sort $ map (getLoc . fst) pairs) ]
where
what_it_is = hsSigDoc sig
dupSigDeclErr [] = panic "dupSigDeclErr"
misplacedSigErr :: LSig Name -> RnM ()
misplacedSigErr (L loc sig)
= addErrAt loc $
sep [text "Misplaced" <+> hsSigDoc sig <> colon, ppr sig]
defaultSigErr :: Sig RdrName -> SDoc
defaultSigErr sig = vcat [ hang (text "Unexpected default signature:")
2 (ppr sig)
, text "Use DefaultSignatures to enable default signatures" ]
bindsInHsBootFile :: LHsBindsLR Name RdrName -> SDoc
bindsInHsBootFile mbinds
= hang (text "Bindings in hs-boot files are not allowed")
2 (ppr mbinds)
nonStdGuardErr :: Outputable body => [LStmtLR Name Name body] -> SDoc
nonStdGuardErr guards
= hang (text "accepting non-standard pattern guards (use PatternGuards to suppress this message)")
4 (interpp'SP guards)
unusedPatBindWarn :: HsBind Name -> SDoc
unusedPatBindWarn bind
= hang (text "This pattern-binding binds no variables:")
2 (ppr bind)
dupMinimalSigErr :: [LSig RdrName] -> RnM ()
dupMinimalSigErr sigs@(L loc _ : _)
= addErrAt loc $
vcat [ text "Multiple minimal complete definitions"
, text "at" <+> vcat (map ppr $ sort $ map getLoc sigs)
, text "Combine alternative minimal complete definitions with `|'" ]
dupMinimalSigErr [] = panic "dupMinimalSigErr"