rebase to ghc main repo
[ghc-hetmet.git] / compiler / parser / RdrHsSyn.lhs
index b83bcd9..ed11fd8 100644 (file)
@@ -44,6 +44,7 @@ module RdrHsSyn (
        checkMDo,             -- [Stmt] -> P [Stmt]
        checkValDef,          -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
        checkValSig,          -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
+       checkDoAndIfThenElse,
        parseError,         
        parseErrorSDoc,     
     ) where
@@ -54,7 +55,7 @@ import TypeRep          ( Kind )
 import RdrName         ( RdrName, isRdrTyVar, isRdrTc, mkUnqual, rdrNameOcc, 
                          isRdrDataCon, isUnqual, getRdrName, setRdrNameSpace )
 import BasicTypes      ( maxPrecedence, Activation(..), RuleMatchInfo,
-                          InlinePragma(..) )
+                          InlinePragma(..), InlineSpec(..) )
 import Lexer
 import TysWiredIn      ( unitTyCon ) 
 import ForeignCall
@@ -70,6 +71,7 @@ import FastString
 import Maybes
 
 import Control.Applicative ((<$>))       
+import Control.Monad
 import Text.ParserCombinators.ReadP as ReadP
 import Data.List        ( nubBy )
 import Data.Char
@@ -120,12 +122,14 @@ extract_lty (L loc ty) acc
       HsAppTy ty1 ty2                  -> extract_lty ty1 (extract_lty ty2 acc)
       HsListTy ty                      -> extract_lty ty acc
       HsPArrTy ty                      -> extract_lty ty acc
