module GHC.Rename.Bind (
rnTopBindsLHS, rnTopBindsBoot, rnValBindsRHS,
rnLocalBindsAndThen, rnLocalValBindsLHS, rnLocalValBindsRHS,
rnMethodBinds, renameSigs,
rnMatchGroup, rnGRHSs, rnGRHS, rnSrcFixityDecl,
makeMiniFixityEnv, MiniFixityEnv,
HsSigCtxt(..)
) where
import GHC.Prelude
import GHC.Rename.Expr( rnExpr, rnLExpr, rnStmts )
import GHC.Hs
import GHC.Tc.Utils.Monad
import GHC.Rename.HsType
import GHC.Rename.Pat
import GHC.Rename.Names
import GHC.Rename.Env
import GHC.Rename.Fixity
import GHC.Rename.Utils ( HsDocContext(..), mapFvRn
, checkDupRdrNames, checkDupRdrNamesN, warnUnusedLocalBinds
, checkUnusedRecordWildcard
, checkDupAndShadowedNames, bindLocalNamesFV
, addNoNestedForallsContextsErr, checkInferredVars )
import GHC.Driver.Session
import GHC.Unit.Module
import GHC.Types.FieldLabel
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Types.Name.Set
import GHC.Types.Name.Reader ( RdrName, rdrNameOcc )
import GHC.Types.SrcLoc as SrcLoc
import GHC.Data.List.SetOps ( findDupsEq )
import GHC.Types.Basic ( RecFlag(..), TypeOrKind(..) )
import GHC.Data.Graph.Directed ( SCC(..) )
import GHC.Data.Bag
import GHC.Utils.Misc
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Types.Unique.Set
import GHC.Data.Maybe ( orElse )
import GHC.Data.OrdList
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
import Data.Foldable ( toList )
import Data.List ( partition, sortBy )
import Data.List.NonEmpty ( NonEmpty(..) )
rnTopBindsLHS :: MiniFixityEnv
-> HsValBinds GhcPs
-> RnM (HsValBindsLR GhcRn GhcPs)
rnTopBindsLHS fix_env binds
= rnValBindsLHS (topRecNameMaker fix_env) binds
rnTopBindsBoot :: NameSet -> HsValBindsLR GhcRn GhcPs
-> RnM (HsValBinds GhcRn, DefUses)
rnTopBindsBoot bound_names (ValBinds _ mbinds sigs)
= do { checkErr (isEmptyLHsBinds mbinds) (bindsInHsBootFile mbinds)
; (sigs', fvs) <- renameSigs (HsBootCtxt bound_names) sigs
; return (XValBindsLR (NValBinds [] sigs'), usesOnly fvs) }
rnTopBindsBoot _ b = pprPanic "rnTopBindsBoot" (ppr b)
rnLocalBindsAndThen :: HsLocalBinds GhcPs
-> (HsLocalBinds GhcRn -> FreeVars -> RnM (result, FreeVars))
-> RnM (result, FreeVars)
rnLocalBindsAndThen (EmptyLocalBinds x) thing_inside =
thing_inside (EmptyLocalBinds x) emptyNameSet
rnLocalBindsAndThen (HsValBinds x val_binds) thing_inside
= rnLocalValBindsAndThen val_binds $ \ val_binds' ->
thing_inside (HsValBinds x val_binds')
rnLocalBindsAndThen (HsIPBinds x binds) thing_inside = do
(binds',fv_binds) <- rnIPBinds binds
(thing, fvs_thing) <- thing_inside (HsIPBinds x binds') fv_binds
return (thing, fvs_thing `plusFV` fv_binds)
rnIPBinds :: HsIPBinds GhcPs -> RnM (HsIPBinds GhcRn, FreeVars)
rnIPBinds (IPBinds _ ip_binds ) = do
(ip_binds', fvs_s) <- mapAndUnzipM (wrapLocFstMA rnIPBind) ip_binds
return (IPBinds noExtField ip_binds', plusFVs fvs_s)
rnIPBind :: IPBind GhcPs -> RnM (IPBind GhcRn, FreeVars)
rnIPBind (IPBind _ ~(Left n) expr) = do
(expr',fvExpr) <- rnLExpr expr
return (IPBind noAnn (Left n) expr', fvExpr)
rnLocalValBindsLHS :: MiniFixityEnv
-> HsValBinds GhcPs
-> RnM ([Name], HsValBindsLR GhcRn GhcPs)
rnLocalValBindsLHS fix_env binds
= do { binds' <- rnValBindsLHS (localRecNameMaker fix_env) binds
; let bound_names = collectHsValBinders CollNoDictBinders binds'
; envs <- getRdrEnvs
; checkDupAndShadowedNames envs bound_names
; return (bound_names, binds') }
rnValBindsLHS :: NameMaker
-> HsValBinds GhcPs
-> RnM (HsValBindsLR GhcRn GhcPs)
rnValBindsLHS topP (ValBinds x mbinds sigs)
= do { mbinds' <- mapBagM (wrapLocMA (rnBindLHS topP doc)) mbinds
; return $ ValBinds x mbinds' sigs }
where
bndrs = collectHsBindsBinders CollNoDictBinders mbinds
doc = text "In the binding group for:" <+> pprWithCommas ppr bndrs
rnValBindsLHS _ b = pprPanic "rnValBindsLHSFromDoc" (ppr b)
rnValBindsRHS :: HsSigCtxt
-> HsValBindsLR GhcRn GhcPs
-> RnM (HsValBinds GhcRn, DefUses)
rnValBindsRHS ctxt (ValBinds _ mbinds sigs)
= do { (sigs', sig_fvs) <- renameSigs ctxt sigs
; binds_w_dus <- mapBagM (rnLBind (mkScopedTvFn sigs')) mbinds
; let !(anal_binds, anal_dus) = depAnalBinds binds_w_dus
; let patsyn_fvs = foldr (unionNameSet . psb_ext) emptyNameSet $
getPatSynBinds anal_binds
valbind'_dus = anal_dus `plusDU` usesOnly sig_fvs
`plusDU` usesOnly patsyn_fvs
; return (XValBindsLR (NValBinds anal_binds sigs'), valbind'_dus) }
rnValBindsRHS _ b = pprPanic "rnValBindsRHS" (ppr b)
rnLocalValBindsRHS :: NameSet
-> HsValBindsLR GhcRn GhcPs
-> RnM (HsValBinds GhcRn, DefUses)
rnLocalValBindsRHS bound_names binds
= rnValBindsRHS (LocalBindCtxt bound_names) binds
rnLocalValBindsAndThen
:: HsValBinds GhcPs
-> (HsValBinds GhcRn -> FreeVars -> RnM (result, FreeVars))
-> RnM (result, FreeVars)
rnLocalValBindsAndThen binds@(ValBinds _ _ 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
rec_uses = hsValBindsImplicits binds'
implicit_uses = mkNameSet $ concatMap snd
$ rec_uses
; mapM_ (\(loc, ns) ->
checkUnusedRecordWildcard loc real_uses (Just ns))
rec_uses
; 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 GhcPs
-> RnM (HsBindLR GhcRn GhcPs)
rnBindLHS name_maker _ bind@(PatBind { pat_lhs = pat })
= do
(pat',pat'_fvs) <- rnBindPat name_maker pat
return (bind { pat_lhs = pat', pat_ext = pat'_fvs })
rnBindLHS name_maker _ bind@(FunBind { fun_id = rdr_name })
= do { name <- applyNameMaker name_maker rdr_name
; return (bind { fun_id = name
, fun_ext = noExtField }) }
rnBindLHS name_maker _ (PatSynBind x psb@PSB{ psb_id = rdrname })
| isTopRecNameMaker name_maker
= do { addLocMA checkConName rdrname
; name <- lookupLocatedTopBndrRnN rdrname
; return (PatSynBind x psb{ psb_ext = noAnn, psb_id = name }) }
| otherwise
= do { addErr localPatternSynonymErr
; name <- applyNameMaker name_maker rdrname
; return (PatSynBind x psb{ psb_ext = noAnn, 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 GhcRn GhcPs
-> RnM (LHsBind GhcRn, [Name], Uses)
rnLBind sig_fn (L loc bind)
= setSrcSpanA loc $
do { (bind', bndrs, dus) <- rnBind sig_fn bind
; return (L loc bind', bndrs, dus) }
rnBind :: (Name -> [Name])
-> HsBindLR GhcRn GhcPs
-> RnM (HsBind GhcRn, [Name], Uses)
rnBind _ bind@(PatBind { pat_lhs = pat
, pat_rhs = grhss
, pat_ext = 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 CollNoDictBinders pat
bind' = bind { pat_rhs = grhss'
, pat_ext = fvs' }
ok_nobind_pat
=
case unLoc pat of
WildPat {} -> True
BangPat {} -> True
SplicePat {} -> True
_ -> False
; whenWOptM Opt_WarnUnusedPatternBinds $
when (null bndrs && not ok_nobind_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'
, fun_ext = fvs' },
[plain_name], rhs_fvs)
}
rnBind sig_fn (PatSynBind x bind)
= do { (bind', name, fvs) <- rnPatSynBind sig_fn bind
; return (PatSynBind x bind', name, fvs) }
rnBind _ b = pprPanic "rnBind" (ppr b)
depAnalBinds :: Bag (LHsBind GhcRn, [Name], Uses)
-> ([(RecFlag, LHsBinds GhcRn)], DefUses)
depAnalBinds binds_w_dus
= (map get_binds sccs, toOL $ 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]
mkScopedTvFn :: [LSig GhcRn] -> (Name -> [Name])
mkScopedTvFn sigs = \n -> lookupNameEnv env n `orElse` []
where
env = mkHsSigEnv get_scoped_tvs sigs
get_scoped_tvs :: LSig GhcRn -> Maybe ([LocatedN 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 GhcPs] -> RnM MiniFixityEnv
makeMiniFixityEnv decls = foldlM add_one_sig emptyFsEnv decls
where
add_one_sig :: MiniFixityEnv -> LFixitySig GhcPs -> RnM MiniFixityEnv
add_one_sig env (L loc (FixitySig _ names fixity)) =
foldlM add_one env [ (locA loc,locA 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 GhcRn GhcPs
-> RnM (PatSynBind GhcRn GhcRn, [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 scoped_tvs = sig_fn name
; ((pat', details'), fvs1) <- bindSigTyVarsFV scoped_tvs $
rnPat PatSyn pat $ \pat' ->
case details of
PrefixCon _ vars ->
do { checkDupRdrNamesN vars
; names <- mapM lookupPatSynBndr vars
; return ( (pat', PrefixCon noTypeArgs names)
, mkFVs (map unLoc names)) }
InfixCon var1 var2 ->
do { checkDupRdrNames [var1, var2]
; name1 <- lookupPatSynBndr var1
; name2 <- lookupPatSynBndr var2
; return ( (pat', InfixCon name1 name2)
, mkFVs (map unLoc [name1, name2])) }
RecCon vars ->
do { checkDupRdrNames (map (rdrNameFieldOcc . recordPatSynField) vars)
; fls <- lookupConstructorFields name
; let fld_env = mkFsEnv [ (flLabel fl, fl) | fl <- fls ]
; let rnRecordPatSynField
(RecordPatSynField { recordPatSynField = visible
, recordPatSynPatVar = hidden })
= do { let visible' = lookupField fld_env visible
; hidden' <- lookupPatSynBndr hidden
; return $ RecordPatSynField { recordPatSynField = visible'
, recordPatSynPatVar = hidden' } }
; names <- mapM rnRecordPatSynField vars
; return ( (pat', RecCon 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 scoped_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_ext = fvs' }
selector_names = case details' of
RecCon names ->
map (extFieldOcc . recordPatSynField) names
_ -> []
; fvs' `seq`
return (bind', name : selector_names , fvs1)
}
where
lookupPatSynBndr = wrapLocMA lookupLocalOccRn
patternSynonymErr :: SDoc
patternSynonymErr
= hang (text "Illegal pattern synonym declaration")
2 (text "Use -XPatternSynonyms to enable this extension")
rnMethodBinds :: Bool
-> Name
-> [Name]
-> LHsBinds GhcPs
-> [LSig GhcPs]
-> RnM (LHsBinds GhcRn, [LSig GhcRn], FreeVars)
rnMethodBinds is_cls_decl cls ktv_names binds sigs
= do { checkDupRdrNamesN (collectMethodBinders binds)
; binds' <- foldrM (rnMethodBindLHS is_cls_decl cls) emptyBag binds
; let (spec_inst_prags, other_sigs) = partition isSpecInstLSig sigs
bound_nms = mkNameSet (collectHsBindsBinders CollNoDictBinders 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) <- bindLocalNamesFV ktv_names $
renameSigs sig_ctxt other_sigs
; (binds'', bind_fvs) <- bindSigTyVarsFV ktv_names $
do { binds_w_dus <- mapBagM (rnLBind (mkScopedTvFn other_sigs')) binds'
; let bind_fvs = foldr (\(_,_,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) }
rnMethodBindLHS :: Bool -> Name
-> LHsBindLR GhcPs GhcPs
-> LHsBindsLR GhcRn GhcPs
-> RnM (LHsBindsLR GhcRn GhcPs)
rnMethodBindLHS _ cls (L loc bind@(FunBind { fun_id = name })) rest
= setSrcSpanA loc $ do
do { sel_name <- wrapLocMA (lookupInstDeclBndr cls (text "method")) name
; let bind' = bind { fun_id = sel_name, fun_ext = noExtField }
; return (L loc bind' `consBag` rest ) }
rnMethodBindLHS is_cls_decl _ (L loc bind) rest
= do { addErrAt (locA 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 GhcPs]
-> RnM ([LSig GhcRn], FreeVars)
renameSigs ctxt sigs
= do { mapM_ dupSigDeclErr (findDupSigs sigs)
; checkDupMinimalSigs sigs
; (sigs', sig_fvs) <- mapFvRn (wrapLocFstMA (renameSig ctxt)) sigs
; let (good_sigs, bad_sigs) = partition (okHsSig ctxt) sigs'
; mapM_ misplacedSigErr bad_sigs
; return (good_sigs, sig_fvs) }
renameSig :: HsSigCtxt -> Sig GhcPs -> RnM (Sig GhcRn, FreeVars)
renameSig _ (IdSig _ x)
= return (IdSig noExtField x, emptyFVs)
renameSig ctxt sig@(TypeSig _ vs ty)
= do { new_vs <- mapM (lookupSigOccRnN ctxt sig) vs
; let doc = TypeSigCtx (ppr_sig_bndrs vs)
; (new_ty, fvs) <- rnHsSigWcType doc ty
; return (TypeSig noAnn 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 (lookupSigOccRnN ctxt sig) vs
; (new_ty, fvs) <- rnHsSigType ty_ctxt TypeLevel ty
; return (ClassOpSig noAnn 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 { checkInferredVars doc inf_msg ty
; (new_ty, fvs) <- rnHsSigType doc TypeLevel ty
; addNoNestedForallsContextsErr doc (text "SPECIALISE instance type")
(getLHsInstDeclHead new_ty)
; return (SpecInstSig noAnn src new_ty,fvs) }
where
doc = SpecInstSigCtx
inf_msg = Just (text "Inferred type variables are not allowed")
renameSig ctxt sig@(SpecSig _ v tys inl)
= do { new_v <- case ctxt of
TopSigCtxt {} -> lookupLocatedOccRn v
_ -> lookupSigOccRnN ctxt sig v
; (new_ty, fvs) <- foldM do_one ([],emptyFVs) tys
; return (SpecSig noAnn 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 TypeLevel ty
; return ( new_ty:tys, fvs_ty `plusFV` fvs) }
renameSig ctxt sig@(InlineSig _ v s)
= do { new_v <- lookupSigOccRnN ctxt sig v
; return (InlineSig noAnn new_v s, emptyFVs) }
renameSig ctxt (FixSig _ fsig)
= do { new_fsig <- rnSrcFixityDecl ctxt fsig
; return (FixSig noAnn new_fsig, emptyFVs) }
renameSig ctxt sig@(MinimalSig _ s (L l bf))
= do new_bf <- traverse (lookupSigOccRnN ctxt sig) bf
return (MinimalSig noAnn s (L l new_bf), emptyFVs)
renameSig ctxt sig@(PatSynSig _ vs ty)
= do { new_vs <- mapM (lookupSigOccRnN ctxt sig) vs
; (ty', fvs) <- rnHsSigType ty_ctxt TypeLevel ty
; return (PatSynSig noAnn 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 <- lookupSigOccRnN ctxt sig v
; return (SCCFunSig noAnn 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) $
addErrCtxt (text "In" <+> ppr sig) $ failWithTc orphanError
return (CompleteMatchSig noAnn 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 :: [LocatedN RdrName] -> SDoc
ppr_sig_bndrs bs = quotes (pprWithCommas ppr bs)
okHsSig :: HsSigCtxt -> LSig (GhcPass 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 GhcPs] -> [NonEmpty (LocatedN RdrName, Sig GhcPs)]
findDupSigs sigs
= findDupsEq matching_sig (concatMap (expand_sig . unLoc) sigs)
where
expand_sig :: Sig GhcPs -> [(LocatedN RdrName, Sig GhcPs)]
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 :: (LocatedN RdrName, Sig GhcPs) -> (LocatedN RdrName, Sig GhcPs) -> Bool --AZ
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 GhcPs] -> RnM ()
checkDupMinimalSigs sigs
= case filter isMinimalLSig sigs of
minSigs@(_:_:_) -> dupMinimalSigErr minSigs
_ -> return ()
type AnnoBody body
= ( Anno [LocatedA (Match GhcRn (LocatedA (body GhcRn)))] ~ SrcSpanAnnL
, Anno [LocatedA (Match GhcPs (LocatedA (body GhcPs)))] ~ SrcSpanAnnL
, Anno (Match GhcRn (LocatedA (body GhcRn))) ~ SrcSpanAnnA
, Anno (Match GhcPs (LocatedA (body GhcPs))) ~ SrcSpanAnnA
, Anno (GRHS GhcRn (LocatedA (body GhcRn))) ~ SrcSpan
, Anno (GRHS GhcPs (LocatedA (body GhcPs))) ~ SrcSpan
, Outputable (body GhcPs)
)
rnMatchGroup :: (Outputable (body GhcPs), AnnoBody body) => HsMatchContext GhcRn
-> (LocatedA (body GhcPs) -> RnM (LocatedA (body GhcRn), FreeVars))
-> MatchGroup GhcPs (LocatedA (body GhcPs))
-> RnM (MatchGroup GhcRn (LocatedA (body GhcRn)), FreeVars)
rnMatchGroup ctxt rnBody (MG { mg_alts = L lm 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 (L lm new_ms), ms_fvs) }
rnMatch :: AnnoBody body
=> HsMatchContext GhcRn
-> (LocatedA (body GhcPs) -> RnM (LocatedA (body GhcRn), FreeVars))
-> LMatch GhcPs (LocatedA (body GhcPs))
-> RnM (LMatch GhcRn (LocatedA (body GhcRn)), FreeVars)
rnMatch ctxt rnBody = wrapLocFstMA (rnMatch' ctxt rnBody)
rnMatch' :: (AnnoBody body)
=> HsMatchContext GhcRn
-> (LocatedA (body GhcPs) -> RnM (LocatedA (body GhcRn), FreeVars))
-> Match GhcPs (LocatedA (body GhcPs))
-> RnM (Match GhcRn (LocatedA (body GhcRn)), FreeVars)
rnMatch' ctxt rnBody (Match { m_ctxt = mf, m_pats = pats, m_grhss = grhss })
= rnPats ctxt pats $ \ pats' -> do
{ (grhss', grhss_fvs) <- rnGRHSs ctxt rnBody grhss
; let mf' = case (ctxt, mf) of
(FunRhs { mc_fun = L _ funid }, FunRhs { mc_fun = L lf _ })
-> mf { mc_fun = L lf funid }
_ -> ctxt
; return (Match { m_ext = noAnn, m_ctxt = mf', m_pats = pats'
, m_grhss = grhss'}, grhss_fvs ) }
emptyCaseErr :: HsMatchContext GhcRn -> 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
rnGRHSs :: AnnoBody body
=> HsMatchContext GhcRn
-> (LocatedA (body GhcPs) -> RnM (LocatedA (body GhcRn), FreeVars))
-> GRHSs GhcPs (LocatedA (body GhcPs))
-> RnM (GRHSs GhcRn (LocatedA (body GhcRn)), FreeVars)
rnGRHSs ctxt rnBody (GRHSs _ grhss binds)
= rnLocalBindsAndThen binds $ \ binds' _ -> do
(grhss', fvGRHSs) <- mapFvRn (rnGRHS ctxt rnBody) grhss
return (GRHSs noExtField grhss' binds', fvGRHSs)
rnGRHS :: AnnoBody body
=> HsMatchContext GhcRn
-> (LocatedA (body GhcPs) -> RnM (LocatedA (body GhcRn), FreeVars))
-> LGRHS GhcPs (LocatedA (body GhcPs))
-> RnM (LGRHS GhcRn (LocatedA (body GhcRn)), FreeVars)
rnGRHS ctxt rnBody = wrapLocFstM (rnGRHS' ctxt rnBody)
rnGRHS' :: HsMatchContext GhcRn
-> (LocatedA (body GhcPs) -> RnM (LocatedA (body GhcRn), FreeVars))
-> GRHS GhcPs (LocatedA (body GhcPs))
-> RnM (GRHS GhcRn (LocatedA (body GhcRn)), FreeVars)
rnGRHS' ctxt rnBody (GRHS _ guards rhs)
= do { pattern_guards_allowed <- xoptM LangExt.PatternGuards
; ((guards', rhs'), fvs) <- rnStmts (PatGuard ctxt) rnExpr guards $ \ _ ->
rnBody rhs
; unless (pattern_guards_allowed || is_standard_guard guards')
(addWarn NoReason (nonStdGuardErr guards'))
; return (GRHS noAnn guards' rhs', fvs) }
where
is_standard_guard [] = True
is_standard_guard [L _ (BodyStmt {})] = True
is_standard_guard _ = False
rnSrcFixityDecl :: HsSigCtxt -> FixitySig GhcPs -> RnM (FixitySig GhcRn)
rnSrcFixityDecl sig_ctxt = rn_decl
where
rn_decl :: FixitySig GhcPs -> RnM (FixitySig GhcRn)
rn_decl (FixitySig _ fnames fixity)
= do names <- concatMapM lookup_one fnames
return (FixitySig noExtField names fixity)
lookup_one :: LocatedN RdrName -> RnM [LocatedN Name]
lookup_one (L name_loc rdr_name)
= setSrcSpanA name_loc $
do names <- lookupLocalTcNames sig_ctxt what rdr_name
return [ L name_loc name | (_, name) <- names ]
what = text "fixity signature"
dupSigDeclErr :: NonEmpty (LocatedN RdrName, Sig GhcPs) -> RnM ()
dupSigDeclErr pairs@((L loc name, sig) :| _)
= addErrAt (locA loc) $
vcat [ text "Duplicate" <+> what_it_is
<> text "s for" <+> quotes (ppr name)
, text "at" <+> vcat (map ppr $ sortBy SrcLoc.leftmost_smallest
$ map (getLocA . fst)
$ toList pairs)
]
where
what_it_is = hsSigDoc sig
misplacedSigErr :: LSig GhcRn -> RnM ()
misplacedSigErr (L loc sig)
= addErrAt (locA loc) $
sep [text "Misplaced" <+> hsSigDoc sig <> colon, ppr sig]
defaultSigErr :: Sig GhcPs -> SDoc
defaultSigErr sig = vcat [ hang (text "Unexpected default signature:")
2 (ppr sig)
, text "Use DefaultSignatures to enable default signatures" ]
bindsInHsBootFile :: LHsBindsLR GhcRn GhcPs -> SDoc
bindsInHsBootFile mbinds
= hang (text "Bindings in hs-boot files are not allowed")
2 (ppr mbinds)
nonStdGuardErr :: (Outputable body,
Anno (Stmt GhcRn body) ~ SrcSpanAnnA)
=> [LStmtLR GhcRn GhcRn body] -> SDoc
nonStdGuardErr guards
= hang (text "accepting non-standard pattern guards (use PatternGuards to suppress this message)")
4 (interpp'SP guards)
unusedPatBindWarn :: HsBind GhcRn -> SDoc
unusedPatBindWarn bind
= hang (text "This pattern-binding binds no variables:")
2 (ppr bind)
dupMinimalSigErr :: [LSig GhcPs] -> RnM ()
dupMinimalSigErr sigs@(L loc _ : _)
= addErrAt (locA loc) $
vcat [ text "Multiple minimal complete definitions"
, text "at" <+> vcat (map ppr $ sortBy SrcLoc.leftmost_smallest $ map getLocA sigs)
, text "Combine alternative minimal complete definitions with `|'" ]
dupMinimalSigErr [] = panic "dupMinimalSigErr"