summaryrefslogtreecommitdiff
path: root/compiler/hsSyn/HsPat.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/hsSyn/HsPat.hs')
-rw-r--r--compiler/hsSyn/HsPat.hs203
1 files changed, 125 insertions, 78 deletions
diff --git a/compiler/hsSyn/HsPat.hs b/compiler/hsSyn/HsPat.hs
index 5c7a6f1b81..8ec39bc1f5 100644
--- a/compiler/hsSyn/HsPat.hs
+++ b/compiler/hsSyn/HsPat.hs
@@ -15,6 +15,8 @@
-- in module PlaceHolder
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE FlexibleInstances #-}
module HsPat (
Pat(..), InPat, OutPat, LPat,
@@ -70,7 +72,7 @@ import Data.Data hiding (TyCon,Fixity)
type InPat p = LPat p -- No 'Out' constructors
type OutPat p = LPat p -- No 'In' constructors
-type LPat p = Located (Pat p)
+type LPat p = Pat p
-- | Pattern
--
@@ -324,7 +326,34 @@ type instance XSigPat GhcRn = NoExt
type instance XSigPat GhcTc = Type
type instance XCoPat (GhcPass _) = NoExt
-type instance XXPat (GhcPass _) = NoExt
+type instance XXPat (GhcPass p) = Located (Pat (GhcPass p))
+
+
+{-
+************************************************************************
+* *
+* HasSrcSpan Instance
+* *
+************************************************************************
+-}
+
+type instance SrcSpanLess (LPat (GhcPass p)) = Pat (GhcPass p)
+instance HasSrcSpan (LPat (GhcPass p)) where
+ -- NB: The following chooses the behaviour of the outer location
+ -- wrapper replacing the inner ones.
+ composeSrcSpan (L sp p) = if sp == noSrcSpan
+ then p
+ else XPat (L sp (stripSrcSpanPat p))
+
+ -- NB: The following only returns the top-level location, if any.
+ decomposeSrcSpan (XPat (L sp p)) = L sp (stripSrcSpanPat p)
+ decomposeSrcSpan p = L noSrcSpan p
+
+stripSrcSpanPat :: LPat (GhcPass p) -> Pat (GhcPass p)
+stripSrcSpanPat (XPat (L _ p)) = stripSrcSpanPat p
+stripSrcSpanPat p = p
+
+
-- ---------------------------------------------------------------------
@@ -489,7 +518,7 @@ pprPatBndr var -- Print with type info if -dppr-debug is on
pprParendLPat :: (OutputableBndrId (GhcPass p))
=> PprPrec -> LPat (GhcPass p) -> SDoc
-pprParendLPat p (L _ pat) = pprParendPat p pat
+pprParendLPat p = pprParendPat p . unLoc
pprParendPat :: (OutputableBndrId (GhcPass p))
=> PprPrec -> Pat (GhcPass p) -> SDoc
@@ -507,7 +536,7 @@ pprParendPat p pat = sdocWithDynFlags $ \ dflags ->
-- is the pattern inside that matters. Sigh.
pprPat :: (OutputableBndrId (GhcPass p)) => Pat (GhcPass p) -> SDoc
-pprPat (VarPat _ (L _ var)) = pprPatBndr var
+pprPat (VarPat _ lvar) = pprPatBndr (unLoc lvar)
pprPat (WildPat _) = char '_'
pprPat (LazyPat _ pat) = char '~' <> pprParendLPat appPrec pat
pprPat (BangPat _ pat) = char '!' <> pprParendLPat appPrec pat
@@ -530,8 +559,11 @@ pprPat (TuplePat _ pats bx) = tupleParens (boxityTupleSort bx)
(pprWithCommas ppr pats)
pprPat (SumPat _ pat alt arity) = sumParens (pprAlternative ppr pat alt arity)
pprPat (ConPatIn con details) = pprUserCon (unLoc con) details
-pprPat (ConPatOut { pat_con = con, pat_tvs = tvs, pat_dicts = dicts,
- pat_binds = binds, pat_args = details })
+pprPat (ConPatOut { pat_con = con
+ , pat_tvs = tvs
+ , pat_dicts = dicts
+ , pat_binds = binds
+ , pat_args = details })
= sdocWithDynFlags $ \dflags ->
-- Tiresome; in TcBinds.tcRhs we print out a
-- typechecked Pat in an error message,
@@ -581,14 +613,19 @@ instance (Outputable p, Outputable arg)
************************************************************************
-}
-mkPrefixConPat :: DataCon -> [OutPat p] -> [Type] -> OutPat p
+mkPrefixConPat :: DataCon ->
+ [OutPat (GhcPass p)] -> [Type] -> OutPat (GhcPass p)
-- Make a vanilla Prefix constructor pattern
mkPrefixConPat dc pats tys
- = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc), pat_tvs = [], pat_dicts = [],
- pat_binds = emptyTcEvBinds, pat_args = PrefixCon pats,
- pat_arg_tys = tys, pat_wrap = idHsWrapper }
-
-mkNilPat :: Type -> OutPat p
+ = noLoc $ ConPatOut { pat_con = noLoc (RealDataCon dc)
+ , pat_tvs = []
+ , pat_dicts = []
+ , pat_binds = emptyTcEvBinds
+ , pat_args = PrefixCon pats
+ , pat_arg_tys = tys
+ , pat_wrap = idHsWrapper }
+
+mkNilPat :: Type -> OutPat (GhcPass p)
mkNilPat ty = mkPrefixConPat nilDataCon [] [ty]
mkCharLitPat :: SourceText -> Char -> OutPat (GhcPass p)
@@ -627,12 +664,15 @@ patterns are treated specially, of course.
The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
-}
-isBangedLPat :: LPat p -> Bool
-isBangedLPat (L _ (ParPat _ p)) = isBangedLPat p
-isBangedLPat (L _ (BangPat {})) = True
-isBangedLPat _ = False
+isBangedLPat :: LPat (GhcPass p) -> Bool
+isBangedLPat = isBangedPat . unLoc
-looksLazyPatBind :: HsBind p -> Bool
+isBangedPat :: Pat (GhcPass p) -> Bool
+isBangedPat (ParPat _ p) = isBangedLPat p
+isBangedPat (BangPat {}) = True
+isBangedPat _ = False
+
+looksLazyPatBind :: HsBind (GhcPass p) -> Bool
-- Returns True of anything *except*
-- a StrictHsBind (as above) or
-- a VarPat
@@ -645,15 +685,18 @@ looksLazyPatBind (AbsBinds { abs_binds = binds })
looksLazyPatBind _
= False
-looksLazyLPat :: LPat p -> Bool
-looksLazyLPat (L _ (ParPat _ p)) = looksLazyLPat p
-looksLazyLPat (L _ (AsPat _ _ p)) = looksLazyLPat p
-looksLazyLPat (L _ (BangPat {})) = False
-looksLazyLPat (L _ (VarPat {})) = False
-looksLazyLPat (L _ (WildPat {})) = False
-looksLazyLPat _ = True
+looksLazyLPat :: LPat (GhcPass p) -> Bool
+looksLazyLPat = looksLazyPat . unLoc
+
+looksLazyPat :: Pat (GhcPass p) -> Bool
+looksLazyPat (ParPat _ p) = looksLazyLPat p
+looksLazyPat (AsPat _ _ p) = looksLazyLPat p
+looksLazyPat (BangPat {}) = False
+looksLazyPat (VarPat {}) = False
+looksLazyPat (WildPat {}) = False
+looksLazyPat _ = True
-isIrrefutableHsPat :: (OutputableBndrId p) => LPat p -> Bool
+isIrrefutableHsPat :: (OutputableBndrId (GhcPass p)) => LPat (GhcPass p) -> Bool
-- (isIrrefutableHsPat p) is true if matching against p cannot fail,
-- in the sense of falling through to the next pattern.
-- (NB: this is not quite the same as the (silly) defn
@@ -666,43 +709,47 @@ isIrrefutableHsPat :: (OutputableBndrId p) => LPat p -> Bool
-- tuple patterns are considered irrefuable at the renamer stage.
--
-- But if it returns True, the pattern is definitely irrefutable
-isIrrefutableHsPat pat
- = go pat
+isIrrefutableHsPat
+ = goL
where
- go (L _ pat) = go1 pat
-
- go1 (WildPat {}) = True
- go1 (VarPat {}) = True
- go1 (LazyPat {}) = True
- go1 (BangPat _ pat) = go pat
- go1 (CoPat _ _ pat _) = go1 pat
- go1 (ParPat _ pat) = go pat
- go1 (AsPat _ _ pat) = go pat
- go1 (ViewPat _ _ pat) = go pat
- go1 (SigPat _ pat _) = go pat
- go1 (TuplePat _ pats _) = all go pats
- go1 (SumPat {}) = False
+ goL = go . unLoc
+
+ go (WildPat {}) = True
+ go (VarPat {}) = True
+ go (LazyPat {}) = True
+ go (BangPat _ pat) = goL pat
+ go (CoPat _ _ pat _) = go pat
+ go (ParPat _ pat) = goL pat
+ go (AsPat _ _ pat) = goL pat
+ go (ViewPat _ _ pat) = goL pat
+ go (SigPat _ pat _) = goL pat
+ go (TuplePat _ pats _) = all goL pats
+ go (SumPat {}) = False
-- See Note [Unboxed sum patterns aren't irrefutable]
- go1 (ListPat {}) = False
-
- go1 (ConPatIn {}) = False -- Conservative
- go1 (ConPatOut{ pat_con = L _ (RealDataCon con), pat_args = details })
- = isJust (tyConSingleDataCon_maybe (dataConTyCon con))
- -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because
- -- the latter is false of existentials. See Trac #4439
- && all go (hsConPatArgs details)
- go1 (ConPatOut{ pat_con = L _ (PatSynCon _pat) })
- = False -- Conservative
-
- go1 (LitPat {}) = False
- go1 (NPat {}) = False
- go1 (NPlusKPat {}) = False
+ go (ListPat {}) = False
+
+ go (ConPatIn {}) = False -- Conservative
+ go (ConPatOut
+ { pat_con = (dL->L _ (RealDataCon con))
+ , pat_args = details })
+ =
+ isJust (tyConSingleDataCon_maybe (dataConTyCon con))
+ -- NB: tyConSingleDataCon_maybe, *not* isProductTyCon, because
+ -- the latter is false of existentials. See Trac #4439
+ && all goL (hsConPatArgs details)
+ go (ConPatOut
+ { pat_con = (dL->L _ (PatSynCon _pat)) })
+ = False -- Conservative
+ go (ConPatOut{}) = panic "ConPatOut:Impossible Match" -- due to #15884
+ go (LitPat {}) = False
+ go (NPat {}) = False
+ go (NPlusKPat {}) = False
-- We conservatively assume that no TH splices are irrefutable
-- since we cannot know until the splice is evaluated.
- go1 (SplicePat {}) = False
+ go (SplicePat {}) = False
- go1 (XPat {}) = False
+ go (XPat {}) = False
{- Note [Unboxed sum patterns aren't irrefutable]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -731,25 +778,25 @@ is the only thing that could possibly be matched!
patNeedsParens :: PprPrec -> Pat p -> Bool
patNeedsParens p = go
where
- go (NPlusKPat {}) = p > opPrec
- go (SplicePat {}) = False
- go (ConPatIn _ ds) = conPatNeedsParens p ds
- go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp)
- go (SigPat {}) = p >= sigPrec
- go (ViewPat {}) = True
- go (CoPat _ _ p _) = go p
- go (WildPat {}) = False
- go (VarPat {}) = False
- go (LazyPat {}) = False
- go (BangPat {}) = False
- go (ParPat {}) = False
- go (AsPat {}) = False
- go (TuplePat {}) = False
- go (SumPat {}) = False
- go (ListPat {}) = False
- go (LitPat _ l) = hsLitNeedsParens p l
- go (NPat _ (L _ ol) _ _) = hsOverLitNeedsParens p ol
- go (XPat {}) = True -- conservative default
+ go (NPlusKPat {}) = p > opPrec
+ go (SplicePat {}) = False
+ go (ConPatIn _ ds) = conPatNeedsParens p ds
+ go cp@(ConPatOut {}) = conPatNeedsParens p (pat_args cp)
+ go (SigPat {}) = p >= sigPrec
+ go (ViewPat {}) = True
+ go (CoPat _ _ p _) = go p
+ go (WildPat {}) = False
+ go (VarPat {}) = False
+ go (LazyPat {}) = False
+ go (BangPat {}) = False
+ go (ParPat {}) = False
+ go (AsPat {}) = False
+ go (TuplePat {}) = False
+ go (SumPat {}) = False
+ go (ListPat {}) = False
+ go (LitPat _ l) = hsLitNeedsParens p l
+ go (NPat _ lol _ _) = hsOverLitNeedsParens p (unLoc lol)
+ go (XPat {}) = True -- conservative default
-- | @'conPatNeedsParens' p cp@ returns 'True' if the constructor patterns @cp@
-- needs parentheses under precedence @p@.
@@ -763,8 +810,8 @@ conPatNeedsParens p = go
-- | @'parenthesizePat' p pat@ checks if @'patNeedsParens' p pat@ is true, and
-- if so, surrounds @pat@ with a 'ParPat'. Otherwise, it simply returns @pat@.
parenthesizePat :: PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p)
-parenthesizePat p lpat@(L loc pat)
- | patNeedsParens p pat = L loc (ParPat NoExt lpat)
+parenthesizePat p lpat@(dL->L loc pat)
+ | patNeedsParens p pat = cL loc (ParPat NoExt lpat)
| otherwise = lpat
{-
@@ -776,7 +823,7 @@ collectEvVarsPats :: [Pat GhcTc] -> Bag EvVar
collectEvVarsPats = unionManyBags . map collectEvVarsPat
collectEvVarsLPat :: LPat GhcTc -> Bag EvVar
-collectEvVarsLPat (L _ pat) = collectEvVarsPat pat
+collectEvVarsLPat = collectEvVarsPat . unLoc
collectEvVarsPat :: Pat GhcTc -> Bag EvVar
collectEvVarsPat pat =