summaryrefslogtreecommitdiff
path: root/compiler/GHC/HsToCore/Match.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/HsToCore/Match.hs')
-rw-r--r--compiler/GHC/HsToCore/Match.hs57
1 files changed, 28 insertions, 29 deletions
diff --git a/compiler/GHC/HsToCore/Match.hs b/compiler/GHC/HsToCore/Match.hs
index 5dc7328879..f3263c00f4 100644
--- a/compiler/GHC/HsToCore/Match.hs
+++ b/compiler/GHC/HsToCore/Match.hs
@@ -35,6 +35,7 @@ import GHC.Tc.Utils.Zonk
import GHC.Tc.Types.Evidence
import GHC.Tc.Utils.Monad
import GHC.HsToCore.PmCheck
+import GHC.HsToCore.PmCheck.Types ( Deltas, initDeltas )
import GHC.Core
import GHC.Types.Literal
import GHC.Core.Utils
@@ -64,7 +65,7 @@ import GHC.Data.FastString
import GHC.Types.Unique
import GHC.Types.Unique.DFM
-import Control.Monad( unless )
+import Control.Monad(zipWithM, unless )
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NEL
import qualified Data.Map as Map
@@ -766,49 +767,47 @@ matchWrapper ctxt mb_scr (MG { mg_alts = L _ matches
-- Pattern match check warnings for /this match-group/.
-- @rhss_deltas@ is a flat list of covered Deltas for each RHS.
-- Each Match will split off one Deltas for its RHSs from this.
- ; rhss_deltas <- if isMatchContextPmChecked dflags origin ctxt
+ ; matches_deltas <- if isMatchContextPmChecked dflags origin ctxt
then addScrutTmCs mb_scr new_vars $
- -- See Note [Type and Term Equality Propagation]
- checkMatches (DsMatchContext ctxt locn) new_vars matches
- else pure [] -- Ultimately this will result in passing Nothing
- -- to dsGRHSs as match_deltas
+ -- See Note [Type and Term Equality Propagation]
+ checkMatches (DsMatchContext ctxt locn) new_vars matches
+ else pure (initDeltasMatches matches)
- ; eqns_info <- mk_eqn_infos matches rhss_deltas
+ ; eqns_info <- zipWithM mk_eqn_info matches matches_deltas
; result_expr <- handleWarnings $
matchEquations ctxt new_vars eqns_info rhs_ty
; return (new_vars, result_expr) }
where
- -- rhss_deltas is a flat list, whereas there are multiple GRHSs per match.
- -- mk_eqn_infos will thread rhss_deltas as state through calls to
- -- mk_eqn_info, distributing each rhss_deltas to a GRHS.
- mk_eqn_infos (L _ match : matches) rhss_deltas
- = do { (info, rhss_deltas') <- mk_eqn_info match rhss_deltas
- ; infos <- mk_eqn_infos matches rhss_deltas'
- ; return (info:infos) }
- mk_eqn_infos [] _ = return []
-- Called once per equation in the match, or alternative in the case
- mk_eqn_info (Match { m_pats = pats, m_grhss = grhss }) rhss_deltas
- | GRHSs _ grhss' _ <- grhss, let n_grhss = length grhss'
+ mk_eqn_info :: LMatch GhcTc (LHsExpr GhcTc) -> (Deltas, NonEmpty Deltas) -> DsM EquationInfo
+ mk_eqn_info (L _ (Match { m_pats = pats, m_grhss = grhss })) (pat_deltas, rhss_deltas)
= do { dflags <- getDynFlags
; let upats = map (unLoc . decideBangHood dflags) pats
- -- Split off one Deltas for each GRHS of the current Match from the
- -- flat list of GRHS Deltas *for all matches* (see the call to
- -- checkMatches above).
- ; let (match_deltas, rhss_deltas') = splitAt n_grhss rhss_deltas
- -- The list of Deltas is empty iff we don't perform any coverage
- -- checking, in which case nonEmpty does the right thing by passing
- -- Nothing.
- ; match_result <- dsGRHSs ctxt grhss rhs_ty (NEL.nonEmpty match_deltas)
- ; return ( EqnInfo { eqn_pats = upats
- , eqn_orig = FromSource
- , eqn_rhs = match_result }
- , rhss_deltas' ) }
+ -- pat_deltas is the covered set *after* matching the pattern, but
+ -- before any of the GRHSs. We extend the environment with pat_deltas
+ -- (via updPmDeltas) so that the where-clause of 'grhss' can profit
+ -- from that knowledge (#18533)
+ ; match_result <- updPmDeltas pat_deltas $
+ dsGRHSs ctxt grhss rhs_ty rhss_deltas
+ ; return EqnInfo { eqn_pats = upats
+ , eqn_orig = FromSource
+ , eqn_rhs = match_result } }
handleWarnings = if isGenerated origin
then discardWarningsDs
else id
+ initDeltasMatches :: [LMatch GhcTc b] -> [(Deltas, NonEmpty Deltas)]
+ initDeltasMatches ms
+ = map (\(L _ m) -> (initDeltas, initDeltasGRHSs (m_grhss m))) ms
+
+ initDeltasGRHSs :: GRHSs GhcTc b -> NonEmpty Deltas
+ initDeltasGRHSs m = expectJust "GRHSs non-empty"
+ $ NEL.nonEmpty
+ $ replicate (length (grhssGRHSs m)) initDeltas
+
+
matchEquations :: HsMatchContext GhcRn
-> [MatchId] -> [EquationInfo] -> Type
-> DsM CoreExpr