+      HsModalBoxType ecn ty    -> extract_lty ty acc
       HsTupleTy _ tys                  -> extract_ltys tys acc
       HsFunTy ty1 ty2                  -> extract_lty ty1 (extract_lty ty2 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 _                 -> acc
+      HsNumTy {}                -> acc
+      HsCoreTy {}               -> acc  -- The type is closed
       HsQuasiQuoteTy {}                -> acc  -- Quasi quotes mention no type variables
       HsSpliceTy {}            -> acc  -- Type splices mention no type variables
       HsKindSig ty _            -> extract_lty ty acc
@@ -172,13 +176,14 @@ Similarly for mkConDecl, mkClassOpSig and default-method names.
   
 \begin{code}
 mkClassDecl :: SrcSpan
-            -> Located (LHsContext RdrName, LHsType RdrName) 
+            -> Located (Maybe (LHsContext RdrName), LHsType RdrName)
             -> Located [Located (FunDep RdrName)]
             -> Located (OrdList (LHsDecl RdrName))
            -> P (LTyClDecl RdrName)
 
-mkClassDecl loc (L _ (cxt, tycl_hdr)) fds where_cls
+mkClassDecl loc (L _ (mcxt, tycl_hdr)) fds where_cls
   = do { let (binds, sigs, ats, docs) = cvBindsAndSigs (unLoc where_cls)
+       ; let cxt = fromMaybe (noLoc []) mcxt
        ; (cls, tparams) <- checkTyClHdr tycl_hdr
        ; tyvars <- checkTyVars tparams      -- Only type vars allowed
        ; checkKindSigs ats
@@ -189,14 +194,16 @@ mkClassDecl loc (L _ (cxt, tycl_hdr)) fds where_cls
 mkTyData :: SrcSpan
          -> NewOrData
         -> Bool                -- True <=> data family instance
-         -> Located (LHsContext RdrName, LHsType RdrName)
+         -> Located (Maybe (LHsContext RdrName), LHsType RdrName)
          -> Maybe Kind
          -> [LConDecl RdrName]
          -> Maybe [LHsType RdrName]
          -> P (LTyClDecl RdrName)
-mkTyData loc new_or_data is_family (L _ (cxt, tycl_hdr)) ksig data_cons maybe_deriv
+mkTyData loc new_or_data is_family (L _ (mcxt, tycl_hdr)) ksig data_cons maybe_deriv
   = do { (tc, tparams) <- checkTyClHdr tycl_hdr
 
+       ; checkDatatypeContext mcxt
+       ; let cxt = fromMaybe (noLoc []) mcxt
        ; (tyvars, typats) <- checkTParams is_family tparams
        ; return (L loc (TyData { tcdND = new_or_data, tcdCtxt = cxt, tcdLName = tc,
                                 tcdTyVars = tyvars, tcdTyPats = typats, 
@@ -231,8 +238,8 @@ mkTopSpliceDecl :: LHsExpr RdrName -> HsDecl RdrName
 --      f x            then behave as if she'd written $(f x)
 --                    ie a SpliceD
 mkTopSpliceDecl (L _ (HsQuasiQuoteE qq))            = QuasiQuoteD qq
-mkTopSpliceDecl (L _ (HsSpliceE (HsSplice _ expr))) = SpliceD (SpliceDecl expr)
-mkTopSpliceDecl other_expr                          = SpliceD (SpliceDecl other_expr)
+mkTopSpliceDecl (L _ (HsSpliceE (HsSplice _ expr))) = SpliceD (SpliceDecl expr       Explicit)
+mkTopSpliceDecl other_expr                          = SpliceD (SpliceDecl other_expr Implicit)
 \end{code}
 
 %************************************************************************
@@ -358,7 +365,7 @@ splitCon ty
    split (L _ (HsAppTy t u)) ts = split t (u : ts)
    split (L l (HsTyVar tc))  ts = do data_con <- tyConToDataCon l tc
                                     return (data_con, mk_rest ts)
-   split (L l _) _             = parseError l "parse error in data/newtype declaration"
+   split (L l _) _             = parseErrorSDoc l (text "parse error in constructor in data/newtype declaration:" <+> ppr ty)
 
    mk_rest [L _ (HsRecTy flds)] = RecCon flds
    mk_rest ts                   = PrefixCon ts
@@ -475,7 +482,7 @@ checkDictTy (L spn ty) = check ty []
   check (HsOpTy t1 (L _ tc) t2) args | isRdrTc tc = done tc (t1:t2: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 _ _ = parseErrorSDoc spn (text "Malformed instance header:" <+> ppr ty)
 
   done tc args = return (L spn (HsPredTy (HsClassP tc args)))
 
@@ -518,8 +525,19 @@ checkTyVars tparms = mapM chk tparms
        | isRdrTyVar tv    = return (L l (KindedTyVar tv k))
     chk (L l (HsTyVar tv))
         | isRdrTyVar tv    = return (L l (UserTyVar tv placeHolderKind))
-    chk (L l _)            =
-         parseError l "Type found where type variable expected"
+    chk t@(L l _)            =
+         parseErrorSDoc l (text "Type found:" <+> ppr t
+                     $$ text "where type variable expected, in:" <+>
+                        sep (map (pprParendHsType . unLoc) tparms))
+
+checkDatatypeContext :: Maybe (LHsContext RdrName) -> P ()
+checkDatatypeContext Nothing = return ()
+checkDatatypeContext (Just (L loc c))
+    = do allowed <- extension datatypeContextsEnabled
+         unless allowed $
+             parseErrorSDoc loc
+                 (text "Illegal datatype context (use -XDatatypeContexts):" <+>
+                  pprHsContext c)
 
 checkTyClHdr :: LHsType RdrName
              -> P (Located RdrName,         -- the head symbol (type or class name)
@@ -540,7 +558,7 @@ checkTyClHdr ty
        | isRdrTc tc         = return (ltc, 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"
+    go l _               _   = parseErrorSDoc l (text "Malformed head of type or class declaration:" <+> ppr ty)
 
 -- Check that associated type declarations of a class are all kind signatures.
 --
@@ -551,7 +569,7 @@ checkKindSigs = mapM_ check
       | isFamilyDecl tydecl
         || isSynDecl tydecl  = return ()
       | otherwise           = 
-       parseError l "Type declaration in a class must be a kind signature or synonym default"
+       parseErrorSDoc l (text "Type declaration in a class must be a kind signature or synonym default:" $$ ppr tydecl)
 
 checkContext :: LHsType RdrName -> P (LHsContext RdrName)
 checkContext (L l t)
@@ -591,8 +609,8 @@ checkPred (L spn ty)
     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 _                        _    = parseErrorSDoc loc
+                                (text "malformed class assertion:" <+> ppr ty)
 
 ---------------------------------------------------------------------------
 -- Checking statements in a do-expression
@@ -608,14 +626,16 @@ checkDo    = checkDoMDo "a " "'do'"
 checkMDo = checkDoMDo "an " "'mdo'"
 
 checkDoMDo :: String -> String -> SrcSpan -> [LStmt RdrName] -> P ([LStmt RdrName], LHsExpr RdrName)
-checkDoMDo _   nm loc []   = parseError loc ("Empty " ++ nm ++ " construct")
+checkDoMDo _   nm loc []   = parseErrorSDoc loc (text ("Empty " ++ nm ++ " construct"))
 checkDoMDo pre nm _   ss   = do
   check ss
   where 
        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  [L l e] = parseErrorSDoc l
+                         (text ("The last statement in " ++ pre ++ nm ++
+                                                   " construct must be an expression:")
+                       $$ ppr e)
        check (s:ss) = do
          (ss',e') <-  check ss
          return ((s:ss'),e')
@@ -650,11 +670,11 @@ checkPat loc (L _ e) []
   = do { pState <- getPState
        ; p <- checkAPat (dflags pState) loc e
        ; return (L loc p) }
-checkPat loc _ _
-  = patFail loc
+checkPat loc e _
+  = patFail loc (unLoc e)
 
 checkAPat :: DynFlags -> SrcSpan -> HsExpr RdrName -> P (Pat RdrName)
-checkAPat dynflags loc e = case e of
+checkAPat dynflags loc e0 = case e0 of
    EWildPat -> return (WildPat placeHolderType)
    HsVar x  -> return (VarPat x)
    HsLit l  -> return (LitPat l)
@@ -670,7 +690,7 @@ checkAPat dynflags loc e = case e of
        | bang == bang_RDR 
        -> do { bang_on <- extension bangPatEnabled
              ; if bang_on then checkLPat e >>= (return . BangPat)
-               else parseError loc "Illegal bang-pattern (use -XBangPatterns)" }
+               else parseErrorSDoc loc (text "Illegal bang-pattern (use -XBangPatterns):" $$ ppr e0) }
 
    ELazyPat e        -> checkLPat e >>= (return . LazyPat)
    EAsPat n e        -> checkLPat e >>= (return . AsPat n)
@@ -688,7 +708,7 @@ checkAPat dynflags loc e = case e of
    -- n+k patterns
    OpApp (L nloc (HsVar n)) (L _ (HsVar plus)) _ 
         (L _ (HsOverLit lit@(OverLit {ol_val = HsIntegral {}})))
-                     | dopt Opt_NPlusKPatterns dynflags && (plus == plus_RDR)
+                     | xopt Opt_NPlusKPatterns dynflags && (plus == plus_RDR)
                      -> return (mkNPlusKPat (L nloc n) lit)
    
    OpApp l op _fix r  -> do l <- checkLPat l
@@ -696,7 +716,7 @@ checkAPat dynflags loc e = case e of
                             case op of
                                L cl (HsVar c) | isDataOcc (rdrNameOcc c)
                                       -> return (ConPatIn (L cl c) (InfixCon l r))
-                               _ -> patFail loc
+                               _ -> patFail loc e0
    
    HsPar e           -> checkLPat e >>= (return . ParPat)
    ExplicitList _ es  -> do ps <- mapM checkLPat es
@@ -707,7 +727,7 @@ checkAPat dynflags loc e = case e of
    ExplicitTuple es b 
      | all tupArgPresent es  -> do ps <- mapM checkLPat [e | Present e <- es]
                                    return (TuplePat ps b placeHolderType)
-     | otherwise -> parseError loc "Illegal tuple section in pattern"
+     | otherwise -> parseErrorSDoc loc (text "Illegal tuple section in pattern:" $$ ppr e0)
    
    RecordCon c _ (HsRecFields fs dd)
                       -> do fs <- mapM checkPatField fs
@@ -715,12 +735,12 @@ checkAPat dynflags loc e = case e of
    HsQuasiQuoteE q    -> return (QuasiQuotePat q)
 -- Generics 
    HsType ty          -> return (TypePat ty) 
-   _                  -> patFail loc
+   _                  -> patFail loc e0
 
-placeHolderPunRhs :: HsExpr RdrName
+placeHolderPunRhs :: LHsExpr RdrName
 -- The RHS of a punned record field will be filled in by the renamer
 -- It's better not to make it an error, in case we want to print it when debugging
-placeHolderPunRhs = HsVar pun_RDR
+placeHolderPunRhs = noLoc (HsVar pun_RDR)
 
 plus_RDR, bang_RDR, pun_RDR :: RdrName
 plus_RDR = mkUnqual varName (fsLit "+")        -- Hack
@@ -731,8 +751,8 @@ checkPatField :: HsRecField RdrName (LHsExpr RdrName) -> P (HsRecField RdrName (
 checkPatField fld = do { p <- checkLPat (hsRecFieldArg fld)
                        ; return (fld { hsRecFieldArg = p }) }
 
-patFail :: SrcSpan -> P a
-patFail loc = parseError loc "Parse error in pattern"
+patFail :: SrcSpan -> HsExpr RdrName -> P a
+patFail loc e = parseErrorSDoc loc (text "Parse error in pattern:" <+> ppr e)
 
 
 ---------------------------------------------------------------------------
@@ -785,15 +805,19 @@ checkValSig
        :: LHsExpr RdrName
        -> LHsType RdrName
        -> P (Sig RdrName)
+checkValSig (L l (HsHetMetBrak _ e)) ty 
+  = checkValSig e ty
 checkValSig (L l (HsVar v)) ty 
   | isUnqual v && not (isDataOcc (rdrNameOcc v))
   = return (TypeSig (L l v) ty)
-checkValSig lhs@(L l _)         _
-  | looks_like_foreign lhs
-  = parseError l "Invalid type signature; perhaps you meant to use -XForeignFunctionInterface?"
-  | otherwise
-  = parseError l "Invalid type signature: should be of form <variable> :: <type>"
+checkValSig lhs@(L l _) ty
+  = parseErrorSDoc l ((text "Invalid type signature:" <+>
+                       ppr lhs <+> text "::" <+> ppr ty)
+                   $$ text hint)
   where
+    hint = if looks_like_foreign lhs
+           then "Perhaps you meant to use -XForeignFunctionInterface?"
+           else "Should be of form <variable> :: <type>"
     -- A common error is to forget the ForeignFunctionInterface flag
     -- so check for that, and suggest.  cf Trac #3805
     -- Sadly 'foreign import' still barfs 'parse error' because 'import' is a keyword
@@ -802,6 +826,27 @@ checkValSig lhs@(L l _)         _
     looks_like_foreign _                   = False
 
     foreign_RDR = mkUnqual varName (fsLit "foreign")
+
+checkDoAndIfThenElse :: LHsExpr RdrName
+                     -> Bool
+                     -> LHsExpr RdrName
+                     -> Bool
+                     -> LHsExpr RdrName
+                     -> P ()
+checkDoAndIfThenElse guardExpr semiThen thenExpr semiElse elseExpr
+ | semiThen || semiElse
+    = do pState <- getPState
+         unless (xopt Opt_DoAndIfThenElse (dflags pState)) $ do
+             parseErrorSDoc (combineLocs guardExpr elseExpr)
+                            (text "Unexpected semi-colons in conditional:"
+                          $$ nest 4 expr
+                          $$ text "Perhaps you meant to use -XDoAndIfThenElse?")
+ | otherwise            = return ()
+    where pprOptSemi True  = semi
+          pprOptSemi False = empty
+          expr = text "if"   <+> ppr guardExpr <> pprOptSemi semiThen <+>
+                 text "then" <+> ppr thenExpr  <> pprOptSemi semiElse <+>
+                 text "else" <+> ppr elseExpr
 \end{code}
 
 
@@ -876,7 +921,8 @@ isFunLhs e = go e []
 checkPrecP :: Located Int -> P Int
 checkPrecP (L l i)
  | 0 <= i && i <= maxPrecedence = return i
- | otherwise                   = parseError l "Precedence out of range"
+ | otherwise
+    = parseErrorSDoc l (text ("Precedence out of range: " ++ show i))
 
 mkRecConstrOrUpdate 
        :: LHsExpr RdrName 
@@ -887,16 +933,16 @@ mkRecConstrOrUpdate
 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"
+  | null fs   = parseErrorSDoc loc (text "Empty record update of:" <+> ppr exp)
   | otherwise = return (RecordUpd exp (mk_rec_fields fs dd) [] [] [])
 
 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) }
 
-mkInlinePragma :: Maybe Activation -> RuleMatchInfo -> Bool -> InlinePragma
+mkInlinePragma :: (InlineSpec, RuleMatchInfo) -> Maybe Activation -> InlinePragma
 -- The Maybe is because the user can omit the activation spec (and usually does)
-mkInlinePragma mb_act match_info inl 
+mkInlinePragma (inl, match_info) mb_act
   = InlinePragma { inl_inline = inl
                  , inl_sat    = Nothing
                  , inl_act    = act
@@ -904,11 +950,10 @@ mkInlinePragma mb_act match_info inl
   where
     act = case mb_act of
             Just act -> act
-            Nothing | inl       -> AlwaysActive
-                    | otherwise -> NeverActive
-        -- If no specific phase is given then:
-       --   NOINLINE => NeverActive
-        --   INLINE   => Active
+            Nothing  -> -- No phase specified
+                        case inl of
+                          NoInline -> NeverActive
+                          _other   -> AlwaysActive
 
 -----------------------------------------------------------------------------
 -- utilities for foreign declarations
@@ -927,7 +972,7 @@ mkImport cconv safety (L loc entity, v, ty)
 
   | otherwise = do
     case parseCImport cconv safety (mkExtName (unLoc v)) (unpackFS entity) of
-      Nothing         -> parseError loc "Malformed entity string"
+      Nothing         -> parseErrorSDoc loc (text "Malformed entity string")
       Just importSpec -> return (ForD (ForeignImport v ty importSpec))
 
 -- the string "foo" is ambigous: either a header or a C identifier.  The