summaryrefslogtreecommitdiff
path: root/compiler/GHC/Parser
diff options
context:
space:
mode:
authorCale Gibbard <cgibbard@gmail.com>2020-11-09 16:11:45 -0500
committerBen Gamari <ben@smart-cactus.org>2020-12-14 13:37:09 -0500
commitc696bb2f4476e0ce4071e0d91687c1fe84405599 (patch)
treedc55fdaebbcd8dbd0c1f53c80214c2996c7f3f0a /compiler/GHC/Parser
parent78580ba3f99565b0aecb25c4206718d4c8a52317 (diff)
downloadhaskell-c696bb2f4476e0ce4071e0d91687c1fe84405599.tar.gz
Implement type applications in patterns
The haddock submodule is also updated so that it understands the changes to patterns.
Diffstat (limited to 'compiler/GHC/Parser')
-rw-r--r--compiler/GHC/Parser/Errors.hs5
-rw-r--r--compiler/GHC/Parser/Errors/Ppr.hs5
-rw-r--r--compiler/GHC/Parser/PostProcess.hs38
-rw-r--r--compiler/GHC/Parser/PostProcess/Haddock.hs8
-rw-r--r--compiler/GHC/Parser/Types.hs6
5 files changed, 33 insertions, 29 deletions
diff --git a/compiler/GHC/Parser/Errors.hs b/compiler/GHC/Parser/Errors.hs
index cf93890532..582b47535d 100644
--- a/compiler/GHC/Parser/Errors.hs
+++ b/compiler/GHC/Parser/Errors.hs
@@ -175,9 +175,6 @@ data ErrorDesc
| ErrIfTheElseInPat
-- ^ If-then-else syntax in pattern
- | ErrTypeAppInPat
- -- ^ Type-application in pattern
-
| ErrLambdaCaseInPat
-- ^ Lambda-case in pattern
@@ -393,6 +390,8 @@ data Hint
| SuggestLetInDo
| SuggestPatternSynonyms
| SuggestInfixBindMaybeAtPat !RdrName
+ | TypeApplicationsInPatternsOnlyDataCons -- ^ Type applications in patterns are only allowed on data constructors
+
data LexErrKind
= LexErrKind_EOF -- ^ End of input
diff --git a/compiler/GHC/Parser/Errors/Ppr.hs b/compiler/GHC/Parser/Errors/Ppr.hs
index c4b411b1c3..a26f6809c6 100644
--- a/compiler/GHC/Parser/Errors/Ppr.hs
+++ b/compiler/GHC/Parser/Errors/Ppr.hs
@@ -263,9 +263,6 @@ pp_err = \case
ErrIfTheElseInPat
-> text "(if ... then ... else ...)-syntax in pattern"
- ErrTypeAppInPat
- -> text "Type applications in patterns are not yet supported"
-
ErrLambdaCaseInPat
-> text "(\\case ...)-syntax in pattern"
@@ -607,6 +604,8 @@ pp_hint = \case
$$ if opIsAt fun
then perhaps_as_pat
else empty
+ TypeApplicationsInPatternsOnlyDataCons ->
+ text "Type applications in patterns are only allowed on data constructors."
perhaps_as_pat :: SDoc
perhaps_as_pat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace"
diff --git a/compiler/GHC/Parser/PostProcess.hs b/compiler/GHC/Parser/PostProcess.hs
index 1b4151cfb7..a59e4a882f 100644
--- a/compiler/GHC/Parser/PostProcess.hs
+++ b/compiler/GHC/Parser/PostProcess.hs
@@ -575,9 +575,9 @@ mkPatSynMatchGroup (L loc patsyn_name) (L _ decls) =
do { unless (name == patsyn_name) $
wrongNameBindingErr loc decl
; match <- case details of
- PrefixCon pats -> return $ Match { m_ext = noExtField
- , m_ctxt = ctxt, m_pats = pats
- , m_grhss = rhs }
+ PrefixCon _ pats -> return $ Match { m_ext = noExtField
+ , m_ctxt = ctxt, m_pats = pats
+ , m_grhss = rhs }
where
ctxt = FunRhs { mc_fun = ln
, mc_fixity = Prefix
@@ -966,27 +966,31 @@ checkPattern_hints :: [Hint] -> PV (Located (PatBuilder GhcPs)) -> P (LPat GhcPs
checkPattern_hints hints pp = runPV_hints hints (pp >>= checkLPat)
checkLPat :: Located (PatBuilder GhcPs) -> PV (LPat GhcPs)
-checkLPat e@(L l _) = checkPat l e []
+checkLPat e@(L l _) = checkPat l e [] []
-checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [LPat GhcPs]
+checkPat :: SrcSpan -> Located (PatBuilder GhcPs) -> [HsPatSigType GhcPs] -> [LPat GhcPs]
-> PV (LPat GhcPs)
-checkPat loc (L l e@(PatBuilderVar (L _ c))) args
+checkPat loc (L l e@(PatBuilderVar (L _ c))) tyargs args
| isRdrDataCon c = return . L loc $ ConPat
{ pat_con_ext = noExtField
, pat_con = L l c
- , pat_args = PrefixCon args
+ , pat_args = PrefixCon tyargs args
}
+ | not (null tyargs) =
+ add_hint TypeApplicationsInPatternsOnlyDataCons $
+ patFail l (ppr e <+> hsep [text "@" <> ppr t | t <- tyargs])
| not (null args) && patIsRec c =
add_hint SuggestRecursiveDo $
patFail l (ppr e)
-checkPat loc (L _ (PatBuilderApp f e)) args
- = do p <- checkLPat e
- checkPat loc f (p : args)
-checkPat loc (L _ e) []
- = do p <- checkAPat loc e
- return (L loc p)
-checkPat loc e _
- = patFail loc (ppr e)
+checkPat loc (L _ (PatBuilderAppType f t)) tyargs args = do
+ checkPat loc f (t : tyargs) args
+checkPat loc (L _ (PatBuilderApp f e)) [] args = do
+ p <- checkLPat e
+ checkPat loc f [] (p : args)
+checkPat loc (L _ e) [] [] = do
+ p <- checkAPat loc e
+ return (L loc p)
+checkPat loc e _ _ = patFail loc (ppr e)
checkAPat :: SrcSpan -> PatBuilder GhcPs -> PV (Pat GhcPs)
checkAPat loc e0 = do
@@ -1517,7 +1521,7 @@ instance DisambECP (PatBuilder GhcPs) where
type FunArg (PatBuilder GhcPs) = PatBuilder GhcPs
superFunArg m = m
mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2)
- mkHsAppTypePV l _ _ = addFatalError $ Error ErrTypeAppInPat [] l
+ mkHsAppTypePV l p t = return $ L l (PatBuilderAppType p (mkHsPatSigType t))
mkHsIfPV l _ _ _ _ _ = addFatalError $ Error ErrIfTheElseInPat [] l
mkHsDoPV l _ _ = addFatalError $ Error ErrDoNotationInPat [] l
mkHsParPV l p = return $ L l (PatBuilderPar p)
@@ -1625,7 +1629,7 @@ dataConBuilderDetails (PrefixDataConBuilder flds _)
-- Normal prefix constructor, e.g. data T = MkT A B C
dataConBuilderDetails (PrefixDataConBuilder flds _)
- = PrefixCon (map hsLinear (toList flds))
+ = PrefixCon noTypeArgs (map hsLinear (toList flds))
-- Infix constructor, e.g. data T = Int :! Bool
dataConBuilderDetails (InfixDataConBuilder lhs _ rhs)
diff --git a/compiler/GHC/Parser/PostProcess/Haddock.hs b/compiler/GHC/Parser/PostProcess/Haddock.hs
index 21f74a878e..f291830ea2 100644
--- a/compiler/GHC/Parser/PostProcess/Haddock.hs
+++ b/compiler/GHC/Parser/PostProcess/Haddock.hs
@@ -708,13 +708,13 @@ instance HasHaddock (Located (ConDecl GhcPs)) where
ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_args } ->
addConTrailingDoc (srcSpanEnd l_con_decl) $
case con_args of
- PrefixCon ts -> do
+ PrefixCon _ ts -> do
con_doc' <- getConDoc (getLoc con_name)
ts' <- traverse addHaddockConDeclFieldTy ts
pure $ L l_con_decl $
ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt,
con_doc = con_doc',
- con_args = PrefixCon ts' }
+ con_args = PrefixCon noTypeArgs ts' }
InfixCon t1 t2 -> do
t1' <- addHaddockConDeclFieldTy t1
con_doc' <- getConDoc (getLoc con_name)
@@ -865,9 +865,9 @@ addConTrailingDoc l_sep =
doc <- selectDocString trailingDocs
return $ L l' (con_fld { cd_fld_doc = doc })
con_args' <- case con_args con_decl of
- x@(PrefixCon []) -> x <$ reportExtraDocs trailingDocs
+ x@(PrefixCon _ []) -> x <$ reportExtraDocs trailingDocs
x@(RecCon (L _ [])) -> x <$ reportExtraDocs trailingDocs
- PrefixCon ts -> PrefixCon <$> mapLastM mk_doc_ty ts
+ PrefixCon _ ts -> PrefixCon noTypeArgs <$> mapLastM mk_doc_ty ts
InfixCon t1 t2 -> InfixCon t1 <$> mk_doc_ty t2
RecCon (L l_rec flds) -> do
flds' <- mapLastM mk_doc_fld flds
diff --git a/compiler/GHC/Parser/Types.hs b/compiler/GHC/Parser/Types.hs
index 26795def9f..ba7ca1d9c1 100644
--- a/compiler/GHC/Parser/Types.hs
+++ b/compiler/GHC/Parser/Types.hs
@@ -41,12 +41,13 @@ pprSumOrTuple boxity = \case
Boxed -> (text "(", text ")")
Unboxed -> (text "(#", text "#)")
--- | See Note [Ambiguous syntactic categories] and Note [PatBuilder] in
--- GHC.parser.PostProcess
+
+-- | See Note [Ambiguous syntactic categories] and Note [PatBuilder]
data PatBuilder p
= PatBuilderPat (Pat p)
| PatBuilderPar (Located (PatBuilder p))
| PatBuilderApp (Located (PatBuilder p)) (Located (PatBuilder p))
+ | PatBuilderAppType (Located (PatBuilder p)) (HsPatSigType GhcPs)
| PatBuilderOpApp (Located (PatBuilder p)) (Located RdrName) (Located (PatBuilder p))
| PatBuilderVar (Located RdrName)
| PatBuilderOverLit (HsOverLit GhcPs)
@@ -55,6 +56,7 @@ instance Outputable (PatBuilder GhcPs) where
ppr (PatBuilderPat p) = ppr p
ppr (PatBuilderPar (L _ p)) = parens (ppr p)
ppr (PatBuilderApp (L _ p1) (L _ p2)) = ppr p1 <+> ppr p2
+ ppr (PatBuilderAppType (L _ p) t) = ppr p <+> text "@" <> ppr t
ppr (PatBuilderOpApp (L _ p1) op (L _ p2)) = ppr p1 <+> ppr op <+> ppr p2
ppr (PatBuilderVar v) = ppr v
ppr (PatBuilderOverLit l) = ppr l