X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fparser%2FRdrHsSyn.lhs;h=382b333e2b75f9cf1e7114f11aa4329ef47c12f8;hp=9a3c70a50ebc53e85c6c3c0a2ef91e07485bfc6c;hb=4bc25e8c30559b7a6a87b39afcc79340ae778788;hpb=c2a3f5861959f9b80ee65c16212447788217223d diff --git a/compiler/parser/RdrHsSyn.lhs b/compiler/parser/RdrHsSyn.lhs index 9a3c70a..382b333 100644 --- a/compiler/parser/RdrHsSyn.lhs +++ b/compiler/parser/RdrHsSyn.lhs @@ -8,16 +8,16 @@ module RdrHsSyn ( extractHsTyRdrTyVars, extractHsRhoRdrTyVars, extractGenericPatTyVars, - mkHsOpApp, mkClassDecl, - mkHsNegApp, mkHsIntegral, mkHsFractional, + mkHsOpApp, mkClassDecl, + mkHsIntegral, mkHsFractional, mkHsIsString, mkHsDo, mkHsSplice, mkTyData, mkPrefixCon, mkRecCon, mkInlineSpec, mkRecConstrOrUpdate, -- HsExp -> [HsFieldUpdate] -> P HsExp cvBindGroup, - cvBindsAndSigs, + cvBindsAndSigs, cvTopDecls, - findSplice, mkGroup, + findSplice, checkDecBrGroup, -- Stuff to do with Foreign declarations CallConv(..), @@ -35,10 +35,15 @@ module RdrHsSyn ( checkPrecP, -- Int -> P Int checkContext, -- HsType -> P HsContext checkPred, -- HsType -> P HsPred - checkTyClHdr, -- LHsContext RdrName -> LHsType RdrName -> P (LHsContext RdrName, Located RdrName, [LHsTyVarBndr RdrName]) - checkSynHdr, -- LHsType RdrName -> P (Located RdrName, [LHsTyVarBndr RdrName]) + checkTyClHdr, -- LHsContext RdrName -> LHsType RdrName + -- -> P (LHsContext RdrName, Located RdrName, [LHsTyVarBndr RdrName], [LHsType RdrName]) + checkTyVars, -- [LHsType RdrName] -> P () + checkSynHdr, -- LHsType RdrName -> P (Located RdrName, [LHsTyVarBndr RdrName], [LHsType RdrName]) + checkKindSigs, -- [LTyClDecl RdrName] -> P () checkInstType, -- HsType -> P HsType + checkDerivDecl, -- LDerivDecl RdrName -> P (LDerivDecl RdrName) checkPattern, -- HsExp -> P HsPat + bang_RDR, checkPatterns, -- SrcLoc -> [HsExp] -> P [HsPat] checkDo, -- [Stmt] -> P [Stmt] checkMDo, -- [Stmt] -> P [Stmt] @@ -47,27 +52,32 @@ module RdrHsSyn ( parseError, -- String -> Pa ) where -#include "HsVersions.h" - import HsSyn -- Lots of it -import RdrName ( RdrName, isRdrTyVar, mkUnqual, rdrNameOcc, +import Class ( FunDep ) +import TypeRep ( Kind ) +import RdrName ( RdrName, isRdrTyVar, isRdrTc, mkUnqual, rdrNameOcc, isRdrDataCon, isUnqual, getRdrName, isQual, - setRdrNameSpace ) -import BasicTypes ( maxPrecedence, Activation, InlineSpec(..), alwaysInlineSpec, neverInlineSpec ) -import Lexer ( P, failSpanMsgP, extension, bangPatEnabled ) + setRdrNameSpace, showRdrName ) +import BasicTypes ( maxPrecedence, Activation, RuleMatchInfo, + InlinePragma(..), InlineSpec(..), + alwaysInlineSpec, neverInlineSpec ) +import Lexer ( P, failSpanMsgP, extension, standaloneDerivingEnabled, bangPatEnabled ) import TysWiredIn ( unitTyCon ) import ForeignCall ( CCallConv, Safety, CCallTarget(..), CExportSpec(..), DNCallSpec(..), DNKind(..), CLabelString ) import OccName ( srcDataName, varName, isDataOcc, isTcOcc, occNameString ) +import PrelNames ( forall_tv_RDR ) import SrcLoc import OrdList ( OrdList, fromOL ) import Bag ( Bag, emptyBag, snocBag, consBag, foldrBag ) import Outputable import FastString -import Panic import List ( isSuffixOf, nubBy ) +import Monad ( unless ) + +#include "HsVersions.h" \end{code} @@ -90,11 +100,15 @@ extractHsRhoRdrTyVars :: LHsContext RdrName -> LHsType RdrName -> [Located RdrNa extractHsRhoRdrTyVars ctxt ty = nubBy eqLocated $ extract_lctxt ctxt (extract_lty ty []) +extract_lctxt :: Located [LHsPred RdrName] -> [Located RdrName] -> [Located RdrName] extract_lctxt ctxt acc = foldr (extract_pred . unLoc) acc (unLoc ctxt) -extract_pred (HsClassP cls tys) acc = foldr extract_lty acc tys -extract_pred (HsIParam n ty) acc = extract_lty ty acc +extract_pred :: HsPred RdrName -> [Located RdrName] -> [Located RdrName] +extract_pred (HsClassP _ tys) acc = foldr extract_lty acc tys +extract_pred (HsEqualP ty1 ty2) acc = extract_lty ty1 (extract_lty ty2 acc) +extract_pred (HsIParam _ ty ) acc = extract_lty ty acc +extract_lty :: LHsType RdrName -> [Located RdrName] -> [Located RdrName] extract_lty (L loc ty) acc = case ty of HsTyVar tv -> extract_tv loc tv acc @@ -107,14 +121,15 @@ extract_lty (L loc ty) acc HsPredTy p -> extract_pred p acc HsOpTy ty1 (L loc tv) ty2 -> extract_tv loc tv (extract_lty ty1 (extract_lty ty2 acc)) HsParTy ty -> extract_lty ty acc - HsNumTy num -> acc + HsNumTy _ -> acc HsSpliceTy _ -> acc -- Type splices mention no type variables - HsKindSig ty k -> extract_lty ty acc - HsForAllTy exp [] cx ty -> extract_lctxt cx (extract_lty ty acc) - HsForAllTy exp tvs cx ty -> acc ++ (filter ((`notElem` locals) . unLoc) $ + HsKindSig ty _ -> extract_lty ty acc + HsForAllTy _ [] cx ty -> extract_lctxt cx (extract_lty ty acc) + HsForAllTy _ tvs cx ty -> acc ++ (filter ((`notElem` locals) . unLoc) $ extract_lctxt cx (extract_lty ty [])) where locals = hsLTyVarNames tvs + HsDocTy ty _ -> extract_lty ty acc extract_tv :: SrcSpan -> RdrName -> [Located RdrName] -> [Located RdrName] extract_tv loc tv acc | isRdrTyVar tv = L loc tv : acc @@ -127,10 +142,10 @@ extractGenericPatTyVars binds = nubBy eqLocated (foldrBag get [] binds) where get (L _ (FunBind { fun_matches = MatchGroup ms _ })) acc = foldr (get_m.unLoc) acc ms - get other acc = acc + get _ acc = acc get_m (Match (L _ (TypePat ty) : _) _ _) acc = extract_lty ty acc - get_m other acc = acc + get_m _ acc = acc \end{code} @@ -151,31 +166,37 @@ Similarly for mkConDecl, mkClassOpSig and default-method names. *** See "THE NAMING STORY" in HsDecls **** \begin{code} -mkClassDecl (cxt, cname, tyvars) fds sigs mbinds +mkClassDecl :: (LHsContext name, Located name, [LHsTyVarBndr name]) + -> [Located (FunDep name)] + -> [LSig name] + -> LHsBinds name + -> [LTyClDecl name] + -> [LDocDecl name] + -> TyClDecl name +mkClassDecl (cxt, cname, tyvars) fds sigs mbinds ats docs = ClassDecl { tcdCtxt = cxt, tcdLName = cname, tcdTyVars = tyvars, tcdFDs = fds, tcdSigs = sigs, - tcdMeths = mbinds + tcdMeths = mbinds, + tcdATs = ats, + tcdDocs = docs } -mkTyData new_or_data (context, tname, tyvars) ksig data_cons maybe_deriv +mkTyData :: NewOrData + -> (LHsContext name, + Located name, + [LHsTyVarBndr name], + Maybe [LHsType name]) + -> Maybe Kind + -> [LConDecl name] + -> Maybe [LHsType name] + -> TyClDecl name +mkTyData new_or_data (context, tname, tyvars, typats) ksig data_cons maybe_deriv = TyData { tcdND = new_or_data, tcdCtxt = context, tcdLName = tname, - tcdTyVars = tyvars, tcdCons = data_cons, + tcdTyVars = tyvars, tcdTyPats = typats, tcdCons = data_cons, tcdKindSig = ksig, tcdDerivs = maybe_deriv } \end{code} -\begin{code} -mkHsNegApp :: LHsExpr RdrName -> HsExpr RdrName --- RdrName If the type checker sees (negate 3#) it will barf, because negate --- can't take an unboxed arg. But that is exactly what it will see when --- we write "-3#". So we have to do the negation right now! -mkHsNegApp (L loc e) = f e - where f (HsLit (HsIntPrim i)) = HsLit (HsIntPrim (-i)) - f (HsLit (HsFloatPrim i)) = HsLit (HsFloatPrim (-i)) - f (HsLit (HsDoublePrim i)) = HsLit (HsDoublePrim (-i)) - f expr = NegApp (L loc e) noSyntaxExpr -\end{code} - %************************************************************************ %* * \subsection[cvBinds-etc]{Converting to @HsBinds@, etc.} @@ -198,23 +219,31 @@ cvTopDecls decls = go (fromOL decls) where (L l' b', ds') = getMonoBind (L l b) ds go (d : ds) = d : go ds +-- Declaration list may only contain value bindings and signatures. cvBindGroup :: OrdList (LHsDecl RdrName) -> HsValBinds RdrName cvBindGroup binding - = case (cvBindsAndSigs binding) of { (mbs, sigs) -> - ValBindsIn mbs sigs - } + = case cvBindsAndSigs binding of + (mbs, sigs, tydecls, _) -> ASSERT( null tydecls ) + ValBindsIn mbs sigs cvBindsAndSigs :: OrdList (LHsDecl RdrName) - -> (Bag (LHsBind RdrName), [LSig RdrName]) + -> (Bag (LHsBind RdrName), [LSig RdrName], [LTyClDecl RdrName], [LDocDecl RdrName]) -- Input decls contain just value bindings and signatures +-- and in case of class or instance declarations also +-- associated type declarations. They might also contain Haddock comments. cvBindsAndSigs fb = go (fromOL fb) where - go [] = (emptyBag, []) - go (L l (SigD s) : ds) = (bs, L l s : ss) - where (bs,ss) = go ds - go (L l (ValD b) : ds) = (b' `consBag` bs, ss) - where (b',ds') = getMonoBind (L l b) ds - (bs,ss) = go ds' + go [] = (emptyBag, [], [], []) + go (L l (SigD s) : ds) = (bs, L l s : ss, ts, docs) + where (bs, ss, ts, docs) = go ds + go (L l (ValD b) : ds) = (b' `consBag` bs, ss, ts, docs) + where (b', ds') = getMonoBind (L l b) ds + (bs, ss, ts, docs) = go ds' + go (L l (TyClD t): ds) = (bs, ss, L l t : ts, docs) + where (bs, ss, ts, docs) = go ds + go (L l (DocD d) : ds) = (bs, ss, ts, (L l d) : docs) + where (bs, ss, ts, docs) = go ds + go (L _ d : _) = pprPanic "cvBindsAndSigs" (ppr d) ----------------------------------------------------------------------------- -- Group function bindings into equation groups @@ -229,21 +258,33 @@ getMonoBind :: LHsBind RdrName -> [LHsDecl RdrName] -- belong with b into a single MonoBinds, and ds' is the depleted -- list of parsed bindings. -- +-- All Haddock comments between equations inside the group are +-- discarded. +-- -- No AndMonoBinds or EmptyMonoBinds here; just single equations -getMonoBind (L loc bind@(FunBind { fun_id = L _ f, fun_matches = MatchGroup mtchs _ })) binds - | has_args mtchs - = go mtchs loc binds +getMonoBind (L loc1 (FunBind { fun_id = fun_id1@(L _ f1), fun_infix = is_infix1, + fun_matches = MatchGroup mtchs1 _ })) binds + | has_args mtchs1 + = go is_infix1 mtchs1 loc1 binds [] where - go mtchs1 loc1 (L loc2 (ValD (FunBind { fun_id = L _ f2, fun_matches = MatchGroup mtchs2 _ })) : binds) - | f == f2 = go (mtchs2++mtchs1) loc binds - where loc = combineSrcSpans loc1 loc2 - go mtchs1 loc binds - = (L loc (bind { fun_matches = mkMatchGroup (reverse mtchs1) }), binds) + go is_infix mtchs loc + (L loc2 (ValD (FunBind { fun_id = L _ f2, fun_infix = is_infix2, + fun_matches = MatchGroup mtchs2 _ })) : binds) _ + | f1 == f2 = go (is_infix || is_infix2) (mtchs2 ++ mtchs) + (combineSrcSpans loc loc2) binds [] + go is_infix mtchs loc (doc_decl@(L loc2 (DocD _)) : binds) doc_decls + = let doc_decls' = doc_decl : doc_decls + in go is_infix mtchs (combineSrcSpans loc loc2) binds doc_decls' + go is_infix mtchs loc binds doc_decls + = (L loc (makeFunBind fun_id1 is_infix (reverse mtchs)), (reverse doc_decls) ++ binds) -- Reverse the final matches, to get it back in the right order + -- Do the same thing with the trailing doc comments getMonoBind bind binds = (bind, binds) +has_args :: [LMatch RdrName] -> Bool +has_args [] = panic "RdrHsSyn:has_args" has_args ((L _ (Match args _ _)) : _) = not (null args) -- Don't group together FunBinds if they have -- no arguments. This is necessary now that variable bindings @@ -255,14 +296,15 @@ has_args ((L _ (Match args _ _)) : _) = not (null args) findSplice :: [LHsDecl a] -> (HsGroup a, Maybe (SpliceDecl a, [LHsDecl a])) findSplice ds = addl emptyRdrGroup ds -mkGroup :: [LHsDecl a] -> HsGroup a -mkGroup ds = addImpDecls emptyRdrGroup ds - -addImpDecls :: HsGroup a -> [LHsDecl a] -> HsGroup a --- The decls are imported, and should not have a splice -addImpDecls group decls = case addl group decls of - (group', Nothing) -> group' - other -> panic "addImpDecls" +checkDecBrGroup :: [LHsDecl a] -> P (HsGroup a) +-- Turn the body of a [d| ... |] into a HsGroup +-- There should be no splices in the "..." +checkDecBrGroup decls + = case addl emptyRdrGroup decls of + (group, Nothing) -> return group + (_, Just (SpliceDecl (L loc _), _)) -> + parseError loc "Declaration splices are not permitted inside declaration brackets" + -- Why not? See Section 7.3 of the TH paper. addl :: HsGroup a -> [LHsDecl a] -> (HsGroup a, Maybe (SpliceDecl a, [LHsDecl a])) -- This stuff reverses the declarations (again) but it doesn't matter @@ -275,13 +317,14 @@ addl gp (L l d : ds) = add gp l d ds add :: HsGroup a -> SrcSpan -> HsDecl a -> [LHsDecl a] -> (HsGroup a, Maybe (SpliceDecl a, [LHsDecl a])) -add gp l (SpliceD e) ds = (gp, Just (e, ds)) +add gp _ (SpliceD e) ds = (gp, Just (e, ds)) -- Class declarations: pull out the fixity signatures to the top -add gp@(HsGroup {hs_tyclds = ts, hs_fixds = fs}) l (TyClD d) ds +add gp@(HsGroup {hs_tyclds = ts, hs_fixds = fs}) + l (TyClD d) ds | isClassDecl d = let fsigs = [ L l f | L l (FixSig f) <- tcdSigs d ] in - addl (gp { hs_tyclds = L l d : ts, hs_fixds = fsigs ++ fs }) ds + addl (gp { hs_tyclds = L l d : ts, hs_fixds = fsigs ++ fs}) ds | otherwise = addl (gp { hs_tyclds = L l d : ts }) ds @@ -298,17 +341,29 @@ add gp@(HsGroup {hs_valds = ts}) l (ValD d) ds -- The rest are routine add gp@(HsGroup {hs_instds = ts}) l (InstD d) ds = addl (gp { hs_instds = L l d : ts }) ds +add gp@(HsGroup {hs_derivds = ts}) l (DerivD d) ds + = addl (gp { hs_derivds = L l d : ts }) ds add gp@(HsGroup {hs_defds = ts}) l (DefD d) ds = addl (gp { hs_defds = L l d : ts }) ds -add gp@(HsGroup {hs_fords = ts}) l (ForD d) ds +add gp@(HsGroup {hs_fords = ts}) l (ForD d) ds = addl (gp { hs_fords = L l d : ts }) ds -add gp@(HsGroup {hs_depds = ts}) l (DeprecD d) ds - = addl (gp { hs_depds = L l d : ts }) ds +add gp@(HsGroup {hs_warnds = ts}) l (WarningD d) ds + = addl (gp { hs_warnds = L l d : ts }) ds +add gp@(HsGroup {hs_annds = ts}) l (AnnD d) ds + = addl (gp { hs_annds = L l d : ts }) ds add gp@(HsGroup {hs_ruleds = ts}) l (RuleD d) ds = addl (gp { hs_ruleds = L l d : ts }) ds +add gp l (DocD d) ds + = addl (gp { hs_docs = (L l d) : (hs_docs gp) }) ds + +add_bind :: LHsBind a -> HsValBinds a -> HsValBinds a add_bind b (ValBindsIn bs sigs) = ValBindsIn (bs `snocBag` b) sigs -add_sig s (ValBindsIn bs sigs) = ValBindsIn bs (s:sigs) +add_bind _ (ValBindsOut {}) = panic "RdrHsSyn:add_bind" + +add_sig :: LSig a -> HsValBinds a -> HsValBinds a +add_sig s (ValBindsIn bs sigs) = ValBindsIn bs (s:sigs) +add_sig _ (ValBindsOut {}) = panic "RdrHsSyn:add_sig" \end{code} %************************************************************************ @@ -328,7 +383,7 @@ add_sig s (ValBindsIn bs sigs) = ValBindsIn bs (s:sigs) -- arguments, and converts the type constructor back into a data constructor. mkPrefixCon :: LHsType RdrName -> [LBangType RdrName] - -> P (Located RdrName, HsConDetails RdrName (LBangType RdrName)) + -> P (Located RdrName, HsConDeclDetails RdrName) mkPrefixCon ty tys = split ty tys where @@ -337,18 +392,24 @@ mkPrefixCon ty tys return (data_con, PrefixCon ts) split (L l _) _ = parseError l "parse error in data/newtype declaration" -mkRecCon :: Located RdrName -> [([Located RdrName], LBangType RdrName)] - -> P (Located RdrName, HsConDetails RdrName (LBangType RdrName)) +mkRecCon :: Located RdrName -> + [([Located RdrName], LBangType RdrName, Maybe (LHsDoc RdrName))] -> + P (Located RdrName, HsConDeclDetails RdrName) mkRecCon (L loc con) fields = do data_con <- tyConToDataCon loc con - return (data_con, RecCon [ (l,t) | (ls,t) <- fields, l <- ls ]) + return (data_con, RecCon [ ConDeclField l t d | (ls, t, d) <- fields, l <- ls ]) tyConToDataCon :: SrcSpan -> RdrName -> P (Located RdrName) tyConToDataCon loc tc | isTcOcc (rdrNameOcc tc) = return (L loc (setRdrNameSpace tc srcDataName)) | otherwise - = parseError loc (showSDoc (text "Not a constructor:" <+> quotes (ppr tc))) + = parseErrorSDoc loc (msg $$ extra) + where + msg = text "Not a data constructor:" <+> quotes (ppr tc) + extra | tc == forall_tv_RDR + = text "Perhaps you intended to use -XExistentialQuantification" + | otherwise = empty ---------------------------------------------------------------------------- -- Various Syntactic Checks @@ -365,53 +426,149 @@ checkInstType (L l t) ty -> do dict_ty <- checkDictTy (L l ty) return (L l (HsForAllTy Implicit [] (noLoc []) dict_ty)) -checkTyVars :: [LHsType RdrName] -> P [LHsTyVarBndr RdrName] -checkTyVars tvs - = mapM chk tvs +checkDictTy :: LHsType RdrName -> P (LHsType RdrName) +checkDictTy (L spn ty) = check ty [] where - -- Check that the name space is correct! - chk (L l (HsKindSig (L _ (HsTyVar tv)) k)) - | isRdrTyVar tv = return (L l (KindedTyVar tv k)) - chk (L l (HsTyVar tv)) - | isRdrTyVar tv = return (L l (UserTyVar tv)) - chk (L l other) - = parseError l "Type found where type variable expected" - -checkSynHdr :: LHsType RdrName -> P (Located RdrName, [LHsTyVarBndr RdrName]) -checkSynHdr ty = do { (_, tc, tvs) <- checkTyClHdr (noLoc []) ty - ; return (tc, tvs) } + check (HsTyVar t) args | not (isRdrTyVar t) + = return (L spn (HsPredTy (HsClassP t args))) + check (HsAppTy l r) args = check (unLoc l) (r:args) + check (HsParTy t) args = check (unLoc t) args + check _ _ = parseError spn "Malformed instance header" +-- Check whether the given list of type parameters are all type variables +-- (possibly with a kind signature). If the second argument is `False', +-- only type variables are allowed and we raise an error on encountering a +-- non-variable; otherwise, we allow non-variable arguments and return the +-- entire list of parameters. +-- +checkTyVars :: [LHsType RdrName] -> P () +checkTyVars tparms = mapM_ chk tparms + where + -- Check that the name space is correct! + chk (L _ (HsKindSig (L _ (HsTyVar tv)) _)) + | isRdrTyVar tv = return () + chk (L _ (HsTyVar tv)) + | isRdrTyVar tv = return () + chk (L l _) = + parseError l "Type found where type variable expected" + +-- Check whether the type arguments in a type synonym head are simply +-- variables. If not, we have a type family instance and return all patterns. +-- If yes, we return 'Nothing' as the third component to indicate a vanilla +-- type synonym. +-- +checkSynHdr :: LHsType RdrName + -> Bool -- is type instance? + -> P (Located RdrName, -- head symbol + [LHsTyVarBndr RdrName], -- parameters + [LHsType RdrName]) -- type patterns +checkSynHdr ty isTyInst = + do { (_, tc, tvs, tparms) <- checkTyClHdr (noLoc []) ty + ; unless isTyInst $ checkTyVars tparms + ; return (tc, tvs, tparms) } + + +-- Well-formedness check and decomposition of type and class heads. +-- checkTyClHdr :: LHsContext RdrName -> LHsType RdrName - -> P (LHsContext RdrName, Located RdrName, [LHsTyVarBndr RdrName]) + -> P (LHsContext RdrName, -- the type context + Located RdrName, -- the head symbol (type or class name) + [LHsTyVarBndr RdrName], -- free variables of the non-context part + [LHsType RdrName]) -- parameters of head symbol -- The header of a type or class decl should look like -- (C a, D b) => T a b -- or T a b -- or a + b -- etc +-- With associated types, we can also have non-variable parameters; ie, +-- T Int [a] +-- or Int :++: [a] +-- The unaltered parameter list is returned in the fourth component of the +-- result. Eg, for +-- T Int [a] +-- we return +-- ('()', 'T', ['a'], ['Int', '[a]']) checkTyClHdr (L l cxt) ty - = do (tc, tvs) <- gol ty [] + = do (tc, tvs, parms) <- gol ty [] mapM_ chk_pred cxt - return (L l cxt, tc, tvs) + return (L l cxt, tc, tvs, parms) where gol (L l ty) acc = go l ty acc - go l (HsTyVar tc) acc - | not (isRdrTyVar tc) = checkTyVars acc >>= \ tvs -> - return (L l tc, tvs) - go l (HsOpTy t1 tc t2) acc = checkTyVars (t1:t2:acc) >>= \ tvs -> - return (tc, tvs) - go l (HsParTy ty) acc = gol ty acc - go l (HsAppTy t1 t2) acc = gol t1 (t2:acc) - go l other acc = parseError l "Malformed LHS to type of class declaration" - - -- The predicates in a type or class decl must all - -- be HsClassPs. They need not all be type variables, - -- even in Haskell 98. E.g. class (Monad m, Monad (t m)) => MonadT t m - chk_pred (L l (HsClassP _ args)) = return () + go l (HsTyVar tc) acc + | isRdrTc tc = do tvs <- extractTyVars acc + return (L l tc, tvs, acc) + go _ (HsOpTy t1 ltc@(L _ tc) t2) acc + | isRdrTc tc = do tvs <- extractTyVars (t1:t2:acc) + return (ltc, tvs, t1:t2:acc) + go _ (HsParTy ty) acc = gol ty acc + go _ (HsAppTy t1 t2) acc = gol t1 (t2:acc) + go l _ _ = + parseError l "Malformed head of type or class declaration" + + -- The predicates in a type or class decl must be class predicates or + -- equational constraints. They need not all have variable-only + -- arguments, even in Haskell 98. + -- E.g. class (Monad m, Monad (t m)) => MonadT t m + chk_pred (L _ (HsClassP _ _)) = return () + chk_pred (L _ (HsEqualP _ _)) = return () chk_pred (L l _) = parseError l "Malformed context in type or class declaration" - +-- Extract the type variables of a list of type parameters. +-- +-- * Type arguments can be complex type terms (needed for associated type +-- declarations). +-- +extractTyVars :: [LHsType RdrName] -> P [LHsTyVarBndr RdrName] +extractTyVars tvs = collects tvs [] + where + -- Collect all variables (2nd arg serves as an accumulator) + collect :: LHsType RdrName -> [LHsTyVarBndr RdrName] + -> P [LHsTyVarBndr RdrName] + collect (L l (HsForAllTy _ _ _ _)) = + const $ parseError l "Forall type not allowed as type parameter" + collect (L l (HsTyVar tv)) + | isRdrTyVar tv = return . (L l (UserTyVar tv) :) + | otherwise = return + collect (L l (HsBangTy _ _ )) = + const $ parseError l "Bang-style type annotations not allowed as type parameter" + collect (L _ (HsAppTy t1 t2 )) = collect t2 >=> collect t1 + collect (L _ (HsFunTy t1 t2 )) = collect t2 >=> collect t1 + collect (L _ (HsListTy t )) = collect t + collect (L _ (HsPArrTy t )) = collect t + collect (L _ (HsTupleTy _ ts )) = collects ts + collect (L _ (HsOpTy t1 _ t2 )) = collect t2 >=> collect t1 + collect (L _ (HsParTy t )) = collect t + collect (L _ (HsNumTy _ )) = return + collect (L l (HsPredTy _ )) = + const $ parseError l "Predicate not allowed as type parameter" + collect (L l (HsKindSig (L _ ty) k)) + | HsTyVar tv <- ty, isRdrTyVar tv + = return . (L l (KindedTyVar tv k) :) + | otherwise + = const $ parseError l "Kind signature only allowed for type variables" + collect (L l (HsSpliceTy _ )) = + const $ parseError l "Splice not allowed as type parameter" + collect (L _ (HsDocTy t _ )) = collect t + + -- Collect all variables of a list of types + collects [] = return + collects (t:ts) = collects ts >=> collect t + + (f >=> g) x = f x >>= g + +-- Check that associated type declarations of a class are all kind signatures. +-- +checkKindSigs :: [LTyClDecl RdrName] -> P () +checkKindSigs = mapM_ check + where + check (L l tydecl) + | isFamilyDecl tydecl + || isSynDecl tydecl = return () + | otherwise = + parseError l "Type declaration in a class must be a kind signature or synonym default" + checkContext :: LHsType RdrName -> P (LHsContext RdrName) checkContext (L l t) = check t @@ -442,21 +599,25 @@ checkPred (L spn ty) where checkl (L l ty) args = check l ty args + check _loc (HsPredTy pred@(HsEqualP _ _)) + args | null args + = return $ L spn pred check _loc (HsTyVar t) args | not (isRdrTyVar t) = return (L spn (HsClassP t args)) check _loc (HsAppTy l r) args = checkl l (r:args) check _loc (HsOpTy l (L loc tc) r) args = check loc (HsTyVar tc) (l:r:args) check _loc (HsParTy t) args = checkl t args - check loc _ _ = parseError loc "malformed class assertion" + check loc _ _ = parseError loc + "malformed class assertion" -checkDictTy :: LHsType RdrName -> P (LHsType RdrName) -checkDictTy (L spn ty) = check ty [] - where - check (HsTyVar t) args | not (isRdrTyVar t) - = return (L spn (HsPredTy (HsClassP t args))) - check (HsAppTy l r) args = check (unLoc l) (r:args) - check (HsParTy t) args = check (unLoc t) args - check _ _ = parseError spn "Malformed context in instance header" +--------------------------------------------------------------------------- +-- Checking stand-alone deriving declarations + +checkDerivDecl :: LDerivDecl RdrName -> P (LDerivDecl RdrName) +checkDerivDecl d@(L loc _) = + do stDerivOn <- extension standaloneDerivingEnabled + if stDerivOn then return d + else parseError loc "Illegal stand-alone deriving declaration (use -XStandaloneDeriving)" --------------------------------------------------------------------------- -- Checking statements in a do-expression @@ -466,15 +627,18 @@ checkDictTy (L spn ty) = check ty [] -- (b) returns it separately -- same comments apply for mdo as well +checkDo, checkMDo :: SrcSpan -> [LStmt RdrName] -> P ([LStmt RdrName], LHsExpr RdrName) + checkDo = checkDoMDo "a " "'do'" checkMDo = checkDoMDo "an " "'mdo'" checkDoMDo :: String -> String -> SrcSpan -> [LStmt RdrName] -> P ([LStmt RdrName], LHsExpr RdrName) -checkDoMDo pre nm loc [] = parseError loc ("Empty " ++ nm ++ " construct") -checkDoMDo pre nm loc ss = do +checkDoMDo _ nm loc [] = parseError loc ("Empty " ++ nm ++ " construct") +checkDoMDo pre nm _ ss = do check ss where - check [L l (ExprStmt e _ _)] = return ([], e) + check [] = panic "RdrHsSyn:checkDoMDo" + check [L _ (ExprStmt e _ _)] = return ([], e) check [L l _] = parseError l ("The last statement in " ++ pre ++ nm ++ " construct must be an expression") check (s:ss) = do @@ -509,9 +673,10 @@ checkPat loc (L _ (HsApp f x)) args = do { x <- checkLPat x; checkPat loc f (x:args) } checkPat loc (L _ e) [] = do { p <- checkAPat loc e; return (L loc p) } -checkPat loc pat _some_args +checkPat loc _ _ = patFail loc +checkAPat :: SrcSpan -> HsExpr RdrName -> P (Pat RdrName) checkAPat loc e = case e of EWildPat -> return (WildPat placeHolderType) HsVar x | isQual x -> parseError loc ("Qualified variable in pattern: " @@ -521,63 +686,69 @@ checkAPat loc e = case e of -- Overloaded numeric patterns (e.g. f 0 x = x) -- Negation is recorded separately, so that the literal is zero or +ve - -- NB. Negative *primitive* literals are already handled by - -- RdrHsSyn.mkHsNegApp - HsOverLit pos_lit -> return (mkNPat pos_lit Nothing) + -- NB. Negative *primitive* literals are already handled by the lexer + HsOverLit pos_lit -> return (mkNPat pos_lit Nothing) NegApp (L _ (HsOverLit pos_lit)) _ -> return (mkNPat pos_lit (Just noSyntaxExpr)) - SectionR (L _ (HsVar bang)) e - | bang == bang_RDR -> checkLPat e >>= (return . BangPat) + SectionR (L _ (HsVar bang)) e -- (! x) + | bang == bang_RDR + -> do { bang_on <- extension bangPatEnabled + ; if bang_on then checkLPat e >>= (return . BangPat) + else parseError loc "Illegal bang-pattern (use -XBangPatterns)" } + ELazyPat e -> checkLPat e >>= (return . LazyPat) EAsPat n e -> checkLPat e >>= (return . AsPat n) - ExprWithTySig e t -> checkLPat e >>= \e -> - -- Pattern signatures are parsed as sigtypes, - -- but they aren't explicit forall points. Hence - -- we have to remove the implicit forall here. - let t' = case t of - L _ (HsForAllTy Implicit _ (L _ []) ty) -> ty - other -> other - in - return (SigPatIn e t') + -- view pattern is well-formed if the pattern is + EViewPat expr patE -> checkLPat patE >>= (return . (\p -> ViewPat expr p placeHolderType)) + ExprWithTySig e t -> do e <- checkLPat e + -- Pattern signatures are parsed as sigtypes, + -- but they aren't explicit forall points. Hence + -- we have to remove the implicit forall here. + let t' = case t of + L _ (HsForAllTy Implicit _ (L _ []) ty) -> ty + other -> other + return (SigPatIn e t') -- n+k patterns OpApp (L nloc (HsVar n)) (L _ (HsVar plus)) _ - (L _ (HsOverLit lit@(HsIntegral _ _))) + (L _ (HsOverLit lit@(OverLit {ol_val = HsIntegral {}}))) | plus == plus_RDR -> return (mkNPlusKPat (L nloc n) lit) - OpApp l op fix r -> checkLPat l >>= \l -> - checkLPat r >>= \r -> - case op of - L cl (HsVar c) | isDataOcc (rdrNameOcc c) - -> return (ConPatIn (L cl c) (InfixCon l r)) - _ -> patFail loc + OpApp l op _fix r -> do l <- checkLPat l + r <- checkLPat r + case op of + L cl (HsVar c) | isDataOcc (rdrNameOcc c) + -> return (ConPatIn (L cl c) (InfixCon l r)) + _ -> patFail loc - HsPar e -> checkLPat e >>= (return . ParPat) - ExplicitList _ es -> mapM (\e -> checkLPat e) es >>= \ps -> - return (ListPat ps placeHolderType) - ExplicitPArr _ es -> mapM (\e -> checkLPat e) es >>= \ps -> - return (PArrPat ps placeHolderType) + HsPar e -> checkLPat e >>= (return . ParPat) + ExplicitList _ es -> do ps <- mapM checkLPat es + return (ListPat ps placeHolderType) + ExplicitPArr _ es -> do ps <- mapM checkLPat es + return (PArrPat ps placeHolderType) - ExplicitTuple es b -> mapM (\e -> checkLPat e) es >>= \ps -> - return (TuplePat ps b placeHolderType) + ExplicitTuple es b -> do ps <- mapM checkLPat es + return (TuplePat ps b placeHolderType) - RecordCon c _ fs -> mapM checkPatField fs >>= \fs -> - return (ConPatIn c (RecCon fs)) + RecordCon c _ (HsRecFields fs dd) + -> do fs <- mapM checkPatField fs + return (ConPatIn c (RecCon (HsRecFields fs dd))) + HsQuasiQuoteE q -> return (QuasiQuotePat q) -- Generics HsType ty -> return (TypePat ty) _ -> patFail loc plus_RDR, bang_RDR :: RdrName -plus_RDR = mkUnqual varName FSLIT("+") -- Hack -bang_RDR = mkUnqual varName FSLIT("!") -- Hack +plus_RDR = mkUnqual varName (fsLit "+") -- Hack +bang_RDR = mkUnqual varName (fsLit "!") -- Hack -checkPatField :: (Located RdrName, LHsExpr RdrName) -> P (Located RdrName, LPat RdrName) -checkPatField (n,e) = do - p <- checkLPat e - return (n,p) +checkPatField :: HsRecField RdrName (LHsExpr RdrName) -> P (HsRecField RdrName (LPat RdrName)) +checkPatField fld = do { p <- checkLPat (hsRecFieldArg fld) + ; return (fld { hsRecFieldArg = p }) } +patFail :: SrcSpan -> P a patFail loc = parseError loc "Parse error in pattern" @@ -589,6 +760,10 @@ checkValDef :: LHsExpr RdrName -> Located (GRHSs RdrName) -> P (HsBind RdrName) +checkValDef lhs (Just sig) grhss + -- x :: ty = rhs parses as a *pattern* binding + = checkPatBind (L (combineLocs lhs sig) (ExprWithTySig lhs sig)) grhss + checkValDef lhs opt_sig grhss = do { mb_fun <- isFunLhs lhs ; case mb_fun of @@ -596,19 +771,33 @@ checkValDef lhs opt_sig grhss fun is_infix pats opt_sig grhss Nothing -> checkPatBind lhs grhss } +checkFunBind :: SrcSpan + -> Located RdrName + -> Bool + -> [LHsExpr RdrName] + -> Maybe (LHsType RdrName) + -> Located (GRHSs RdrName) + -> P (HsBind RdrName) checkFunBind lhs_loc fun is_infix pats opt_sig (L rhs_span grhss) | isQual (unLoc fun) - = parseError (getLoc fun) ("Qualified name in function definition: " ++ - showRdrName (unLoc fun)) + = parseErrorSDoc (getLoc fun) + (ptext (sLit "Qualified name in function definition:") <+> ppr (unLoc fun)) | otherwise = do ps <- checkPatterns pats let match_span = combineSrcSpans lhs_loc rhs_span - matches = mkMatchGroup [L match_span (Match ps opt_sig grhss)] - return (FunBind { fun_id = fun, fun_infix = is_infix, fun_matches = matches, - fun_co_fn = idCoercion, bind_fvs = placeHolderNames }) + return (makeFunBind fun is_infix [L match_span (Match ps opt_sig grhss)]) -- The span of the match covers the entire equation. -- That isn't quite right, but it'll do for now. +makeFunBind :: Located id -> Bool -> [LMatch id] -> HsBind id +-- Like HsUtils.mkFunBind, but we need to be able to set the fixity too +makeFunBind fn is_infix ms + = FunBind { fun_id = fn, fun_infix = is_infix, fun_matches = mkMatchGroup ms, + fun_co_fn = idHsWrapper, bind_fvs = placeHolderNames, fun_tick = Nothing } + +checkPatBind :: LHsExpr RdrName + -> Located (GRHSs RdrName) + -> P (HsBind RdrName) checkPatBind lhs (L _ grhss) = do { lhs <- checkPattern lhs ; return (PatBind lhs grhss placeHolderType placeHolderNames) } @@ -620,33 +809,31 @@ checkValSig checkValSig (L l (HsVar v)) ty | isUnqual v && not (isDataOcc (rdrNameOcc v)) = return (TypeSig (L l v) ty) -checkValSig (L l other) ty +checkValSig (L l _) _ = parseError l "Invalid type signature" -mkGadtDecl - :: Located RdrName - -> LHsType RdrName -- assuming HsType - -> ConDecl RdrName -mkGadtDecl name (L _ (HsForAllTy _ qvars cxt ty)) = ConDecl - { con_name = name - , con_explicit = Implicit - , con_qvars = qvars - , con_cxt = cxt - , con_details = PrefixCon args - , con_res = ResTyGADT res - } - where - (args, res) = splitHsFunType ty -mkGadtDecl name ty = ConDecl - { con_name = name - , con_explicit = Implicit - , con_qvars = [] - , con_cxt = noLoc [] - , con_details = PrefixCon args - , con_res = ResTyGADT res - } - where - (args, res) = splitHsFunType ty +mkGadtDecl :: Located RdrName + -> LHsType RdrName -- assuming HsType + -> ConDecl RdrName +mkGadtDecl name (L _ (HsForAllTy _ qvars cxt ty)) = mk_gadt_con name qvars cxt ty +mkGadtDecl name ty = mk_gadt_con name [] (noLoc []) ty + +mk_gadt_con :: Located RdrName + -> [LHsTyVarBndr RdrName] + -> LHsContext RdrName + -> LHsType RdrName + -> ConDecl RdrName +mk_gadt_con name qvars cxt ty + = ConDecl { con_name = name + , con_explicit = Implicit + , con_qvars = qvars + , con_cxt = cxt + , con_details = PrefixCon [] + , con_res = ResTyGADT ty + , con_doc = Nothing } + -- NB: we put the whole constr type into the ResTyGADT for now; + -- the renamer will unravel it once it has sorted out + -- operator fixities -- A variable binding is parsed as a FunBind. @@ -654,33 +841,57 @@ mkGadtDecl name ty = ConDecl -- The parser left-associates, so there should -- not be any OpApps inside the e's splitBang :: LHsExpr RdrName -> Maybe (LHsExpr RdrName, [LHsExpr RdrName]) --- Splits (f ! g a b) into (f, [(! g), a, g]) -splitBang (L loc (OpApp l_arg bang@(L loc' (HsVar op)) _ r_arg)) +-- Splits (f ! g a b) into (f, [(! g), a, b]) +splitBang (L loc (OpApp l_arg bang@(L _ (HsVar op)) _ r_arg)) | op == bang_RDR = Just (l_arg, L loc (SectionR bang arg1) : argns) where (arg1,argns) = split_bang r_arg [] split_bang (L _ (HsApp f e)) es = split_bang f (e:es) split_bang e es = (e,es) -splitBang other = Nothing +splitBang _ = Nothing isFunLhs :: LHsExpr RdrName -> P (Maybe (Located RdrName, Bool, [LHsExpr RdrName])) -- Just (fun, is_infix, arg_pats) if e is a function LHS +-- +-- The whole LHS is parsed as a single expression. +-- Any infix operators on the LHS will parse left-associatively +-- E.g. f !x y !z +-- will parse (rather strangely) as +-- (f ! x y) ! z +-- It's up to isFunLhs to sort out the mess +-- +-- a .!. !b + isFunLhs e = go e [] where go (L loc (HsVar f)) es | not (isRdrDataCon f) = return (Just (L loc f, False, es)) go (L _ (HsApp f e)) es = go f (e:es) go (L _ (HsPar e)) es@(_:_) = go e es + + -- For infix function defns, there should be only one infix *function* + -- (though there may be infix *datacons* involved too). So we don't + -- need fixity info to figure out which function is being defined. + -- a `K1` b `op` c `K2` d + -- must parse as + -- (a `K1` b) `op` (c `K2` d) + -- The renamer checks later that the precedences would yield such a parse. + -- + -- There is a complication to deal with bang patterns. + -- + -- ToDo: what about this? + -- x + 1 `op` y = ... + go e@(L loc (OpApp l (L loc' (HsVar op)) fix r)) es | Just (e',es') <- splitBang e = do { bang_on <- extension bangPatEnabled ; if bang_on then go e' (es' ++ es) else return (Just (L loc' op, True, (l:r:es))) } -- No bangs; behave just like the next case - | not (isRdrDataCon op) + | not (isRdrDataCon op) -- We have found the function! = return (Just (L loc' op, True, (l:r:es))) - | otherwise + | otherwise -- Infix data con; keep going = do { mb_l <- go l es ; case mb_l of Just (op', True, j : k : es') @@ -701,21 +912,26 @@ checkPrecP (L l i) mkRecConstrOrUpdate :: LHsExpr RdrName -> SrcSpan - -> HsRecordBinds RdrName + -> ([HsRecField RdrName (LHsExpr RdrName)], Bool) -> P (HsExpr RdrName) -mkRecConstrOrUpdate (L l (HsVar c)) loc fs | isRdrDataCon c - = return (RecordCon (L l c) noPostTcExpr fs) -mkRecConstrOrUpdate exp loc fs@(_:_) - = return (RecordUpd exp fs placeHolderType placeHolderType) -mkRecConstrOrUpdate _ loc [] - = parseError loc "Empty record update" +mkRecConstrOrUpdate (L l (HsVar c)) _ (fs,dd) | isRdrDataCon c + = return (RecordCon (L l c) noPostTcExpr (mk_rec_fields fs dd)) +mkRecConstrOrUpdate exp loc (fs,dd) + | null fs = parseError loc "Empty record update" + | otherwise = return (RecordUpd exp (mk_rec_fields fs dd) [] [] []) -mkInlineSpec :: Maybe Activation -> Bool -> InlineSpec +mk_rec_fields :: [HsRecField id arg] -> Bool -> HsRecFields id arg +mk_rec_fields fs False = HsRecFields { rec_flds = fs, rec_dotdot = Nothing } +mk_rec_fields fs True = HsRecFields { rec_flds = fs, rec_dotdot = Just (length fs) } + +mkInlineSpec :: Maybe Activation -> RuleMatchInfo -> Bool -> InlineSpec -- The Maybe is becuase the user can omit the activation spec (and usually does) -mkInlineSpec Nothing True = alwaysInlineSpec -- INLINE -mkInlineSpec Nothing False = neverInlineSpec -- NOINLINE -mkInlineSpec (Just act) inl = Inline act inl +mkInlineSpec Nothing match_info True = alwaysInlineSpec match_info + -- INLINE +mkInlineSpec Nothing match_info False = neverInlineSpec match_info + -- NOINLINE +mkInlineSpec (Just act) match_info inl = Inline (InlinePragma act match_info) inl ----------------------------------------------------------------------------- @@ -734,10 +950,10 @@ mkImport :: CallConv -> P (HsDecl RdrName) mkImport (CCall cconv) safety (entity, v, ty) = do importSpec <- parseCImport entity cconv safety v - return (ForD (ForeignImport v ty importSpec False)) + return (ForD (ForeignImport v ty importSpec)) mkImport (DNCall ) _ (entity, v, ty) = do spec <- parseDImport entity - return $ ForD (ForeignImport v ty (DNImport spec) False) + return $ ForD (ForeignImport v ty (DNImport spec)) -- parse the entity string of a foreign import declaration for the `ccall' or -- `stdcall' calling convention' @@ -749,9 +965,9 @@ parseCImport :: Located FastString -> P ForeignImport parseCImport (L loc entity) cconv safety v -- FIXME: we should allow white space around `dynamic' and `wrapper' -=chak - | entity == FSLIT ("dynamic") = + | entity == fsLit "dynamic" = return $ CImport cconv safety nilFS nilFS (CFunction DynamicTarget) - | entity == FSLIT ("wrapper") = + | entity == fsLit "wrapper" = return $ CImport cconv safety nilFS nilFS CWrapper | otherwise = parse0 (unpackFS entity) where @@ -819,8 +1035,9 @@ parseDImport (L loc entity) = parse0 comps parse2 _ _ [] = d'oh parse2 isStatic kind (('[':x):xs) = case x of - [] -> d'oh - vs | last vs == ']' -> parse3 isStatic kind (init vs) xs + [] -> d'oh + vs | last vs == ']' -> parse3 isStatic kind (init vs) xs + _ -> d'oh parse2 isStatic kind xs = parse3 isStatic kind "" xs parse3 isStatic kind assem [x] = @@ -837,12 +1054,12 @@ parseDImport (L loc entity) = parse0 comps mkExport :: CallConv -> (Located FastString, Located RdrName, LHsType RdrName) -> P (HsDecl RdrName) -mkExport (CCall cconv) (L loc entity, v, ty) = return $ - ForD (ForeignExport v ty (CExport (CExportStatic entity' cconv)) False) +mkExport (CCall cconv) (L _ entity, v, ty) = return $ + ForD (ForeignExport v ty (CExport (CExportStatic entity' cconv))) where entity' | nullFS entity = mkExtName (unLoc v) | otherwise = entity -mkExport DNCall (L loc entity, v, ty) = +mkExport DNCall (L _ _, v, _) = parseError (getLoc v){-TODO: not quite right-} "Foreign export is not yet supported for .NET" @@ -861,9 +1078,9 @@ mkExtName rdrNm = mkFastString (occNameString (rdrNameOcc rdrNm)) -- Misc utils \begin{code} -showRdrName :: RdrName -> String -showRdrName r = showSDoc (ppr r) - parseError :: SrcSpan -> String -> P a -parseError span s = failSpanMsgP span s +parseError span s = parseErrorSDoc span (text s) + +parseErrorSDoc :: SrcSpan -> SDoc -> P a +parseErrorSDoc span s = failSpanMsgP span s \end{code}