Simon Peyton Jones pushed to branch wip/T24464 at Glasgow Haskell Compiler / GHC

Commits:

8 changed files:

Changes:

  • compiler/GHC/HsToCore/Expr.hs
    ... ... @@ -29,6 +29,7 @@ import GHC.HsToCore.Utils
    29 29
     import GHC.HsToCore.Arrows
    
    30 30
     import GHC.HsToCore.Monad
    
    31 31
     import GHC.HsToCore.Pmc
    
    32
    +import GHC.HsToCore.Types( LdiNablas(..) )
    
    32 33
     import GHC.HsToCore.Pmc.Utils
    
    33 34
     import GHC.HsToCore.Errors.Types
    
    34 35
     import GHC.HsToCore.Quote
    
    ... ... @@ -505,7 +506,12 @@ dsExpr (HsStatic (static_ptr_ty, from_static_fun) expr@(L loc _))
    505 506
     
    
    506 507
            ; static_id <- newStaticId (mkSpecForAllTys static_fvs static_ptr_ty)
    
    507 508
     
    
    508
    -       ; emitStaticBinds [(static_id, static_rhs)]
    
    509
    +       -- Emit the static bindings to top level, but NOT when we are in
    
    510
    +       -- the auxiliary desugaring for the pattern-match checking
    
    511
    +       ; ldi_nablas <- getPmNablas
    
    512
    +       ; case ldi_nablas of
    
    513
    +           NoPmc  -> return ()
    
    514
    +           Ldi {} -> emitStaticBinds [(static_id, static_rhs)]
    
    509 515
     
    
    510 516
            ; return (App from_static_ds (mkVarApps (Var static_id) static_fvs)) }
    
    511 517
     
    

  • compiler/GHC/HsToCore/GuardedRHSs.hs
    ... ... @@ -22,7 +22,7 @@ import GHC.Core.Utils (bindNonRec)
    22 22
     
    
    23 23
     import GHC.HsToCore.Monad
    
    24 24
     import GHC.HsToCore.Utils
    
    25
    -import GHC.HsToCore.Pmc.Types ( Nablas )
    
    25
    +import GHC.HsToCore.Types
    
    26 26
     import GHC.Core.Type ( Type )
    
    27 27
     import GHC.Types.SrcLoc
    
    28 28
     import GHC.Utils.Outputable
    
    ... ... @@ -44,7 +44,7 @@ producing an expression with a runtime error in the corner case if
    44 44
     necessary.  The type argument gives the type of the @ei@.
    
    45 45
     -}
    
    46 46
     
    
    47
    -dsGuarded :: GRHSs GhcTc (LHsExpr GhcTc) -> Type -> NonEmpty Nablas -> DsM CoreExpr
    
    47
    +dsGuarded :: GRHSs GhcTc (LHsExpr GhcTc) -> Type -> NonEmpty LdiNablas -> DsM CoreExpr
    
    48 48
     dsGuarded grhss rhs_ty rhss_nablas = do
    
    49 49
         match_result <- dsGRHSs PatBindRhs grhss rhs_ty rhss_nablas
    
    50 50
         error_expr <- mkErrorAppDs nON_EXHAUSTIVE_GUARDS_ERROR_ID rhs_ty
    
    ... ... @@ -56,7 +56,7 @@ dsGuarded grhss rhs_ty rhss_nablas = do
    56 56
     dsGRHSs :: HsMatchContextRn
    
    57 57
             -> GRHSs GhcTc (LHsExpr GhcTc) -- ^ Guarded RHSs
    
    58 58
             -> Type                        -- ^ Type of RHS
    
    59
    -        -> NonEmpty Nablas             -- ^ Refined pattern match checking
    
    59
    +        -> NonEmpty LdiNablas          -- ^ Refined pattern match checking
    
    60 60
                                            --   models, one for the pattern part and
    
    61 61
                                            --   one for each GRHS.
    
    62 62
             -> DsM (MatchResult CoreExpr)
    
    ... ... @@ -73,11 +73,11 @@ dsGRHSs hs_ctx (GRHSs _ grhss binds) rhs_ty rhss_nablas
    73 73
                                  -- NB: nested dsLet inside matchResult
    
    74 74
            ; return match_result2 }
    
    75 75
     
    
    76
    -dsGRHS :: HsMatchContextRn -> Type -> Nablas -> LGRHS GhcTc (LHsExpr GhcTc)
    
    76
    +dsGRHS :: HsMatchContextRn -> Type -> LdiNablas -> LGRHS GhcTc (LHsExpr GhcTc)
    
    77 77
            -> DsM (MatchResult CoreExpr)
    
    78 78
     dsGRHS hs_ctx rhs_ty rhs_nablas (L _ (GRHS _ guards rhs))
    
    79 79
       = updPmNablas rhs_nablas $
    
    80
    -      matchGuards (map unLoc guards) hs_ctx rhs rhs_ty
    
    80
    +    matchGuards (map unLoc guards) hs_ctx rhs rhs_ty
    
    81 81
     
    
    82 82
     {-
    
    83 83
     ************************************************************************
    

  • compiler/GHC/HsToCore/Match.hs
    ... ... @@ -39,7 +39,7 @@ import GHC.Tc.Types.Evidence
    39 39
     import GHC.Tc.Utils.Monad
    
    40 40
     import GHC.HsToCore.Pmc
    
    41 41
     import GHC.HsToCore.Pmc.Utils
    
    42
    -import GHC.HsToCore.Pmc.Types ( Nablas )
    
    42
    +import GHC.HsToCore.Types ( LdiNablas )
    
    43 43
     import GHC.HsToCore.Monad
    
    44 44
     import GHC.HsToCore.Binds
    
    45 45
     import GHC.HsToCore.GuardedRHSs
    
    ... ... @@ -833,7 +833,9 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches
    833 833
             ; return (new_vars, result_expr) }
    
    834 834
       where
    
    835 835
         -- Called once per equation in the match, or alternative in the case
    
    836
    -    mk_eqn_info :: LMatch GhcTc (LHsExpr GhcTc) -> (Nablas, NonEmpty Nablas) -> DsM EquationInfo
    
    836
    +    mk_eqn_info :: LMatch GhcTc (LHsExpr GhcTc)
    
    837
    +                -> (LdiNablas, NonEmpty LdiNablas)
    
    838
    +                -> DsM EquationInfo
    
    837 839
         mk_eqn_info (L _ (Match { m_pats = L _ pats, m_grhss = grhss })) (pat_nablas, rhss_nablas)
    
    838 840
           = do { dflags <- getDynFlags
    
    839 841
                ; let upats = map (decideBangHood dflags) pats
    
    ... ... @@ -850,13 +852,6 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches
    850 852
           then id
    
    851 853
           else discardWarningsDs
    
    852 854
     
    
    853
    -    initNablasMatches :: Nablas -> [LMatch GhcTc b] -> [(Nablas, NonEmpty Nablas)]
    
    854
    -    initNablasMatches ldi_nablas ms
    
    855
    -      = map (\(L _ m) -> (ldi_nablas, initNablasGRHSs ldi_nablas (m_grhss m))) ms
    
    856
    -
    
    857
    -    initNablasGRHSs :: Nablas -> GRHSs GhcTc b -> NonEmpty Nablas
    
    858
    -    initNablasGRHSs ldi_nablas m = ldi_nablas <$ grhssGRHSs m
    
    859
    -
    
    860 855
     {- Note [Long-distance information in matchWrapper]
    
    861 856
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    862 857
     The pattern match checking in matchWrapper is done conditionally, depending
    
    ... ... @@ -985,7 +980,7 @@ matchSinglePatVar var mb_scrut ctx pat ty match_result
    985 980
     
    
    986 981
            ; match [var] ty [eqn_info] }
    
    987 982
     
    
    988
    -updPmNablasMatchResult :: Nablas -> MatchResult r -> MatchResult r
    
    983
    +updPmNablasMatchResult :: LdiNablas -> MatchResult r -> MatchResult r
    
    989 984
     updPmNablasMatchResult nablas = \case
    
    990 985
       MR_Infallible body_fn -> MR_Infallible $
    
    991 986
         updPmNablas nablas body_fn
    

  • compiler/GHC/HsToCore/Monad.hs
    ... ... @@ -65,7 +65,7 @@ import GHC.Hs
    65 65
     
    
    66 66
     import GHC.HsToCore.Types
    
    67 67
     import GHC.HsToCore.Errors.Types
    
    68
    -import GHC.HsToCore.Pmc.Solver.Types (Nablas, initNablas)
    
    68
    +import GHC.HsToCore.Pmc.Solver.Types (initNablas)
    
    69 69
     
    
    70 70
     import GHC.Core.FamInstEnv
    
    71 71
     import GHC.Core
    
    ... ... @@ -416,7 +416,7 @@ mkDsEnvs unit_env mod rdr_env type_env fam_inst_env ptc msg_var cc_st_var
    416 416
                                }
    
    417 417
             lcl_env = DsLclEnv { dsl_meta        = emptyNameEnv
    
    418 418
                                , dsl_loc         = real_span
    
    419
    -                           , dsl_nablas      = initNablas
    
    419
    +                           , dsl_nablas      = Ldi initNablas
    
    420 420
                                , dsl_unspecables = Just emptyVarSet
    
    421 421
                                }
    
    422 422
         in (gbl_env, lcl_env)
    
    ... ... @@ -479,12 +479,12 @@ getGhcModeDs :: DsM GhcMode
    479 479
     getGhcModeDs =  getDynFlags >>= return . ghcMode
    
    480 480
     
    
    481 481
     -- | Get the current pattern match oracle state. See 'dsl_nablas'.
    
    482
    -getPmNablas :: DsM Nablas
    
    482
    +getPmNablas :: DsM LdiNablas
    
    483 483
     getPmNablas = do { env <- getLclEnv; return (dsl_nablas env) }
    
    484 484
     
    
    485 485
     -- | Set the pattern match oracle state within the scope of the given action.
    
    486 486
     -- See 'dsl_nablas'.
    
    487
    -updPmNablas :: Nablas -> DsM a -> DsM a
    
    487
    +updPmNablas :: LdiNablas -> DsM a -> DsM a
    
    488 488
     updPmNablas nablas = updLclEnv (\env -> env { dsl_nablas = nablas })
    
    489 489
     
    
    490 490
     addUnspecables :: [EvVar] -> DsM a -> DsM a
    

  • compiler/GHC/HsToCore/Pmc.hs
    ... ... @@ -30,6 +30,7 @@
    30 30
     module GHC.HsToCore.Pmc (
    
    31 31
             -- Checking and printing
    
    32 32
             pmcPatBind, pmcMatches, pmcGRHSs, pmcRecSel,
    
    33
    +        initNablasMatches,
    
    33 34
             isMatchContextPmChecked, isMatchContextPmChecked_SinglePat,
    
    34 35
     
    
    35 36
             -- See Note [Long-distance information]
    
    ... ... @@ -45,6 +46,7 @@ import GHC.HsToCore.Pmc.Utils
    45 46
     import GHC.HsToCore.Pmc.Desugar
    
    46 47
     import GHC.HsToCore.Pmc.Check
    
    47 48
     import GHC.HsToCore.Pmc.Solver
    
    49
    +import GHC.HsToCore.Types
    
    48 50
     import GHC.Types.Basic (Origin(..), isDoExpansionGenerated)
    
    49 51
     import GHC.Core
    
    50 52
     import GHC.Driver.DynFlags
    
    ... ... @@ -77,26 +79,35 @@ import GHC.Tc.Utils.Monad
    77 79
     -- capturing long-distance information, or the trivially habitable 'Nablas' if
    
    78 80
     -- the former is uninhabited.
    
    79 81
     -- See Note [Recovering from unsatisfiable pattern-matching constraints].
    
    80
    -getLdiNablas :: DsM Nablas
    
    82
    +getLdiNablas :: DsM LdiNablas
    
    81 83
     getLdiNablas = do
    
    82 84
       nablas <- getPmNablas
    
    83
    -  isInhabited nablas >>= \case
    
    84
    -    True  -> pure nablas
    
    85
    -    False -> pure initNablas
    
    85
    +  case nablas of
    
    86
    +    NoPmc      -> pure NoPmc
    
    87
    +    Ldi nablas -> isInhabited nablas >>= \case
    
    88
    +                     True  -> pure (Ldi nablas)
    
    89
    +                     False -> pure (Ldi initNablas)
    
    86 90
     
    
    87 91
     -- | We need to call the Hs desugarer to get the Core of a let-binding or where
    
    88 92
     -- clause. We don't want to run the coverage checker when doing so! Efficiency
    
    89 93
     -- is one concern, but also a lack of properly set up long-distance information
    
    90 94
     -- might trigger warnings that we normally wouldn't emit.
    
    91
    -noCheckDs :: DsM a -> DsM a
    
    92
    -noCheckDs = updTopFlags (\dflags -> foldl' wopt_unset dflags allPmCheckWarnings)
    
    95
    +dontDoPmc :: DsM a -> DsM a
    
    96
    +dontDoPmc thing_inside = updPmNablas NoPmc thing_inside
    
    97
    +
    
    98
    +whenDoingPmc :: a -> (Nablas -> DsM a) -> DsM a
    
    99
    +whenDoingPmc no_pmc thing_inside
    
    100
    +  = do { ldi_nablas <- getPmNablas
    
    101
    +       ; case ldi_nablas of
    
    102
    +            NoPmc      -> return no_pmc
    
    103
    +            Ldi nablas -> thing_inside nablas }
    
    93 104
     
    
    94 105
     -- | Check a pattern binding (let, where) for exhaustiveness.
    
    95
    -pmcPatBind :: DsMatchContext -> Id -> Pat GhcTc -> DsM Nablas
    
    106
    +pmcPatBind :: DsMatchContext -> Id -> Pat GhcTc -> DsM LdiNablas
    
    96 107
     pmcPatBind ctxt@(DsMatchContext match_ctxt loc) var p
    
    97
    -  = mb_discard_warnings $ do
    
    98
    -      !missing <- getLdiNablas
    
    99
    -      pat_bind <- noCheckDs $ desugarPatBind loc var p
    
    108
    +  = whenDoingPmc NoPmc $ \ !missing ->
    
    109
    +    mb_discard_warnings $ do
    
    110
    +      pat_bind <- dontDoPmc $ desugarPatBind loc var p
    
    100 111
           tracePm "pmcPatBind {" (vcat [ppr ctxt, ppr var, ppr p, ppr pat_bind, ppr missing])
    
    101 112
           result <- unCA (checkPatBind pat_bind) missing
    
    102 113
           let ldi = ldiGRHS $ ( \ pb -> case pb of PmPatBind grhs -> grhs) $ cr_ret result
    
    ... ... @@ -124,21 +135,21 @@ pmcPatBind ctxt@(DsMatchContext match_ctxt loc) var p
    124 135
     pmcGRHSs
    
    125 136
       :: HsMatchContextRn             -- ^ Match context, for warning messages
    
    126 137
       -> GRHSs GhcTc (LHsExpr GhcTc)  -- ^ The GRHSs to check
    
    127
    -  -> DsM (NonEmpty Nablas)        -- ^ Covered 'Nablas' for each RHS, for long
    
    128
    -                                  --   distance info
    
    129
    -pmcGRHSs hs_ctxt guards@(GRHSs _ grhss _) = do
    
    130
    -  let combined_loc = foldl1 combineSrcSpans (NE.map getLocA grhss)
    
    131
    -      ctxt = DsMatchContext hs_ctxt combined_loc
    
    132
    -  !missing <- getLdiNablas
    
    133
    -  matches  <- noCheckDs $ desugarGRHSs combined_loc empty guards
    
    134
    -  tracePm "pmcGRHSs" (hang (vcat [ppr ctxt
    
    135
    -                                , text "Guards:"])
    
    136
    -                                2
    
    137
    -                                (pprGRHSs hs_ctxt guards $$ ppr missing))
    
    138
    -  result <- unCA (checkGRHSs matches) missing
    
    139
    -  tracePm "}: " (ppr (cr_uncov result))
    
    140
    -  formatReportWarnings ReportGRHSs ctxt [] result
    
    141
    -  return (ldiGRHSs (cr_ret result))
    
    138
    +  -> DsM (NonEmpty LdiNablas)     -- ^ Covered 'Nablas' for each RHS,
    
    139
    +                                  --   for long distance info
    
    140
    +pmcGRHSs hs_ctxt guards@(GRHSs _ grhss _) =
    
    141
    +  whenDoingPmc (NE.map (const NoPmc) grhss) $ \ !missing -> do
    
    142
    +    let combined_loc = foldl1 combineSrcSpans (NE.map getLocA grhss)
    
    143
    +        ctxt = DsMatchContext hs_ctxt combined_loc
    
    144
    +    matches  <- dontDoPmc $ desugarGRHSs combined_loc empty guards
    
    145
    +    tracePm "pmcGRHSs" (hang (vcat [ppr ctxt
    
    146
    +                                  , text "Guards:"])
    
    147
    +                                  2
    
    148
    +                                  (pprGRHSs hs_ctxt guards $$ ppr missing))
    
    149
    +    result <- unCA (checkGRHSs matches) missing
    
    150
    +    tracePm "}: " (ppr (cr_uncov result))
    
    151
    +    formatReportWarnings ReportGRHSs ctxt [] result
    
    152
    +    return (ldiGRHSs (cr_ret result))
    
    142 153
     
    
    143 154
     -- | Check a list of syntactic 'Match'es (part of case, functions, etc.), each
    
    144 155
     -- with a 'Pat' and one or more 'GRHSs':
    
    ... ... @@ -160,37 +171,44 @@ pmcMatches
    160 171
       -> DsMatchContext                  -- ^ Match context, for warnings messages
    
    161 172
       -> [Id]                            -- ^ Match variables, i.e. x and y above
    
    162 173
       -> [LMatch GhcTc (LHsExpr GhcTc)]  -- ^ List of matches
    
    163
    -  -> DsM [(Nablas, NonEmpty Nablas)] -- ^ One covered 'Nablas' per Match and
    
    164
    -                                     --   GRHS, for long distance info.
    
    165
    -pmcMatches origin ctxt vars matches = {-# SCC "pmcMatches" #-} do
    
    166
    -  -- We have to force @missing@ before printing out the trace message,
    
    167
    -  -- otherwise we get interleaved output from the solver. This function
    
    168
    -  -- should be strict in @missing@ anyway!
    
    169
    -  !missing <- getLdiNablas
    
    170
    -  tracePm "pmcMatches {" $
    
    171
    -          hang (vcat [ppr origin, ppr ctxt, ppr vars, text "Matches:"])
    
    172
    -               2
    
    173
    -               ((ppr matches) $$ (text "missing:" <+> ppr missing))
    
    174
    -  case NE.nonEmpty matches of
    
    175
    -    Nothing -> do
    
    176
    -      -- This must be an -XEmptyCase. See Note [Checking EmptyCase]
    
    177
    -      let var = only vars
    
    178
    -      empty_case <- noCheckDs $ desugarEmptyCase var
    
    179
    -      result <- unCA (checkEmptyCase empty_case) missing
    
    180
    -      tracePm "}: " (ppr (cr_uncov result))
    
    181
    -      formatReportWarnings ReportEmptyCase ctxt vars result
    
    182
    -      return []
    
    183
    -    Just matches -> do
    
    184
    -      matches <- {-# SCC "desugarMatches" #-}
    
    185
    -                 noCheckDs $ desugarMatches vars matches
    
    186
    -      tracePm "desugared matches" (ppr matches)
    
    187
    -      result  <- {-# SCC "checkMatchGroup" #-}
    
    188
    -                 unCA (checkMatchGroup matches) missing
    
    189
    -      tracePm "}: " (ppr (cr_uncov result))
    
    190
    -      unless (isDoExpansionGenerated origin) -- Do expansion generated code shouldn't emit overlapping warnings
    
    191
    -        ({-# SCC "formatReportWarnings" #-}
    
    192
    -        formatReportWarnings ReportMatchGroup ctxt vars result)
    
    193
    -      return (NE.toList (ldiMatchGroup (cr_ret result)))
    
    174
    +  -> DsM [(LdiNablas, NonEmpty LdiNablas)] -- ^ One covered 'Nablas' per Match and
    
    175
    +                                           --   GRHS, for long distance info.
    
    176
    +pmcMatches origin ctxt vars matches = {-# SCC "pmcMatches" #-}
    
    177
    +  whenDoingPmc (initNablasMatches NoPmc matches) $ \ !missing -> do
    
    178
    +      -- We have to force @missing@ before printing out the trace message,
    
    179
    +      -- otherwise we get interleaved output from the solver. This function
    
    180
    +      -- should be strict in @missing@ anyway!
    
    181
    +    tracePm "pmcMatches {" $
    
    182
    +            hang (vcat [ppr origin, ppr ctxt, ppr vars, text "Matches:"])
    
    183
    +                 2
    
    184
    +                 ((ppr matches) $$ (text "missing:" <+> ppr missing))
    
    185
    +    case NE.nonEmpty matches of
    
    186
    +      Nothing -> do
    
    187
    +        -- This must be an -XEmptyCase. See Note [Checking EmptyCase]
    
    188
    +        let var = only vars
    
    189
    +        empty_case <- dontDoPmc $ desugarEmptyCase var
    
    190
    +        result <- unCA (checkEmptyCase empty_case) missing
    
    191
    +        tracePm "}: " (ppr (cr_uncov result))
    
    192
    +        formatReportWarnings ReportEmptyCase ctxt vars result
    
    193
    +        return []
    
    194
    +      Just matches -> do
    
    195
    +        matches <- {-# SCC "desugarMatches" #-}
    
    196
    +                   dontDoPmc $ desugarMatches vars matches
    
    197
    +        tracePm "desugared matches" (ppr matches)
    
    198
    +        result  <- {-# SCC "checkMatchGroup" #-}
    
    199
    +                   unCA (checkMatchGroup matches) missing
    
    200
    +        tracePm "}: " (ppr (cr_uncov result))
    
    201
    +        unless (isDoExpansionGenerated origin) -- Do expansion generated code shouldn't emit overlapping warnings
    
    202
    +          ({-# SCC "formatReportWarnings" #-}
    
    203
    +          formatReportWarnings ReportMatchGroup ctxt vars result)
    
    204
    +        return (NE.toList (ldiMatchGroup (cr_ret result)))
    
    205
    +
    
    206
    +initNablasMatches :: LdiNablas -> [LMatch GhcTc b] -> [(LdiNablas, NonEmpty LdiNablas)]
    
    207
    +initNablasMatches ldi_nablas ms
    
    208
    +  = map (\(L _ m) -> (ldi_nablas, initNablasGRHSs ldi_nablas (m_grhss m))) ms
    
    209
    +  where
    
    210
    +    initNablasGRHSs :: LdiNablas -> GRHSs GhcTc b -> NonEmpty LdiNablas
    
    211
    +    initNablasGRHSs ldi_nablas m = NE.map (const ldi_nablas) (grhssGRHSs m)
    
    194 212
     
    
    195 213
     {-
    
    196 214
     Note [Detecting incomplete record selectors]
    
    ... ... @@ -361,9 +379,8 @@ pmcRecSel sel_id arg
    361 379
       | RecSelId{ sel_cons = rec_sel_info } <- idDetails sel_id
    
    362 380
       , RSI { rsi_def = cons_w_field, rsi_undef = cons_wo_field } <- rec_sel_info
    
    363 381
       , not (null cons_wo_field)
    
    364
    -  = do { !missing <- getLdiNablas
    
    365
    -
    
    366
    -       ; tracePm "pmcRecSel {" (ppr sel_id)
    
    382
    +  = whenDoingPmc () $ \ !missing ->
    
    383
    +    do { tracePm "pmcRecSel {" (ppr sel_id)
    
    367 384
            ; CheckResult{ cr_ret = PmRecSel{ pr_arg_var = arg_id }, cr_uncov = uncov_nablas }
    
    368 385
                <- unCA (checkRecSel (PmRecSel () arg cons_w_field)) missing
    
    369 386
            ; tracePm "}: " $ ppr uncov_nablas
    
    ... ... @@ -415,18 +432,18 @@ discardWarningsDs.
    415 432
     -- * Collecting long-distance information
    
    416 433
     --
    
    417 434
     
    
    418
    -ldiMatchGroup :: PmMatchGroup Post -> NonEmpty (Nablas, NonEmpty Nablas)
    
    435
    +ldiMatchGroup :: PmMatchGroup Post -> NonEmpty (LdiNablas, NonEmpty LdiNablas)
    
    419 436
     ldiMatchGroup (PmMatchGroup matches) = ldiMatch <$> matches
    
    420 437
     
    
    421
    -ldiMatch :: PmMatch Post -> (Nablas, NonEmpty Nablas)
    
    438
    +ldiMatch :: PmMatch Post -> (LdiNablas, NonEmpty LdiNablas)
    
    422 439
     ldiMatch (PmMatch { pm_pats = red, pm_grhss = grhss }) =
    
    423
    -  (rs_cov red, ldiGRHSs grhss)
    
    440
    +  (Ldi (rs_cov red), ldiGRHSs grhss)
    
    424 441
     
    
    425
    -ldiGRHSs :: PmGRHSs Post -> NonEmpty Nablas
    
    442
    +ldiGRHSs :: PmGRHSs Post -> NonEmpty LdiNablas
    
    426 443
     ldiGRHSs (PmGRHSs { pgs_grhss = grhss }) = ldiGRHS <$> grhss
    
    427 444
     
    
    428
    -ldiGRHS :: PmGRHS Post -> Nablas
    
    429
    -ldiGRHS (PmGRHS { pg_grds = red }) = rs_cov red
    
    445
    +ldiGRHS :: PmGRHS Post -> LdiNablas
    
    446
    +ldiGRHS (PmGRHS { pg_grds = red }) = Ldi (rs_cov red)
    
    430 447
     
    
    431 448
     --
    
    432 449
     -- * Collecting redundancy information
    
    ... ... @@ -620,9 +637,11 @@ getNFirstUncovered mode vars n (MkNablas nablas) = go n (bagToList nablas)
    620 637
     -- with 'unsafeInterleaveM' in order not to do unnecessary work.
    
    621 638
     locallyExtendPmNablas :: DsM a -> (Nablas -> DsM Nablas) -> DsM a
    
    622 639
     locallyExtendPmNablas k ext = do
    
    623
    -  nablas <- getLdiNablas
    
    624
    -  nablas' <- unsafeInterleaveM $ ext nablas
    
    625
    -  updPmNablas nablas' k
    
    640
    +  ldi_nablas <- getLdiNablas
    
    641
    +  case ldi_nablas of
    
    642
    +     NoPmc      -> k  -- No nablas to extend, easy!
    
    643
    +     Ldi nablas -> do { nablas' <- unsafeInterleaveM $ ext nablas
    
    644
    +                      ; updPmNablas (Ldi nablas') k }
    
    626 645
     
    
    627 646
     -- | Add in-scope type constraints if the coverage checker might run and then
    
    628 647
     -- run the given action.
    
    ... ... @@ -670,18 +689,40 @@ Consider
    670 689
     
    
    671 690
     Humans can make the "long-distance connection" between the outer pattern match
    
    672 691
     and the nested case pattern match to see that the inner pattern match is
    
    673
    -exhaustive: @c@ can't be @R@ anymore because it was matched in the first clause
    
    674
    -of @f@.
    
    675
    -
    
    676
    -To achieve similar reasoning in the coverage checker, we keep track of the set
    
    677
    -of values that can reach a particular program point (often loosely referred to
    
    678
    -as "Covered set") in 'GHC.HsToCore.Monad.dsl_nablas'.
    
    679
    -We fill that set with Covered Nablas returned by the exported checking
    
    680
    -functions, which the call sites put into place with
    
    681
    -'GHC.HsToCore.Monad.updPmNablas'.
    
    682
    -Call sites also extend this set with facts from type-constraint dictionaries,
    
    683
    -case scrutinees, etc. with the exported functions 'addTyCs', 'addCoreScrutTmCs'
    
    684
    -and 'addHsScrutTmCs'.
    
    692
    +exhaustive: `c` can't be `R` anymore because it was matched in the first clause
    
    693
    +of `f`.
    
    694
    +
    
    695
    +To achieve similar reasoning in the coverage checker:
    
    696
    +
    
    697
    +* We keep track of the set of values that can reach a particular program point
    
    698
    +  (often loosely refer red to as "Covered set") in 'GHC.HsToCore.Monad.dsl_nablas
    
    699
    +  :: LdiNablas'.
    
    700
    +
    
    701
    +* We fill that set with Covered Nablas returned by the exported checking functions,
    
    702
    +  which the call sites put into place with 'GHC.HsToCore.Monad.updPmNablas'.
    
    703
    +
    
    704
    +* Call sites also extend this set with facts from type-constraint dictionaries,
    
    705
    +  case scrutinees, etc. with the exported functions 'addTyCs', 'addCoreScrutTmCs'
    
    706
    +  and 'addHsScrutTmCs'.
    
    707
    +
    
    708
    +Wrinkles:
    
    709
    +
    
    710
    +(LDI1) During patterm-match checking, we need to make an auxiliary call the Hs
    
    711
    +  desugarer to get the Core of a let-binding or where-clause. We don't want to run
    
    712
    +  the coverage checker when doing so! Efficiency is one concern, but also a lack of
    
    713
    +  properly set up long-distance information might trigger warnings that we normally
    
    714
    +  wouldn't emit.
    
    715
    +
    
    716
    +  So `dsl_nablas :: LdiNablas` where
    
    717
    +     data LdiNablas = NoPmc | Ldi Nablas
    
    718
    +
    
    719
    +  If dsl_nablas = NoPmc, that means we are in one of these auxiliary calls; so
    
    720
    +  we want to do no pattern-match checking whatsoever.  We won't need to carry
    
    721
    +  any long-distance info around; we are simply degsugaring to Core.
    
    722
    +
    
    723
    +  If dsl_nablas = Ldi nablas, then we do want to do pattern-match checking,
    
    724
    +  and the long-distance context is given by `nablas`
    
    725
    +
    
    685 726
     
    
    686 727
     Note [Recovering from unsatisfiable pattern-matching constraints]
    
    687 728
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/HsToCore/Types.hs
    ... ... @@ -7,7 +7,7 @@
    7 7
     
    
    8 8
     -- | Various types used during desugaring.
    
    9 9
     module GHC.HsToCore.Types (
    
    10
    -        DsM, DsLclEnv(..), DsGblEnv(..),
    
    10
    +        DsM, DsLclEnv(..), DsGblEnv(..), LdiNablas(..),
    
    11 11
             DsMetaEnv, DsMetaVal(..), CompleteMatches
    
    12 12
         ) where
    
    13 13
     
    
    ... ... @@ -85,13 +85,23 @@ data DsGblEnv
    85 85
     instance ContainsModule DsGblEnv where
    
    86 86
       extractModule = ds_mod
    
    87 87
     
    
    88
    +data LdiNablas
    
    89
    +  = NoPmc        -- Do desugaring only, no pattern-match checking
    
    90
    +                 --   See (LDI1) in Note [Long-distance information]
    
    91
    +  | Ldi Nablas   -- Do pattern match checking; here are "reaching values" Nablas
    
    92
    +
    
    93
    +instance Outputable LdiNablas where
    
    94
    +  ppr NoPmc    = text "NoPmc"
    
    95
    +  ppr (Ldi ns) = text "Ldi" <> braces (ppr ns)
    
    96
    +
    
    88 97
     -- | Local state of the desugarer, extended as we lexically descend
    
    89 98
     data DsLclEnv
    
    90 99
       = DsLclEnv
    
    91 100
       { dsl_meta    :: DsMetaEnv   -- ^ Template Haskell bindings
    
    92 101
       , dsl_loc     :: RealSrcSpan -- ^ To put in pattern-matching error msgs
    
    93
    -  , dsl_nablas  :: Nablas
    
    94
    -  -- ^ See Note [Long-distance information] in "GHC.HsToCore.Pmc".
    
    102
    +
    
    103
    +  , dsl_nablas  :: LdiNablas
    
    104
    +  -- ^ See Note [Long-distance information] in "GHC.HsToCore.Pmc", esp (LDI1)
    
    95 105
       -- The set of reaching values Nablas is augmented as we walk inwards, refined
    
    96 106
       -- through each pattern match in turn
    
    97 107
     
    

  • compiler/GHC/Tc/Gen/Bind.hs
    ... ... @@ -1874,9 +1874,9 @@ isClosedBndrGroup type_env binds
    1874 1874
     
    
    1875 1875
           | otherwise
    
    1876 1876
           = True   -- The free-var set for a top level binding mentions
    
    1877
    -               -- * imported things so that we can report unused imports
    
    1878
    -               -- * class method etc from the current module
    
    1879
    -               -- * the Ids from the current Rec group
    
    1877
    +               --  - imported things so that we can report unused imports
    
    1878
    +               --  - class method etc from the current module
    
    1879
    +               --  - the Ids from the current Rec group
    
    1880 1880
                    -- None of these will be in the type envt
    
    1881 1881
     
    
    1882 1882
     lHsBindFreeVars :: LHsBind GhcRn -> NameSet
    

  • compiler/GHC/Tc/Utils/Env.hs
    ... ... @@ -117,7 +117,7 @@ import GHC.Utils.Misc ( HasDebugCallStack )
    117 117
     
    
    118 118
     import GHC.Data.FastString
    
    119 119
     import GHC.Data.List.SetOps
    
    120
    -import GHC.Data.Maybe( MaybeErr(..), maybeToList, fromMaybe, isNothing )
    
    120
    +import GHC.Data.Maybe( MaybeErr(..), maybeToList, fromMaybe )
    
    121 121
     
    
    122 122
     import GHC.Types.SrcLoc
    
    123 123
     import GHC.Types.Basic hiding( SuccessFlag(..) )