summaryrefslogtreecommitdiff
path: root/compiler/GHC/HsToCore/Binds.hs
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2020-02-20 16:48:16 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-02-27 16:22:45 -0500
commit74311e10bbb6ced9cd3093c8949f2535a715d8f6 (patch)
tree28ce759f7f4699dac70c24e32b303a4fa77dc198 /compiler/GHC/HsToCore/Binds.hs
parent817f93eac4d13f680e8e3e7a25eb403b1864f82e (diff)
downloadhaskell-74311e10bbb6ced9cd3093c8949f2535a715d8f6.tar.gz
PmCheck: Implement Long-distance information with Covered sets
Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227
Diffstat (limited to 'compiler/GHC/HsToCore/Binds.hs')
-rw-r--r--compiler/GHC/HsToCore/Binds.hs5
1 files changed, 3 insertions, 2 deletions
diff --git a/compiler/GHC/HsToCore/Binds.hs b/compiler/GHC/HsToCore/Binds.hs
index 86d309c73d..a80b2cc2d3 100644
--- a/compiler/GHC/HsToCore/Binds.hs
+++ b/compiler/GHC/HsToCore/Binds.hs
@@ -75,6 +75,7 @@ import UniqSet( nonDetEltsUniqSet )
import MonadUtils
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
+import Data.List.NonEmpty ( nonEmpty )
{-**********************************************************************
* *
@@ -175,8 +176,8 @@ dsHsBind dflags b@(FunBind { fun_id = L _ fun
dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss
, pat_ext = NPatBindTc _ ty
, pat_ticks = (rhs_tick, var_ticks) })
- = do { body_expr <- dsGuarded grhss ty
- ; checkGuardMatches PatBindGuards grhss
+ = do { rhss_deltas <- checkGuardMatches PatBindGuards grhss
+ ; body_expr <- dsGuarded grhss ty (nonEmpty rhss_deltas)
; let body' = mkOptTickBox rhs_tick body_expr
pat' = decideBangHood dflags pat
; (force_var,sel_binds) <- mkSelectorBinds var_ticks pat body'