diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2018-09-20 20:02:39 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2018-09-23 02:45:23 +0100 |
commit | 4bde71df9a32bf6f5ee7d44fbbf79523da4b0a9e (patch) | |
tree | a629d95f46f0e0c80279168f855b5ac4e36d07e5 /compiler/rename | |
parent | cad5d0b69bc039b635a6eb0e5c9ed47d7c5a38ed (diff) | |
download | haskell-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.hs | 22 |
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 |