\begin{code}
module HsPat (
- Pat(..), InPat, OutPat, LPat,
+ Pat(..), InPat, OutPat, LPat,
HsConDetails(..), hsConArgs,
+ HsRecField(..), mkRecField,
- mkPrefixConPat, mkCharLitPat, mkNilPat,
+ mkPrefixConPat, mkCharLitPat, mkNilPat, mkCoPat,
isBangHsBind,
patsAreAllCons, isConPat, isSigPat, isWildPat,
import {-# SOURCE #-} HsExpr ( SyntaxExpr )
-- friends:
-import HsBinds ( DictBinds, HsBind(..), emptyLHsBinds, pprLHsBinds )
+import HsBinds ( DictBinds, HsBind(..), HsWrapper, isIdHsWrapper, pprHsWrapper,
+ emptyLHsBinds, pprLHsBinds )
import HsLit ( HsLit(HsCharPrim), HsOverLit )
import HsTypes ( LHsType, PostTcType )
+import HsDoc ( LHsDoc, ppr_mbDoc )
import BasicTypes ( Boxity, tupleParens )
-- others:
import PprCore ( {- instance OutputableBndr TyVar -} )
| ConPatIn (Located id)
(HsConDetails id (LPat id))
- | ConPatOut (Located DataCon)
- [TyVar] -- Existentially bound type variables
- [id] -- Ditto dictionaries
- (DictBinds id) -- Bindings involving those dictionaries
- (HsConDetails id (LPat id))
- Type -- The type of the pattern
+ | ConPatOut {
+ pat_con :: Located DataCon,
+ pat_tvs :: [TyVar], -- Existentially bound type variables
+ -- including any bound coercion variables
+ pat_dicts :: [id], -- Ditto dictionaries
+ pat_binds :: DictBinds id, -- Bindings involving those dictionaries
+ pat_args :: HsConDetails id (LPat id),
+ pat_ty :: Type -- The type of the pattern
+ }
------------ Literal and n+k patterns ---------------
| LitPat HsLit -- Used for *non-overloaded* literal patterns:
------------ Dictionary patterns (translation only) ---------------
| DictPat -- Used when destructing Dictionaries with an explicit case
- [id] -- superclass dicts
- [id] -- methods
+ [id] -- Superclass dicts
+ [id] -- Methods
+
+ ------------ Pattern coercions (translation only) ---------------
+ | CoPat HsWrapper -- If co::t1 -> t2, p::t2,
+ -- then (CoPat co p) :: t1
+ (Pat id) -- Why not LPat? Ans: existing locn will do
+ Type
+ -- During desugaring a (CoPat co pat) turns into a cast with 'co' on
+ -- the scrutinee, followed by a match on 'pat'
\end{code}
HsConDetails is use both for patterns and for data type declarations
\begin{code}
data HsConDetails id arg
- = PrefixCon [arg] -- C p1 p2 p3
- | RecCon [(Located id, arg)] -- C { x = p1, y = p2 }
- | InfixCon arg arg -- p1 `C` p2
+ = PrefixCon [arg] -- C p1 p2 p3
+ | RecCon [HsRecField id arg] -- C { x = p1, y = p2 }
+ | InfixCon arg arg -- p1 `C` p2
+
+data HsRecField id arg = HsRecField {
+ hsRecFieldId :: Located id,
+ hsRecFieldArg :: arg,
+ hsRecFieldDoc :: Maybe (LHsDoc id)
+}
+
+mkRecField id arg = HsRecField id arg Nothing
hsConArgs :: HsConDetails id arg -> [arg]
hsConArgs (PrefixCon ps) = ps
-hsConArgs (RecCon fs) = map snd fs
+hsConArgs (RecCon fs) = map hsRecFieldArg fs
hsConArgs (InfixCon p1 p2) = [p1,p2]
\end{code}
pprPat (TuplePat pats bx _) = tupleParens bx (interpp'SP pats)
pprPat (ConPatIn con details) = pprUserCon con details
-pprPat (ConPatOut con tvs dicts binds details _)
+pprPat (ConPatOut { pat_con = con, pat_tvs = tvs, pat_dicts = dicts,
+ pat_binds = binds, pat_args = details })
= getPprStyle $ \ sty -> -- Tiresome; in TcBinds.tcRhs we print out a
if debugStyle sty then -- typechecked Pat in an error message,
-- and we want to make sure it prints nicely
pprPat (NPat l (Just _) _ _) = char '-' <> ppr l
pprPat (NPlusKPat n k _ _) = hcat [ppr n, char '+', ppr k]
pprPat (TypePat ty) = ptext SLIT("{|") <> ppr ty <> ptext SLIT("|}")
+pprPat (CoPat co pat _) = parens (pprHsWrapper (ppr pat) co)
pprPat (SigPatIn pat ty) = ppr pat <+> dcolon <+> ppr ty
pprPat (SigPatOut pat ty) = ppr pat <+> dcolon <+> ppr ty
pprPat (DictPat ds ms) = parens (sep [ptext SLIT("{-dict-}"),
pprConArgs (InfixCon p1 p2) = interppSP [p1,p2]
pprConArgs (RecCon rpats) = braces (hsep (punctuate comma (map (pp_rpat) rpats)))
where
- pp_rpat (v, p) = hsep [ppr v, char '=', ppr p]
-
+ pp_rpat (HsRecField v p d) =
+ hsep [ppr d, ppr v, char '=', ppr p]
-- add parallel array brackets around a document
--
pabrackets :: SDoc -> SDoc
pabrackets p = ptext SLIT("[:") <> p <> ptext SLIT(":]")
+
+instance (OutputableBndr id, Outputable arg) =>
+ Outputable (HsRecField id arg) where
+ ppr (HsRecField n ty doc) = ppr n <+> dcolon <+> ppr ty <+> ppr_mbDoc doc
\end{code}
\begin{code}
mkPrefixConPat :: DataCon -> [OutPat id] -> Type -> OutPat id
-- Make a vanilla Prefix constructor pattern
-mkPrefixConPat dc pats ty = noLoc $ ConPatOut (noLoc dc) [] [] emptyLHsBinds (PrefixCon pats) ty
+mkPrefixConPat dc pats ty
+ = noLoc $ ConPatOut { pat_con = noLoc dc, pat_tvs = [], pat_dicts = [],
+ pat_binds = emptyLHsBinds, pat_args = PrefixCon pats,
+ pat_ty = ty }
mkNilPat :: Type -> OutPat id
mkNilPat ty = mkPrefixConPat nilDataCon [] ty
mkCharLitPat :: Char -> OutPat id
mkCharLitPat c = mkPrefixConPat charDataCon [noLoc $ LitPat (HsCharPrim c)] charTy
+
+mkCoPat :: HsWrapper -> OutPat id -> Type -> OutPat id
+mkCoPat co lpat@(L loc pat) ty
+ | isIdHsWrapper co = lpat
+ | otherwise = L loc (CoPat co pat ty)
\end{code}
patsAreAllCons :: [Pat id] -> Bool
patsAreAllCons pat_list = all isConPat pat_list
-isConPat (AsPat _ pat) = isConPat (unLoc pat)
-isConPat (ConPatIn _ _) = True
-isConPat (ConPatOut _ _ _ _ _ _) = True
-isConPat (ListPat _ _) = True
-isConPat (PArrPat _ _) = True
-isConPat (TuplePat _ _ _) = True
-isConPat (DictPat ds ms) = (length ds + length ms) > 1
-isConPat other = False
+isConPat (AsPat _ pat) = isConPat (unLoc pat)
+isConPat (ConPatIn {}) = True
+isConPat (ConPatOut {}) = True
+isConPat (ListPat {}) = True
+isConPat (PArrPat {}) = True
+isConPat (TuplePat {}) = True
+isConPat (DictPat ds ms) = (length ds + length ms) > 1
+isConPat other = False
isSigPat (SigPatIn _ _) = True
isSigPat (SigPatOut _ _) = True
go1 (VarPatOut _ _) = True
go1 (LazyPat pat) = True
go1 (BangPat pat) = go pat
+ go1 (CoPat _ pat _) = go1 pat
go1 (ParPat pat) = go pat
go1 (AsPat _ pat) = go pat
go1 (SigPatIn pat _) = go pat
go1 (PArrPat pats _) = False -- ?
go1 (ConPatIn _ _) = False -- Conservative
- go1 (ConPatOut (L _ con) _ _ _ details _)
+ go1 (ConPatOut{ pat_con = L _ con, pat_args = details })
= isProductTyCon (dataConTyCon con)
&& all go (hsConArgs details)