[commit: ghc] master: Desugar bang patterns correctly (fixes Trac #7649) (4430227)
Simon Peyton Jones
simonpj at microsoft.com
Wed Feb 13 18:44:08 CET 2013
Repository : ssh://darcs.haskell.org//srv/darcs/ghc
On branch : master
http://hackage.haskell.org/trac/ghc/changeset/44302272b568bc86f0e62579f6707e6e9ae8e4ab
>---------------------------------------------------------------
commit 44302272b568bc86f0e62579f6707e6e9ae8e4ab
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Wed Feb 13 17:42:18 2013 +0000
Desugar bang patterns correctly (fixes Trac #7649)
We were discarding a bang around a view pattern, which is
utterly wrong
>---------------------------------------------------------------
compiler/deSugar/Match.lhs | 42 ++++++++++++++++++++++++++++--------------
1 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/compiler/deSugar/Match.lhs b/compiler/deSugar/Match.lhs
index 2de2bb4..5b0f3b1 100644
--- a/compiler/deSugar/Match.lhs
+++ b/compiler/deSugar/Match.lhs
@@ -507,6 +507,7 @@ tidy1 :: Id -- The Id being scrutinised
tidy1 v (ParPat pat) = tidy1 v (unLoc pat)
tidy1 v (SigPatOut pat _) = tidy1 v (unLoc pat)
tidy1 _ (WildPat ty) = return (idDsWrapper, WildPat ty)
+tidy1 v (BangPat (L l p)) = tidy_bang_pat v l p
-- case v of { x -> mr[] }
-- = case v of { _ -> let x=v in mr[] }
@@ -565,24 +566,37 @@ tidy1 _ (LitPat lit)
tidy1 _ (NPat lit mb_neg eq)
= return (idDsWrapper, tidyNPat tidyLitPat lit mb_neg eq)
--- BangPatterns: Pattern matching is already strict in constructors,
--- tuples etc, so the last case strips off the bang for thoses patterns.
-tidy1 v (BangPat (L _ (LazyPat p))) = tidy1 v (BangPat p)
-tidy1 v (BangPat (L _ (ParPat p))) = tidy1 v (BangPat p)
-tidy1 _ p@(BangPat (L _(VarPat _))) = return (idDsWrapper, p)
-tidy1 _ p@(BangPat (L _ (WildPat _))) = return (idDsWrapper, p)
-tidy1 _ p@(BangPat (L _ (CoPat _ _ _))) = return (idDsWrapper, p)
-tidy1 _ p@(BangPat (L _ (SigPatIn _ _))) = return (idDsWrapper, p)
-tidy1 _ p@(BangPat (L _ (SigPatOut _ _))) = return (idDsWrapper, p)
-tidy1 v (BangPat (L _ (AsPat (L _ var) pat)))
- = do { (wrap, pat') <- tidy1 v (BangPat pat)
- ; return (wrapBind var v . wrap, pat') }
-tidy1 v (BangPat (L _ p)) = tidy1 v p
-
-- Everything else goes through unchanged...
tidy1 _ non_interesting_pat
= return (idDsWrapper, non_interesting_pat)
+
+--------------------
+tidy_bang_pat :: Id -> SrcSpan -> Pat Id -> DsM (DsWrapper, Pat Id)
+-- BangPatterns: Pattern matching is already strict in constructors,
+-- tuples etc, so the last case strips off the bang for those patterns.
+
+-- Discard bang around strict pattern
+tidy_bang_pat v _ p@(ListPat {}) = tidy1 v p
+tidy_bang_pat v _ p@(TuplePat {}) = tidy1 v p
+tidy_bang_pat v _ p@(PArrPat {}) = tidy1 v p
+tidy_bang_pat v _ p@(ConPatOut {}) = tidy1 v p
+tidy_bang_pat v _ p@(LitPat {}) = tidy1 v p
+
+-- Discard lazy/par/sig under a bang
+tidy_bang_pat v _ (LazyPat (L l p)) = tidy_bang_pat v l p
+tidy_bang_pat v _ (ParPat (L l p)) = tidy_bang_pat v l p
+tidy_bang_pat v _ (SigPatOut (L l p) _) = tidy_bang_pat v l p
+
+-- Push the bang-pattern inwards, in the hope that
+-- it may disappear next time
+tidy_bang_pat v l (AsPat v' p) = tidy1 v (AsPat v' (L l (BangPat p)))
+tidy_bang_pat v l (CoPat w p t) = tidy1 v (CoPat w (BangPat (L l p)) t)
+
+-- Default case, leave the bang there:
+-- VarPat, WildPat, ViewPat, NPat, NPlusKPat
+tidy_bang_pat _ l p = return (idDsWrapper, BangPat (L l p))
+ -- NB: SigPatIn, ConPatIn should not happen
\end{code}
\noindent
More information about the ghc-commits
mailing list