summaryrefslogtreecommitdiff
path: root/compiler/rename
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2018-09-20 20:02:39 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2018-09-23 02:45:23 +0100
commit4bde71df9a32bf6f5ee7d44fbbf79523da4b0a9e (patch)
treea629d95f46f0e0c80279168f855b5ac4e36d07e5 /compiler/rename
parentcad5d0b69bc039b635a6eb0e5c9ed47d7c5a38ed (diff)
downloadhaskell-4bde71df9a32bf6f5ee7d44fbbf79523da4b0a9e.tar.gz
Don't look up unnecessary return in LastStmt
This fixes Trac #15607. The general pattern is well established (e.g. see the guard_op binding in rnStmt of BodyStme), but we weren't using it for LastStmt.
Diffstat (limited to 'compiler/rename')
-rw-r--r--compiler/rename/RnExpr.hs22
1 files changed, 17 insertions, 5 deletions
diff --git a/compiler/rename/RnExpr.hs b/compiler/rename/RnExpr.hs
index b9e097c4d8..ae2bdf7a2b 100644
--- a/compiler/rename/RnExpr.hs
+++ b/compiler/rename/RnExpr.hs
@@ -826,20 +826,29 @@ rnStmt :: Outputable (body GhcPs)
rnStmt ctxt rnBody (L loc (LastStmt _ body noret _)) thing_inside
= do { (body', fv_expr) <- rnBody body
- ; (ret_op, fvs1) <- lookupStmtName ctxt returnMName
- ; (thing, fvs3) <- thing_inside []
+ ; (ret_op, fvs1) <- if isMonadCompContext ctxt
+ then lookupStmtName ctxt returnMName
+ else return (noSyntaxExpr, emptyFVs)
+ -- The 'return' in a LastStmt is used only
+ -- for MonadComp; and we don't want to report
+ -- "non in scope: return" in other cases
+ -- Trac #15607
+
+ ; (thing, fvs3) <- thing_inside []
; return (([(L loc (LastStmt noExt body' noret ret_op), fv_expr)]
, thing), fv_expr `plusFV` fvs1 `plusFV` fvs3) }
rnStmt ctxt rnBody (L loc (BodyStmt _ body _ _)) thing_inside
= do { (body', fv_expr) <- rnBody body
; (then_op, fvs1) <- lookupStmtName ctxt thenMName
- ; (guard_op, fvs2) <- if isListCompExpr ctxt
+
+ ; (guard_op, fvs2) <- if isComprehensionContext ctxt
then lookupStmtName ctxt guardMName
else return (noSyntaxExpr, emptyFVs)
-- Only list/monad comprehensions use 'guard'
-- Also for sub-stmts of same eg [ e | x<-xs, gd | blah ]
-- Here "gd" is a guard
+
; (thing, fvs3) <- thing_inside []
; return ( ([(L loc (BodyStmt noExt body' then_op guard_op), fv_expr)]
, thing), fv_expr `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) }
@@ -854,14 +863,17 @@ rnStmt ctxt rnBody (L loc (BindStmt _ pat body _ _)) thing_inside
-- If the pattern is irrefutable (e.g.: wildcard, tuple,
-- ~pat, etc.) we should not need to fail.
| isIrrefutableHsPat pat
- = return (noSyntaxExpr, emptyFVs)
+ = return (noSyntaxExpr, emptyFVs)
+
-- For non-monadic contexts (e.g. guard patterns, list
-- comprehensions, etc.) we should not need to fail.
-- See Note [Failing pattern matches in Stmts]
| not (isMonadFailStmtContext ctxt)
- = return (noSyntaxExpr, emptyFVs)
+ = return (noSyntaxExpr, emptyFVs)
+
| xMonadFailEnabled = lookupSyntaxName failMName
| otherwise = lookupSyntaxName failMName_preMFP
+
; (fail_op, fvs2) <- getFailFunction
; rnPat (StmtCtxt ctxt) pat $ \ pat' -> do