summaryrefslogtreecommitdiff
path: root/compiler/hsSyn
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2017-10-26 11:23:23 +0100
committerSimon Marlow <marlowsd@gmail.com>2017-10-27 14:48:23 +0100
commit41f905596dc2560f29657753e4c69ce695161786 (patch)
tree071774ec3b99b5644f3b16f25e464f2da2558eef /compiler/hsSyn
parent7d7d94fb4876dc7e58263abc9dd65921e09cddac (diff)
downloadhaskell-41f905596dc2560f29657753e4c69ce695161786.tar.gz
ApplicativeDo: handle BodyStmt (#12143)
Summary: It's simple to treat BodyStmt just like a BindStmt with a wildcard pattern, which is enough to fix #12143 without going all the way to using `<*` and `*>` (#10892). Test Plan: * new test cases in `ado004.hs` * validate Reviewers: niteria, simonpj, bgamari, austin, erikd Subscribers: rwbarton, thomie GHC Trac Issues: #12143 Differential Revision: https://phabricator.haskell.org/D4128
Diffstat (limited to 'compiler/hsSyn')
-rw-r--r--compiler/hsSyn/HsExpr.hs57
-rw-r--r--compiler/hsSyn/HsUtils.hs2
2 files changed, 50 insertions, 9 deletions
diff --git a/compiler/hsSyn/HsExpr.hs b/compiler/hsSyn/HsExpr.hs
index 1cfaa79af5..fedaa4491a 100644
--- a/compiler/hsSyn/HsExpr.hs
+++ b/compiler/hsSyn/HsExpr.hs
@@ -1777,13 +1777,18 @@ deriving instance (DataId idL, DataId idR) => Data (ParStmtBlock idL idR)
-- | Applicative Argument
data ApplicativeArg idL idR
- = ApplicativeArgOne -- pat <- expr (pat must be irrefutable)
- (LPat idL)
+ = ApplicativeArgOne -- A single statement (BindStmt or BodyStmt)
+ (LPat idL) -- WildPat if it was a BodyStmt (see below)
(LHsExpr idL)
- | ApplicativeArgMany -- do { stmts; return vars }
- [ExprLStmt idL] -- stmts
- (HsExpr idL) -- return (v1,..,vn), or just (v1,..,vn)
- (LPat idL) -- (v1,...,vn)
+ Bool -- True <=> was a BodyStmt
+ -- False <=> was a BindStmt
+ -- See Note [Applicative BodyStmt]
+
+ | ApplicativeArgMany -- do { stmts; return vars }
+ [ExprLStmt idL] -- stmts
+ (HsExpr idL) -- return (v1,..,vn), or just (v1,..,vn)
+ (LPat idL) -- (v1,...,vn)
+
deriving instance (DataId idL, DataId idR) => Data (ApplicativeArg idL idR)
{-
@@ -1921,6 +1926,34 @@ Parallel statements require the 'Control.Monad.Zip.mzip' function:
In any other context than 'MonadComp', the fields for most of these
'SyntaxExpr's stay bottom.
+
+
+Note [Applicative BodyStmt]
+
+(#12143) For the purposes of ApplicativeDo, we treat any BodyStmt
+as if it was a BindStmt with a wildcard pattern. For example,
+
+ do
+ x <- A
+ B
+ return x
+
+is transformed as if it were
+
+ do
+ x <- A
+ _ <- B
+ return x
+
+so it transforms to
+
+ (\(x,_) -> x) <$> A <*> B
+
+But we have to remember when we treat a BodyStmt like a BindStmt,
+because in error messages we want to emit the original syntax the user
+wrote, not our internal representation. So ApplicativeArgOne has a
+Bool flag that is True when the original statement was a BodyStmt, so
+that we can pretty-print it correctly.
-}
instance (SourceTextX idL, OutputableBndrId idL)
@@ -1973,7 +2006,11 @@ pprStmt (ApplicativeStmt args mb_join _)
flattenStmt (L _ (ApplicativeStmt args _ _)) = concatMap flattenArg args
flattenStmt stmt = [ppr stmt]
- flattenArg (_, ApplicativeArgOne pat expr) =
+ flattenArg (_, ApplicativeArgOne pat expr isBody)
+ | isBody = -- See Note [Applicative BodyStmt]
+ [ppr (BodyStmt expr noSyntaxExpr noSyntaxExpr (panic "pprStmt")
+ :: ExprStmt idL)]
+ | otherwise =
[ppr (BindStmt pat expr noSyntaxExpr noSyntaxExpr (panic "pprStmt")
:: ExprStmt idL)]
flattenArg (_, ApplicativeArgMany stmts _ _) =
@@ -1987,7 +2024,11 @@ pprStmt (ApplicativeStmt args mb_join _)
then ap_expr
else text "join" <+> parens ap_expr
- pp_arg (_, ApplicativeArgOne pat expr) =
+ pp_arg (_, ApplicativeArgOne pat expr isBody)
+ | isBody = -- See Note [Applicative BodyStmt]
+ ppr (BodyStmt expr noSyntaxExpr noSyntaxExpr (panic "pprStmt")
+ :: ExprStmt idL)
+ | otherwise =
ppr (BindStmt pat expr noSyntaxExpr noSyntaxExpr (panic "pprStmt")
:: ExprStmt idL)
pp_arg (_, ApplicativeArgMany stmts return pat) =
diff --git a/compiler/hsSyn/HsUtils.hs b/compiler/hsSyn/HsUtils.hs
index 3c1726b306..8e17994993 100644
--- a/compiler/hsSyn/HsUtils.hs
+++ b/compiler/hsSyn/HsUtils.hs
@@ -1197,7 +1197,7 @@ lStmtsImplicits = hs_lstmts
hs_stmt :: StmtLR GhcRn idR (Located (body idR)) -> NameSet
hs_stmt (BindStmt pat _ _ _ _) = lPatImplicits pat
hs_stmt (ApplicativeStmt args _ _) = unionNameSets (map do_arg args)
- where do_arg (_, ApplicativeArgOne pat _) = lPatImplicits pat
+ where do_arg (_, ApplicativeArgOne pat _ _) = lPatImplicits pat
do_arg (_, ApplicativeArgMany stmts _ _) = hs_lstmts stmts
hs_stmt (LetStmt binds) = hs_local_binds (unLoc binds)
hs_stmt (BodyStmt {}) = emptyNameSet