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

Commits:

15 changed files:

Changes:

  • changelog.d/T27844
    1
    +section: compiler
    
    2
    +issues: #27844
    
    3
    +mrs: !16723
    
    4
    +synopsis:
    
    5
    +  Reinstate a missing occurs check in the constraint solver
    
    6
    +description:
    
    7
    +  Simplifies code in GHC's type-constraint solver, thereby fixing an outright
    
    8
    +  compiler loop (via a missing occurs check).
    
    9
    +

  • compiler/GHC/Runtime/Heap/Inspect.hs
    ... ... @@ -630,7 +630,7 @@ be sigmas and not taus.
    630 630
     ~~~~~~~~~~~~~~~~~~~~~~
    
    631 631
     In the GHCi debugger we use unification variables whose MetaInfo is
    
    632 632
     RuntimeUnkTv.  The special property of a RuntimeUnkTv is that it can
    
    633
    -unify with a polytype (see GHC.Tc.Utils.Unify.checkTypeEq).
    
    633
    +unify with a polytype (see GHC.Tc.Solver.Equality.checkTypeEqNoUnification).
    
    634 634
     If we don't do this `:print <term>` will fail if the type of <term>
    
    635 635
     has nested `forall`s or `=>`s.
    
    636 636
     
    

  • compiler/GHC/Tc/Solver/Equality.hs
    ... ... @@ -21,6 +21,7 @@ import GHC.Tc.Types.Evidence
    21 21
     import GHC.Tc.Types.Constraint
    
    22 22
     import GHC.Tc.Types.CtLoc
    
    23 23
     import GHC.Tc.Types.Origin
    
    24
    +import GHC.Tc.Types( TcM )
    
    24 25
     import GHC.Tc.Utils.Unify
    
    25 26
     import GHC.Tc.Utils.TcType
    
    26 27
     import GHC.Tc.Instance.Family ( tcUnwrapNewtype_maybe )
    
    ... ... @@ -36,8 +37,8 @@ import GHC.Core.Coercion
    36 37
     import GHC.Core.Reduction
    
    37 38
     import GHC.Core.FamInstEnv ( FamInstEnvs )
    
    38 39
     import GHC.Core
    
    39
    -import GHC.Types.Var
    
    40 40
     
    
    41
    +import GHC.Types.Var
    
    41 42
     import GHC.Types.Basic
    
    42 43
     import GHC.Types.Name.Reader
    
    43 44
     import GHC.Types.Var.Env
    
    ... ... @@ -49,6 +50,8 @@ import GHC.Utils.Misc
    49 50
     import GHC.Utils.Monad
    
    50 51
     
    
    51 52
     import GHC.Data.Pair
    
    53
    +import GHC.Data.Bag
    
    54
    +
    
    52 55
     import Control.Monad
    
    53 56
     import Data.Maybe ( isJust, isNothing )
    
    54 57
     import Data.List  ( zip4 )
    
    ... ... @@ -406,11 +409,13 @@ canonicaliseEquality
    406 409
     --   hold.
    
    407 410
     
    
    408 411
     canonicaliseEquality ev eq_rel ty1 ty2
    
    409
    -  = Stage $ do { traceTcS "canonicaliseEquality" $
    
    412
    +  = Stage $ do { traceTcS "canonicaliseEquality {" $
    
    410 413
                      vcat [ ppr ev, ppr eq_rel, ppr ty1, ppr ty2 ]
    
    411 414
                    ; rdr_env   <- getGlobalRdrEnvTcS
    
    412 415
                    ; fam_insts <- getFamInstEnvs
    
    413
    -               ; can_eq_nc initCanEqState rdr_env fam_insts ev eq_rel ty1 ty1 ty2 ty2 }
    
    416
    +               ; res <- can_eq_nc initCanEqState rdr_env fam_insts ev eq_rel ty1 ty1 ty2 ty2
    
    417
    +               ; traceTcS "canonicaliseEquality }" (ppr res)
    
    418
    +               ; return res }
    
    414 419
     
    
    415 420
     -- | Main worker function for 'canonicaliseEquality'.
    
    416 421
     --
    
    ... ... @@ -1822,7 +1827,7 @@ Ticket #10009, a very nasty example:
    1822 1827
         g :: forall a. (UnF (F a) ~ a) => a -> ()
    
    1823 1828
         g _ = f (undefined :: F a)
    
    1824 1829
     
    
    1825
    -For g we get [G]  g1 : UnF (F a) ~ a
    
    1830
    +For g we get [G] g1 : UnF (F a) ~ a
    
    1826 1831
                  [W] w1 : UnF (F beta) ~ beta
    
    1827 1832
                  [W] w2 : F a ~ F beta
    
    1828 1833
     
    
    ... ... @@ -2205,63 +2210,45 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs
    2205 2210
       , TyVarLHS lhs_tv <- lhs
    
    2206 2211
       = do  { given_eq_lvl <- getInnermostGivenEqLevel
    
    2207 2212
             ; case simpleUnifyCheck UC_Solver given_eq_lvl lhs_tv rhs of
    
    2208
    -            SUC_CanUnify ->
    
    2209
    -              unify lhs_tv (mkReflRedn Nominal rhs)
    
    2210
    -            SUC_CannotUnify
    
    2211
    -              | Just can_rhs <- canTyFamEqLHS_maybe rhs
    
    2212
    -              -> swap_and_finish lhs_tv can_rhs -- See Note [Orienting TyVarLHS/TyFamLHS]
    
    2213
    -              | otherwise
    
    2214
    -              -> finish_no_unify
    
    2215
    -            SUC_NotSure ->
    
    2213
    +            SUC_CannotUnify -> finish_no_unify
    
    2214
    +            SUC_CanUnify    -> do_unification lhs_tv (mkReflRedn Nominal rhs)
    
    2215
    +            SUC_NotSure     ->
    
    2216 2216
                   -- We have a touchable unification variable on the left,
    
    2217 2217
                   -- and the top-shape check succeeded. These are both guaranteed
    
    2218 2218
                   -- by the fact that simpleUnifyCheck did not return SUC_CannotUnify.
    
    2219
    +              --
    
    2220
    +              -- Next, do a fully `checkTyEqRhs` check to see if we can unify
    
    2221
    +              -- See Note [checkTyEqRhs] in GHC.Tc.Utils.Unify
    
    2219 2222
                   do  { let flags = unifyingLHSMetaTyVar_TEFTask ev lhs_tv
    
    2220 2223
                       ; check_result <- wrapTcS (checkTyEqRhs flags rhs)
    
    2224
    +                  ; traceTcS "canEqCanLHSFinish_try_unification" $
    
    2225
    +                    vcat [ text "lhs" <+> ppr lhs
    
    2226
    +                         , text "rhs" <+> ppr rhs
    
    2227
    +                         , text "check_result" <+> ppr check_result ]
    
    2221 2228
                       ; case check_result of
    
    2222
    -                      PuOK cts rhs_redn ->
    
    2223
    -                        do { emitWork cts
    
    2224
    -                           ; unify lhs_tv rhs_redn }
    
    2225
    -                      PuFail reason
    
    2226
    -                        | Just can_rhs <- canTyFamEqLHS_maybe rhs
    
    2227
    -                        -> swap_and_finish lhs_tv can_rhs -- See Note [Orienting TyVarLHS/TyFamLHS]
    
    2228
    -                        | reason `cterHasOnlyProblems` do_not_prevent_rewriting
    
    2229
    -                        ->
    
    2230
    -                          -- ContinueWith, to allow using this constraint for
    
    2231
    -                          -- rewriting (e.g. alpha[2] ~ beta[3]).
    
    2232
    -                          do { new_ev <- rewriteEqEvidenceSwapOnly ev eq_rel swapped lhs rhs
    
    2233
    -                             ; continueWith $ Right $
    
    2234
    -                                 EqCt { eq_ev  = new_ev, eq_eq_rel = eq_rel
    
    2235
    -                                      , eq_lhs = lhs , eq_rhs = rhs }
    
    2236
    -                             }
    
    2237
    -                        | otherwise
    
    2238
    -                        -> try_irred reason
    
    2239
    -                  }
    
    2229
    +                      PuFail {}         -> finish_no_unify
    
    2230
    +                      PuOK cts rhs_redn -> do { emitWork cts
    
    2231
    +                                              ; do_unification lhs_tv rhs_redn } }
    
    2240 2232
              }
    
    2241 2233
       -- Otherwise unification is off the table
    
    2242 2234
       | otherwise
    
    2243 2235
       = finish_no_unify
    
    2244 2236
     
    
    2245 2237
       where
    
    2246
    -    -- We can't unify, but this equality can go in the inert set
    
    2247
    -    -- and be used to rewrite other constraints.
    
    2248
    -    finish_no_unify =
    
    2249
    -      canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs
    
    2250
    -
    
    2251
    -    -- We can't unify, and this equality should not be used to rewrite
    
    2252
    -    -- other constraints (e.g. because it has an occurs check).
    
    2253
    -    -- So add it to the inert Irreds.
    
    2254
    -    try_irred reason =
    
    2255
    -      tryIrredInstead reason ev eq_rel swapped lhs rhs
    
    2256
    -
    
    2257
    -    -- We can't unify as-is, and want to flip the equality around.
    
    2258
    -    -- Example: alpha ~ F tys, flip it around to become the canonical
    
    2259
    -    -- equality f tys ~ alpha.
    
    2260
    -    swap_and_finish tv can_rhs =
    
    2261
    -      swapAndFinish ev eq_rel swapped (mkTyVarTy tv) can_rhs
    
    2262
    -
    
    2263
    -    -- Phew! Finally!  We can unify; go ahead and do so.
    
    2264
    -    unify tv rhs_redn =
    
    2238
    +    -- finish_no_unify: abandon the attempt to unify, and instead hand off to
    
    2239
    +    -- canEqCanLHSFinish_no_unification
    
    2240
    +    -- First, though, if we have (tv ~ F tys)
    
    2241
    +    --        swap it over so we get (F tys ~ tv), with `F tys` on the LHS
    
    2242
    +    -- See Note [Orienting TyVarLHS/TyFamLHS]
    
    2243
    +    finish_no_unify
    
    2244
    +      | TyVarLHS lhs_tv <- lhs
    
    2245
    +      , Just can_rhs <- canTyFamEqLHS_maybe rhs
    
    2246
    +      = canEqCanLHSFinish_no_unification ev eq_rel (flipSwap swapped) can_rhs (mkTyVarTy lhs_tv)
    
    2247
    +      | otherwise
    
    2248
    +      = canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs
    
    2249
    +
    
    2250
    +    -- do_unification: Phew! Finally!  We can unify; go ahead and do so.
    
    2251
    +    do_unification tv rhs_redn =
    
    2265 2252
           do { -- In the common case where rhs_redn is Refl, we don't need to rewrite
    
    2266 2253
                -- the evidence, even if swapped=IsSwapped.   Suppose the original was
    
    2267 2254
                --     [W] co : Int ~ alpha
    
    ... ... @@ -2273,7 +2260,8 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs
    2273 2260
                          else rewriteEqEvidence ev swapped
    
    2274 2261
                                   (mkReflRedn Nominal (mkTyVarTy tv)) rhs_redn
    
    2275 2262
                                   emptyCoHoleSet
    
    2276
    -                              -- emptyCoHoleSet: rhs_redn has no CoercionHoles
    
    2263
    +                              -- emptyCoHoleSet: we are about to /solve/ this
    
    2264
    +                              -- constraint, so its CoHoleSet doesn't matter
    
    2277 2265
     
    
    2278 2266
              ; let tv_ty     = mkTyVarTy tv
    
    2279 2267
                    final_rhs = reductionReducedType rhs_redn
    
    ... ... @@ -2297,45 +2285,44 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs
    2297 2285
              ; return (Stop new_ev (text "Solved by unification")) }
    
    2298 2286
     
    
    2299 2287
     ---------------------------
    
    2300
    --- Unification is off the table
    
    2301 2288
     canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs
    
    2302
    -  = do { -- Do checkTypeEq to guarantee (TyEq:OC), (TyEq:F)
    
    2289
    +  -- We can't unify, but we can see if this equality can go in the inert set
    
    2290
    +  -- and be used to rewrite other constraints.
    
    2291
    +  -- See Note [Equalities where unification fails]
    
    2292
    +  = do { -- Do checkTypeEqNoUnfication to guarantee (TyEq:OC), (TyEq:F)
    
    2303 2293
              -- Must do the occurs check even on tyvar/tyvar equalities,
    
    2304 2294
              -- in case have  x ~ (y :: ..x...); this is #12593.
    
    2305
    -       ; check_result <- checkTypeEq ev eq_rel lhs rhs
    
    2306
    -
    
    2307
    -       ; let lhs_ty = canEqLHSType lhs
    
    2295
    +       ; check_result <- checkTypeEqNoUnification ev eq_rel lhs rhs
    
    2308 2296
            ; case check_result of
    
    2309 2297
                 PuFail reason
    
    2310
    -
    
    2311
    -              -- If we had F a ~ G (F a), which gives an occurs check,
    
    2312
    -              -- then swap it to G (F a) ~ F a, which does not
    
    2313
    -              -- However `swap_for_size` above will orient it with (G (F a)) on
    
    2314
    -              -- the left anwyway.  `swap_for_rewriting` "wins", but that doesn't
    
    2315
    -              -- matter: in the occurs check case swap_for_rewriting will be moot.
    
    2316
    -              -- TL;DR: the next four lines of code are redundant
    
    2317
    -              -- I'm leaving them here in case they become relevant again
    
    2318
    ---              | TyFamLHS {} <- lhs
    
    2319
    ---              , Just can_rhs <- canTyFamEqLHS_maybe rhs
    
    2320
    ---              , reason `cterHasOnlyProblem` cteSolubleOccurs
    
    2321
    ---              -> swapAndFinish ev eq_rel swapped lhs_ty can_rhs
    
    2322
    ---              | otherwise
    
    2323
    -
    
    2324
    -              | reason `cterHasOnlyProblems` do_not_prevent_rewriting
    
    2325
    -              -> do { new_ev <- rewriteEqEvidenceSwapOnly ev eq_rel swapped lhs rhs
    
    2326
    -                    ; continueWith $ Right $
    
    2327
    -                        EqCt { eq_ev  = new_ev, eq_eq_rel = eq_rel
    
    2328
    -                             , eq_lhs = lhs , eq_rhs = rhs }
    
    2329
    -                    }
    
    2330
    -
    
    2331
    -              | otherwise
    
    2332
    -              -> tryIrredInstead reason ev eq_rel swapped lhs rhs
    
    2298
    +              -> -- We can't unify, and this equality should not be used to rewrite
    
    2299
    +                 -- other constraints (e.g. because it has an occurs check).
    
    2300
    +                 -- So add it to the inert Irreds.
    
    2301
    +                 do { new_ev <- rewriteEqEvidenceSwapOnly ev eq_rel swapped lhs rhs
    
    2302
    +                    ; finishCanWithIrred (NonCanonicalReason reason) new_ev }
    
    2333 2303
     
    
    2334 2304
                 PuOK new_eqs rhs_redn
    
    2335
    -              -> do { emitWork new_eqs
    
    2336
    -                    ; let new_holes = rewriterSetFromCts new_eqs
    
    2305
    +              -> -- Put this constraint into the inert set, so that it will be used
    
    2306
    +                 -- to solve or rewrite other constraints.
    
    2307
    +                 --
    
    2308
    +                 -- NB: checkTypeEqNoUnification does not check for
    
    2309
    +                 --     (b) skolem-escape (tefTyVar_levelCheck = LC_None)
    
    2310
    +                 --     (a) concreteness  (tefTyVar_concreteCheck = CC_None)
    
    2311
    +                 --   So an equality whose only problem is e.g. skolem-escape will
    
    2312
    +                 --   return PuOK, will be put in the inert set, will be used for
    
    2313
    +                 --   rewriting. That is fine.
    
    2314
    +                 --
    
    2315
    +                 -- assertPpr (isEmptyCts new_eqs):
    
    2316
    +                 --   checkTypeEqNoUnification does neither promotion nor type-family
    
    2317
    +                 --   flattening for Wanteds, and hence creates no equalities to solve
    
    2318
    +                 assertPpr (isEmptyCts new_eqs)
    
    2319
    +                    (vcat [ text "new_eqs"  <+> ppr new_eqs
    
    2320
    +                          , text "rhs_redn" <+> ppr rhs_redn
    
    2321
    +                          , text "lhs"      <+> ppr lhs
    
    2322
    +                          , text "rhs"      <+> ppr rhs ]) $
    
    2323
    +                 do { let lhs_ty    = canEqLHSType lhs
    
    2337 2324
                               lhs_redn  = mkReflRedn (eqRelRole eq_rel) lhs_ty
    
    2338
    -                    ; new_ev <- rewriteEqEvidence ev swapped lhs_redn rhs_redn new_holes
    
    2325
    +                    ; new_ev <- rewriteEqEvidence ev swapped lhs_redn rhs_redn emptyCoHoleSet
    
    2339 2326
     
    
    2340 2327
                         -- Important: even if the coercion is Refl,
    
    2341 2328
                         --   * new_ev has reductionReducedType on the RHS
    
    ... ... @@ -2346,45 +2333,56 @@ canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs
    2346 2333
                                , eq_lhs = lhs
    
    2347 2334
                                , eq_rhs = reductionReducedType rhs_redn } } }
    
    2348 2335
     
    
    2349
    --- | Some problems prevent /unification/ but not /rewriting/:
    
    2350
    ---
    
    2351
    --- Skolem-escape: if we have [W] alpha[2] ~ Maybe b[3]
    
    2352
    ---    we can't unify (skolem-escape); but it /is/ canonical,
    
    2353
    ---    and hence we /can/ use it for rewriting
    
    2354
    ---
    
    2355
    --- Concrete-ness:  alpha[conc] ~ b[sk]
    
    2356
    ---    We can use it to rewrite; we still have to solve the original
    
    2357
    -do_not_prevent_rewriting :: CheckTyEqResult
    
    2358
    -do_not_prevent_rewriting = cteProblem cteSkolemEscape S.<>
    
    2359
    -                           cteProblem cteConcrete
    
    2336
    +checkTypeEqNoUnification :: CtEvidence -> EqRel -> CanEqLHS -> TcType
    
    2337
    +                         -> TcS (PuResult Ct Reduction)
    
    2338
    +-- Used for general CanEqLHSs, when we have decided that we cannot unify
    
    2339
    +checkTypeEqNoUnification ev eq_rel lhs rhs =
    
    2340
    +  case ev of
    
    2341
    +    CtGiven {} ->
    
    2342
    +      do { traceTcS "checkTypeEqNoUnification (given) {" (vcat [ text "lhs:" <+> ppr lhs
    
    2343
    +                                                  , text "rhs:" <+> ppr rhs ])
    
    2344
    +         ; check_result <- wrapTcS (checkTyEqRhs given_flags rhs)
    
    2345
    +         ; traceTcS "checkTypeEqNoUnification }" (ppr check_result)
    
    2346
    +         ; case check_result of
    
    2347
    +              PuFail reason -> return (PuFail reason)
    
    2348
    +              PuOK prs redn -> do { new_givens <- mapBagM mk_new_given prs
    
    2349
    +                                  ; emitWork new_givens
    
    2350
    +                                  ; updInertSet (addCycleBreakerBindings prs)
    
    2351
    +                                  ; return (pure redn) } }
    
    2352
    +    CtWanted {} -> do { traceTcS "checkTypeEqNoUnification (wanted) {" $
    
    2353
    +                        vcat [ text "lhs:" <+> ppr lhs
    
    2354
    +                             , text "rhs:" <+> ppr rhs ]
    
    2355
    +                      ; check_result <- wrapTcS (checkTyEqRhs wanted_flags rhs)
    
    2356
    +                      ; traceTcS "checkTypeEqNoUnification }" (ppr check_result)
    
    2357
    +                      ; return check_result }
    
    2358
    +  where
    
    2359
    +    wanted_flags :: TyEqFlags TcM Ct
    
    2360
    +    wanted_flags = notUnifying_TEFTask occ_prob lhs
    
    2361
    +        -- See Note [Don't cycle-break Wanteds when not unifying]
    
    2362
    +
    
    2363
    +    given_flags :: TyEqFlags TcM (TcTyVar, TcType)
    
    2364
    +    given_flags = wanted_flags { tef_fam_app = mkTEFA_Break ev eq_rel BreakGiven }
    
    2365
    +        -- TEFA_Break used for: [G] a ~ Maybe (F a)
    
    2366
    +        --                   or [G] F a ~ Maybe (F a)
    
    2367
    +
    
    2368
    +    -- occ_prob: see Note [Occurs check and representational equality]
    
    2369
    +    occ_prob = case eq_rel of
    
    2370
    +                 NomEq  -> cteInsolubleOccurs
    
    2371
    +                 ReprEq -> cteSolubleOccurs
    
    2372
    +
    
    2373
    +    ---------------------------
    
    2374
    +    mk_new_given :: (TcTyVar, TcType) -> TcS Ct
    
    2375
    +    mk_new_given (new_tv, fam_app)
    
    2376
    +      = mkNonCanonical . CtGiven <$> newGivenEv cb_loc (given_pred, given_term)
    
    2377
    +      where
    
    2378
    +        new_ty     = mkTyVarTy new_tv
    
    2379
    +        given_pred = mkNomEqPred fam_app new_ty
    
    2380
    +        given_term = evCoercion $ mkNomReflCo new_ty  -- See Detail (4) of Note
    
    2360 2381
     
    
    2361
    -----------------------
    
    2362
    -swapAndFinish :: CtEvidence -> EqRel -> SwapFlag
    
    2363
    -              -> TcType -> CanEqLHS      -- ty ~ F tys
    
    2364
    -              -> TcS (StopOrContinue (Either unused EqCt))
    
    2365
    --- We have an equality alpha ~ F tys, that we can't unify e.g because 'tys'
    
    2366
    --- mentions alpha, it would not be a canonical constraint as-is.
    
    2367
    --- We want to flip it to (F tys ~ a), whereupon it is canonical
    
    2368
    -swapAndFinish ev eq_rel swapped lhs_ty can_rhs
    
    2369
    -  = do { new_ev <- rewriteEqEvidenceSwapOnly ev eq_rel (flipSwap swapped) can_rhs lhs_ty
    
    2370
    -       ; continueWith $ Right $
    
    2371
    -         EqCt { eq_ev  = new_ev, eq_eq_rel = eq_rel
    
    2372
    -              , eq_lhs = can_rhs, eq_rhs = lhs_ty } }
    
    2382
    +    -- See Detail (7) of the Note
    
    2383
    +    cb_loc = updateCtLocOrigin (ctEvLoc ev) CycleBreakerOrigin
    
    2373 2384
     
    
    2374 2385
     ----------------------
    
    2375
    -tryIrredInstead :: CheckTyEqResult -> CtEvidence
    
    2376
    -                -> EqRel -> SwapFlag -> CanEqLHS -> TcType
    
    2377
    -                -> TcS (StopOrContinue (Either IrredCt unused))
    
    2378
    --- We have a non-canonical equality
    
    2379
    --- We still swap it if 'swapped' says so, so that it is oriented
    
    2380
    --- in the direction that the error-reporting machinery
    
    2381
    --- expects it; e.g.  (m ~ t m) rather than (t m ~ m)
    
    2382
    --- This is not very important, and only affects error reporting.
    
    2383
    -tryIrredInstead reason ev eq_rel swapped lhs rhs
    
    2384
    -  = do { traceTcS "cantMakeCanonical" (ppr reason $$ ppr lhs $$ ppr rhs)
    
    2385
    -       ; new_ev <- rewriteEqEvidenceSwapOnly ev eq_rel swapped lhs rhs
    
    2386
    -       ; finishCanWithIrred (NonCanonicalReason reason) new_ev }
    
    2387
    -
    
    2388 2386
     finishCanWithIrred :: CtIrredReason -> CtEvidence
    
    2389 2387
                        -> TcS (StopOrContinue (Either IrredCt a))
    
    2390 2388
     finishCanWithIrred reason ev
    
    ... ... @@ -2404,8 +2402,63 @@ canEqReflexive ev eq_rel ty
    2404 2402
       = do { setEqIfWanted ev (mkReflCPH eq_rel ty)
    
    2405 2403
            ; stopWith ev "Solved by reflexivity" }
    
    2406 2404
     
    
    2407
    -{- Note [Equalities with heterogeneous kinds]
    
    2408
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2405
    +{- Note [Equalities where unification fails]
    
    2406
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2407
    +If we can't unify, but the equality is canonical, we still want to add it to the
    
    2408
    +inert set so that it can be used to rewrite other Wanteds.  (There are many
    
    2409
    +reasons by unification might not happen: the LHS is not a touchable unification
    
    2410
    +variable, it has rewriters, it's a Given etc.)
    
    2411
    +
    
    2412
    +* In this case we call `checkTypeEqNoUnification`to see if it is canonical (which
    
    2413
    +  in turn calls `checkTypeEqRhs` with suitable flags).
    
    2414
    +
    
    2415
    +* NB: we do /not/ try to take advantage of the case where
    
    2416
    +  `canEqCanLHSFinish_try_unification` has already called `checkTyEqRhs`; doing so
    
    2417
    +  caused #27844.  (The first call did fam-app breaking, which concealed a genuine
    
    2418
    +  occurs check.)  It's just too clever; better to do the simple thing.
    
    2419
    +
    
    2420
    +Note [Don't cycle-break Wanteds when not unifying]
    
    2421
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2422
    +Consdier
    
    2423
    +  [W] a[2] ~ Maybe (F a[2])
    
    2424
    +
    
    2425
    +Should we cycle-break this Wanted, thus?
    
    2426
    +
    
    2427
    +  [W] a[2] ~ Maybe delta[2]
    
    2428
    +  [W] delta[2] ~ F a[2]
    
    2429
    +
    
    2430
    +For a start, this is dodgy because we might just unify delta, thus undoing
    
    2431
    +what we have done, and getting an infinite loop in the solver.  Even if we
    
    2432
    +somehow prevented ourselves from doing so, is there any merit in the split?
    
    2433
    +Maybe: perhaps we can use that equality on `a` to unlock other constraints?
    
    2434
    +Consider
    
    2435
    +  type instance F (Maybe _) = Bool
    
    2436
    +
    
    2437
    +  [G] g1: a ~ Maybe Bool
    
    2438
    +  [W] w1: a ~ Maybe (F a)
    
    2439
    +
    
    2440
    +If we loop-break w1 to get
    
    2441
    +  [W] w1': a ~ Maybe gamma
    
    2442
    +  [W] w3:  gamma ~ F a
    
    2443
    +Now rewrite w3 with w1'
    
    2444
    +  [W] w3':  gamma ~ F (Maybe gamma)
    
    2445
    +Now use the type instance to get
    
    2446
    +  gamma := Bool
    
    2447
    +Now we are left with
    
    2448
    +  [W] w1': a ~ Maybe Bool
    
    2449
    +which we can solve from the Given.
    
    2450
    +
    
    2451
    +BUT in this situation we could have rewritten the
    
    2452
    +/original/ Wanted from the Given, like this:
    
    2453
    +  [W] w1': Maybe Bool ~ Maybe (F (Maybe Bool))
    
    2454
    +and that is readily soluble.
    
    2455
    +
    
    2456
    +In short: loop-breaking Wanteds, when we aren't unifying,
    
    2457
    +seems of no merit.  Hence TEFA_Recurse, rather than TEFA_Break,
    
    2458
    +in `wanted_flags` in `checkTypeEqNoUnification`.
    
    2459
    +
    
    2460
    +Note [Equalities with heterogeneous kinds]
    
    2461
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2409 2462
     What do we do when we have an equality
    
    2410 2463
     
    
    2411 2464
       (tv :: k1) ~ (rhs :: k2)
    
    ... ... @@ -2587,8 +2640,7 @@ The details depend on whether we're working with a Given or a Wanted.
    2587 2640
     Given
    
    2588 2641
     -----
    
    2589 2642
     We emit a new Given, [G] F a ~ cbv, equating the type family application
    
    2590
    -to our new cbv. This is actually done by `break_given` in
    
    2591
    -`GHC.Tc.Solver.Monad.checkTypeEq`.
    
    2643
    +to our new cbv. This is actually done by `break_given` in `checkTypeEqNoUnification`.
    
    2592 2644
     
    
    2593 2645
     Note its orientation: The type family ends up on the left; see
    
    2594 2646
     Note [Orienting TyFamLHS/TyFamLHS]. No special treatment for
    
    ... ... @@ -3076,8 +3128,6 @@ inertsEqsCanDischarge inerts (EqCt { eq_lhs = lhs_w, eq_rhs = rhs_w
    3076 3128
     
    
    3077 3129
     inertsEqsCanDischarge _ _ = Nothing
    
    3078 3130
     
    
    3079
    -
    
    3080
    -
    
    3081 3131
     {- Note [Do not unify Givens]
    
    3082 3132
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3083 3133
     Consider this GADT match
    
    ... ... @@ -3143,34 +3193,6 @@ Wrinkles:
    3143 3193
        we should kick out `co` so that we can now unify it, which might
    
    3144 3194
        unlock other stuff.  See `kickOutAfterFillingCoercionHole` in
    
    3145 3195
        GHC.Tc.Solver.Monad.
    
    3146
    -
    
    3147
    -Note [Solve by unification]
    
    3148
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3149
    -If we solve
    
    3150
    -   alpha[n] ~ ty
    
    3151
    -by unification, there are two cases to consider
    
    3152
    -
    
    3153
    -* TouchableSameLevel: if the ambient level is 'n', then
    
    3154
    -  we can simply update alpha := ty, and do nothing else
    
    3155
    -
    
    3156
    -* TouchableOuterLevel free_metas n: if the ambient level is greater than
    
    3157
    -  'n' (the level of alpha), in addition to setting alpha := ty we must
    
    3158
    -  do two other things:
    
    3159
    -
    
    3160
    -  1. Promote all the free meta-vars of 'ty' to level n.  After all,
    
    3161
    -     alpha[n] is at level n, and so if we set, say,
    
    3162
    -          alpha[n] := Maybe beta[m],
    
    3163
    -     we must ensure that when unifying beta we do skolem-escape checks
    
    3164
    -     etc relevant to level n.  Simple way to do that: promote beta to
    
    3165
    -     level n.
    
    3166
    -
    
    3167
    -  2. Set the Unification Level Flag to record that a level-n unification has
    
    3168
    -     taken place. See Note [WhatUnifications] in GHC.Tc.Utils.Unify
    
    3169
    -
    
    3170
    -NB: TouchableSameLevel is just an optimisation for TouchableOuterLevel. Promotion
    
    3171
    -would be a no-op, and setting the unification flag unnecessarily would just
    
    3172
    -make the solver iterate more often.  (We don't need to iterate when unifying
    
    3173
    -at the ambient level because of the kick-out mechanism.)
    
    3174 3196
     -}
    
    3175 3197
     
    
    3176 3198
     
    

  • compiler/GHC/Tc/Solver/InertSet.hs
    ... ... @@ -983,7 +983,7 @@ How do we establish these conditions?
    983 983
         with S(fw,_).
    
    984 984
     
    
    985 985
       * (T3) is guaranteed by an occurs-check on the work item.
    
    986
    -    This is done during canonicalisation, in checkTypeEq; invariant
    
    986
    +    This is done during canonicalisation, in checkTyEqRhs; invariant
    
    987 987
         (TyEq:OC) of CEqCan. See also Note [EqCt occurs check] in GHC.Tc.Types.Constraint.
    
    988 988
     
    
    989 989
       * (T4) is established by GHC.Tc.Solver.Monad.kickOutRewritable.  If the inert
    

  • compiler/GHC/Tc/Solver/Monad.hs
    ... ... @@ -117,10 +117,7 @@ module GHC.Tc.Solver.Monad (
    117 117
         getDefaultInfo, getDynFlags, getGlobalRdrEnvTcS,
    
    118 118
         matchFam, matchFamTcM,
    
    119 119
         checkWellLevelledDFun,
    
    120
    -    pprEq,
    
    121
    -
    
    122
    -    -- Enforcing invariants for type equalities
    
    123
    -    checkTypeEq
    
    120
    +    pprEq
    
    124 121
     ) where
    
    125 122
     
    
    126 123
     import GHC.Prelude
    
    ... ... @@ -2302,52 +2299,6 @@ wrapUnifier rws loc role do_unifications
    2302 2299
     ************************************************************************
    
    2303 2300
     -}
    
    2304 2301
     
    
    2305
    -checkTypeEq :: CtEvidence -> EqRel -> CanEqLHS -> TcType
    
    2306
    -            -> TcS (PuResult Ct Reduction)
    
    2307
    --- Used for general CanEqLHSs, ones that do
    
    2308
    --- not have a touchable type variable on the LHS (i.e. not unifying)
    
    2309
    -checkTypeEq ev eq_rel lhs rhs =
    
    2310
    -  case ev of
    
    2311
    -    CtGiven {} ->
    
    2312
    -      do { traceTcS "checkTypeEq {" (vcat [ text "lhs:" <+> ppr lhs
    
    2313
    -                                          , text "rhs:" <+> ppr rhs ])
    
    2314
    -         ; check_result <- wrapTcS (checkTyEqRhs given_flags rhs)
    
    2315
    -         ; traceTcS "checkTypeEq }" (ppr check_result)
    
    2316
    -         ; case check_result of
    
    2317
    -              PuFail reason -> return (PuFail reason)
    
    2318
    -              PuOK prs redn -> do { new_givens <- mapBagM mk_new_given prs
    
    2319
    -                                  ; emitWork new_givens
    
    2320
    -                                  ; updInertSet (addCycleBreakerBindings prs)
    
    2321
    -                                  ; return (pure redn) } }
    
    2322
    -    CtWanted {} -> wrapTcS (checkTyEqRhs wanted_flags rhs)
    
    2323
    -  where
    
    2324
    -    wanted_flags :: TyEqFlags TcM Ct
    
    2325
    -    wanted_flags = notUnifying_TEFTask occ_prob lhs
    
    2326
    -                   -- checkTypeEq deals only with the non-unifying case
    
    2327
    -
    
    2328
    -    given_flags :: TyEqFlags TcM (TcTyVar, TcType)
    
    2329
    -    given_flags = wanted_flags { tef_fam_app = mkTEFA_Break ev eq_rel BreakGiven }
    
    2330
    -        -- TEFA_Break used for: [G] a ~ Maybe (F a)
    
    2331
    -        --                   or [W] F a ~ Maybe (F a)
    
    2332
    -
    
    2333
    -    -- occ_prob: see Note [Occurs check and representational equality]
    
    2334
    -    occ_prob = case eq_rel of
    
    2335
    -                 NomEq  -> cteInsolubleOccurs
    
    2336
    -                 ReprEq -> cteSolubleOccurs
    
    2337
    -
    
    2338
    -    ---------------------------
    
    2339
    -    mk_new_given :: (TcTyVar, TcType) -> TcS Ct
    
    2340
    -    mk_new_given (new_tv, fam_app)
    
    2341
    -      = mkNonCanonical . CtGiven <$> newGivenEv cb_loc (given_pred, given_term)
    
    2342
    -      where
    
    2343
    -        new_ty     = mkTyVarTy new_tv
    
    2344
    -        given_pred = mkNomEqPred fam_app new_ty
    
    2345
    -        given_term = evCoercion $ mkNomReflCo new_ty  -- See Detail (4) of Note
    
    2346
    -
    
    2347
    -    -- See Detail (7) of the Note
    
    2348
    -    cb_loc = updateCtLocOrigin (ctEvLoc ev) CycleBreakerOrigin
    
    2349
    -
    
    2350
    --------------------------
    
    2351 2302
     -- | Fill in CycleBreakerTvs with the variables they stand for.
    
    2352 2303
     -- See Note [Type equality cycles] in GHC.Tc.Solver.Equality
    
    2353 2304
     restoreTyVarCycles :: InertSet -> TcM ()
    
    ... ... @@ -2363,43 +2314,4 @@ restoreTyVarCycles is
    2363 2314
     (a ~R# b a) is soluble if b later turns out to be Identity
    
    2364 2315
     So we treat this as a "soluble occurs check".
    
    2365 2316
     
    
    2366
    -Note [Don't cycle-break Wanteds when not unifying]
    
    2367
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2368
    -Consdier
    
    2369
    -  [W] a[2] ~ Maybe (F a[2])
    
    2370
    -
    
    2371
    -Should we cycle-break this Wanted, thus?
    
    2372
    -
    
    2373
    -  [W] a[2] ~ Maybe delta[2]
    
    2374
    -  [W] delta[2] ~ F a[2]
    
    2375
    -
    
    2376
    -For a start, this is dodgy because we might just unify delta, thus undoing
    
    2377
    -what we have done, and getting an infinite loop in the solver.  Even if we
    
    2378
    -somehow prevented ourselves from doing so, is there any merit in the split?
    
    2379
    -Maybe: perhaps we can use that equality on `a` to unlock other constraints?
    
    2380
    -Consider
    
    2381
    -  type instance F (Maybe _) = Bool
    
    2382
    -
    
    2383
    -  [G] g1: a ~ Maybe Bool
    
    2384
    -  [W] w1: a ~ Maybe (F a)
    
    2385
    -
    
    2386
    -If we loop-break w1 to get
    
    2387
    -  [W] w1': a ~ Maybe gamma
    
    2388
    -  [W] w3:  gamma ~ F a
    
    2389
    -Now rewrite w3 with w1'
    
    2390
    -  [W] w3':  gamma ~ F (Maybe gamma)
    
    2391
    -Now use the type instance to get
    
    2392
    -  gamma := Bool
    
    2393
    -Now we are left with
    
    2394
    -  [W] w1': a ~ Maybe Bool
    
    2395
    -which we can solve from the Given.
    
    2396
    -
    
    2397
    -BUT in this situation we could have rewritten the
    
    2398
    -/original/ Wanted from the Given, like this:
    
    2399
    -  [W] w1': Maybe Bool ~ Maybe (F (Maybe Bool))
    
    2400
    -and that is readily soluble.
    
    2401
    -
    
    2402
    -In short: loop-breaking Wanteds, when we aren't unifying,
    
    2403
    -seems of no merit.  Hence TEFA_Recurse, rather than TEFA_Break,
    
    2404
    -in `wanted_flags` in `checkTypeEq`.
    
    2405 2317
     -}

  • compiler/GHC/Tc/Types/Constraint.hs
    ... ... @@ -524,7 +524,7 @@ isInsolubleReason (InsolubleFunDepReason {}) = True
    524 524
     ------------------------------------------------------------------------------
    
    525 525
     
    
    526 526
     -- | A /set/ of problems in checking the validity of a type equality.
    
    527
    --- See 'checkTypeEq'.
    
    527
    +-- See 'GHC.Tc.Utils.Unify.checkTyEqRhs'.
    
    528 528
     newtype CheckTyEqResult = CTER Word8
    
    529 529
     
    
    530 530
     -- | No problems in checking the validity of a type equality.
    

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -3617,15 +3617,20 @@ instance Outputable SimpleUnifyResult where
    3617 3617
     simpleUnifyCheck :: UnifyCheckCaller -> TcLevel -> TcTyVar -> TcType -> SimpleUnifyResult
    
    3618 3618
     -- ^ A fast check for unification. May return "not sure", in which case
    
    3619 3619
     -- unification might still be OK, but it'll take more work to do
    
    3620
    --- (use the full 'checkTypeEq').
    
    3620
    +-- (use the full 'checkTyEqRhs').
    
    3621 3621
     --
    
    3622
    --- * Rejects if lhs_tv occurs in rhs_ty (occurs check)
    
    3623
    --- * Rejects foralls unless
    
    3624
    ---      lhs_tv is RuntimeUnk (used by GHCi debugger)
    
    3625
    ---          or is a QL instantiation variable
    
    3626
    --- * Rejects a non-concrete type if lhs_tv is concrete
    
    3627
    --- * Rejects type families unless fam_ok=True
    
    3628
    --- * Does a level-check for type variables, to avoid skolem escape
    
    3622
    +-- It returns SUC_CannotUnify for
    
    3623
    +--   * Touchability failure
    
    3624
    +--   * Top level-shape failure
    
    3625
    +--
    
    3626
    +-- It returns SUC_NotSure for
    
    3627
    +--   * Occurs check: lhs_tv occurs in rhs_ty
    
    3628
    +--   * Type families unless fam_ok=True
    
    3629
    +--   * Foralls unless
    
    3630
    +--        lhs_tv is RuntimeUnk (used by GHCi debugger)
    
    3631
    +--            or is a QL instantiation variable
    
    3632
    +--   * Concreteness: lhs_tv is concrete and rhs is a non-concrete type
    
    3633
    +--   * Skolem-escape: a level-check for type variables, to avoid skolem escape
    
    3629 3634
     --
    
    3630 3635
     -- This function is pretty heavily used, so it's optimised not to allocate
    
    3631 3636
     simpleUnifyCheck caller given_eq_lvl lhs_tv rhs
    
    ... ... @@ -4198,7 +4203,7 @@ famAppArgFlags flags = case flags of
    4198 4203
     The key function `checkTyEqRhs ty_eq_flags rhs` is called on the
    
    4199 4204
     RHS of a type equality
    
    4200 4205
            lhs ~ rhs
    
    4201
    -and checks to see if `rhs` satisfies, or can be made to satisfy,
    
    4206
    +and checks to see if `rhs` satisfies, /or can be made to satisfy/,
    
    4202 4207
     invariants described by `ty_eq_flags`.  It can succeded or fail; in
    
    4203 4208
     the latter case it returns a `CheckTyEqResult` that describes why it
    
    4204 4209
     failed.
    
    ... ... @@ -4219,6 +4224,15 @@ Notably, it can check for things like:
    4219 4224
       * Concreteness error
    
    4220 4225
           e.g. alpha[conc] ~ r[sk]
    
    4221 4226
     
    
    4227
    +Note "or can be made to satisfy the preconditions"!  `checkTyEqRhs` may transform
    
    4228
    +the RHS by
    
    4229
    +
    
    4230
    +  * Turning a type-family application into a type variable, perhaps to avoid
    
    4231
    +    an occurs check.  See Note Note [Family applications in canonical constraints]
    
    4232
    +
    
    4233
    +  * Promoting any nested unification variables, in order to satisfy the
    
    4234
    +    level invariant. See Note [Promotion and level-checking]
    
    4235
    +
    
    4222 4236
     Its specific behaviour is governed by the `TyEqFlags` that are passed
    
    4223 4237
     to it; see Note [TyEqFlags].
    
    4224 4238
     
    
    ... ... @@ -4275,7 +4289,7 @@ NB: We never see a TyVarLHS here, such as
    4275 4289
         [G] a ~ F tys here
    
    4276 4290
     because we'd have swapped it to
    
    4277 4291
        [G] F tys ~ a
    
    4278
    -in canEqCanLHS2, before getting to checkTypeEq.
    
    4292
    +in canEqCanLHS2, before getting to checkTyEqRhs.
    
    4279 4293
     -}
    
    4280 4294
     
    
    4281 4295
     check_ty_eq_rhs :: forall m a
    
    ... ... @@ -4799,7 +4813,6 @@ promote_meta_tyvar info dest_lvl occ_tv
    4799 4813
     touchabilityTest :: TcLevel -> TcTyVar -> Bool
    
    4800 4814
     -- ^ This is the key test for untouchability:
    
    4801 4815
     -- See Note [Unification preconditions] in GHC.Tc.Utils.Unify
    
    4802 4816
     --
    
    4803 4817
     -- @True@ <=> the variable is touchable
    
    4804 4818
     touchabilityTest given_eq_lvl tv
    

  • testsuite/tests/indexed-types/should_fail/T9662.stderr
    1 1
     T9662.hs:49:8: error: [GHC-25897]
    
    2
    -    • Couldn't match type ‘n’ with ‘Int’
    
    2
    +    • Couldn't match type ‘m’ with ‘Int’
    
    3 3
           Expected: Exp (((sh :. k) :. m) :. n)
    
    4 4
                     -> Exp (((sh :. m) :. n) :. k)
    
    5 5
             Actual: Exp
    
    6 6
                       (Tuple (((Atom a0 :. Atom Int) :. Atom Int) :. Atom Int))
    
    7 7
                     -> Exp
    
    8 8
                          (Plain (((Unlifted (Atom a0) :. Exp Int) :. Exp Int) :. Exp Int))
    
    9
    -      ‘n’ is a rigid type variable bound by
    
    9
    +      ‘m’ is a rigid type variable bound by
    
    10 10
             the type signature for:
    
    11 11
               test :: forall sh k m n.
    
    12 12
                       Shape (((sh :. k) :. m) :. n) -> Shape (((sh :. m) :. n) :. k)
    

  • testsuite/tests/simplCore/should_compile/T7803.hs
    1
    +{-# OPTIONS_GHC -ddump-simpl #-}
    
    2
    +
    
    3
    +-- #7803: foo1 should be fully specialised at Double.  In the bug report
    
    4
    +-- it ended up calling the overloaded exp5Tail (with a dictionary argument),
    
    5
    +-- because the specialiser ran before the overloaded call was floated to
    
    6
    +-- the top level.  So the dumped Core for this module must mention no
    
    7
    +-- exp5Tail at all.
    
    8
    +module T7803 (foo1) where
    
    9
    +
    
    10
    +import T7803a
    
    11
    +
    
    12
    +bar :: Floating a => a -> a -> a
    
    13
    +bar z = subtract (evaluate integ z) . evaluate integ
    
    14
    +  where
    
    15
    +    integ = indefinite (Piecewise [Poly4 1])
    
    16
    +{-# SPECIALIZE bar :: Double -> Double -> Double #-}
    
    17
    +
    
    18
    +foo :: Floating a => a -> a -> a
    
    19
    +foo x = bar x
    
    20
    +{-# SPECIALIZE foo :: Double -> Double -> Double #-}
    
    21
    +
    
    22
    +foo1 :: Double -> Double -> Double
    
    23
    +foo1 x = foo x

  • testsuite/tests/simplCore/should_compile/T7803.stderr
    1
    +foo1

  • testsuite/tests/simplCore/should_compile/T7803a.hs
    1
    +{-# LANGUAGE ConstraintKinds #-}
    
    2
    +{-# LANGUAGE FlexibleContexts #-}
    
    3
    +{-# LANGUAGE FlexibleInstances #-}
    
    4
    +{-# LANGUAGE MultiParamTypeClasses #-}
    
    5
    +{-# LANGUAGE TypeFamilies #-}
    
    6
    +{-# LANGUAGE UndecidableInstances #-}
    
    7
    +{-# LANGUAGE UndecidableSuperClasses #-}
    
    8
    +
    
    9
    +module T7803a
    
    10
    +    ( Evaluate (..)
    
    11
    +    , HasIntegral (..)
    
    12
    +    , Poly4 (..)
    
    13
    +    , Domain
    
    14
    +    , IntOfLogPoly4 (..)
    
    15
    +    , Piecewise (..)
    
    16
    +    ) where
    
    17
    +
    
    18
    +import Data.Kind (Constraint, Type)
    
    19
    +
    
    20
    +class Evaluate poly where
    
    21
    +    evaluate :: (Domain' poly a) => poly a -> a -> a
    
    22
    +
    
    23
    +class Evaluate (IntegralOf poly) => HasIntegral poly where
    
    24
    +    type IntegralOf poly :: Type -> Type
    
    25
    +    indefinite :: (Domain' poly a, Domain' (IntegralOf poly) a)
    
    26
    +               => poly a -> IntegralOf poly a
    
    27
    +
    
    28
    +type family Domain (f :: Type -> Type) a :: Constraint
    
    29
    +
    
    30
    +class Domain f a => Domain' f a
    
    31
    +instance Domain f a => Domain' f a
    
    32
    +
    
    33
    +newtype Poly4 a = Poly4 { poly4_a :: a }
    
    34
    +
    
    35
    +type instance Domain Poly4 a = Fractional a
    
    36
    +
    
    37
    +data IntOfLogPoly4 a = IntOfLogPoly4 { ilp4_k :: !a, ilp4_u :: !a }
    
    38
    +
    
    39
    +type instance Domain IntOfLogPoly4 a = Floating a
    
    40
    +
    
    41
    +instance Evaluate IntOfLogPoly4 where
    
    42
    +    evaluate (IntOfLogPoly4 k _) x = k + x * exp5Tail (- log x)
    
    43
    +    {-# INLINE evaluate #-}
    
    44
    +
    
    45
    +{-# RULES "exp5Tail/Double" exp5Tail = exp5TailDouble #-}
    
    46
    +{-# NOINLINE exp5Tail #-}
    
    47
    +
    
    48
    +exp5Tail :: (Floating a) => a -> a
    
    49
    +exp5Tail x = x / 120
    
    50
    +
    
    51
    +exp5TailDouble :: Double -> Double
    
    52
    +exp5TailDouble x = x / 120
    
    53
    +
    
    54
    +instance HasIntegral Poly4 where
    
    55
    +    type IntegralOf Poly4 = IntOfLogPoly4
    
    56
    +    indefinite = \ (Poly4 a) -> IntOfLogPoly4 0 a
    
    57
    +    {-# INLINE indefinite #-}
    
    58
    +
    
    59
    +newtype Piecewise poly a = Piecewise { unPiecewise :: [poly a] }
    
    60
    +
    
    61
    +type instance Domain (Piecewise poly) a = (Domain poly a, Num a)
    
    62
    +
    
    63
    +instance (Evaluate poly) => Evaluate (Piecewise poly) where
    
    64
    +    evaluate = \ (Piecewise pp) x ->
    
    65
    +        case pp of
    
    66
    +          p : _ -> evaluate p x
    
    67
    +          []    -> error "evaluate: empty Piecewise"
    
    68
    +    {-# INLINE evaluate #-}
    
    69
    +
    
    70
    +instance (HasIntegral poly) => HasIntegral (Piecewise poly) where
    
    71
    +    type IntegralOf (Piecewise poly) = Piecewise (IntegralOf poly)
    
    72
    +    indefinite (Piecewise m) = Piecewise $ map indefinite m
    
    73
    +    {-# INLINE indefinite #-}

  • testsuite/tests/simplCore/should_compile/all.T
    ... ... @@ -148,6 +148,13 @@ test('T7785', [ only_ways(['optasm']),
    148 148
                    grep_errmsg(r'SPEC') ],
    
    149 149
           compile, ['-ddump-cse'])
    
    150 150
     
    
    151
    +# T7803: we expect NO calls to the overloaded 'exp5Tail' in T7803.hs
    
    152
    +# In the bug report #7803, the unspecialised call was signalled by 'exp5Tail'
    
    153
    +#    in foo1's Core, so we grep for that; also for 'foo1', lest we dump nothing
    
    154
    +# One module, T7803.hs, has OPTIONS_GHC -ddump-simpl
    
    155
    +test('T7803', [ grep_errmsg(r'exp5Tail|foo1') ],
    
    156
    +     multimod_compile, ['T7803', '-O2 -v0 -dsuppress-all -dsuppress-uniques -dno-typeable-binds'])
    
    157
    +
    
    151 158
     test('T7702',
    
    152 159
          [extra_files(['T7702plugin']),
    
    153 160
           pre_cmd('$MAKE -s --no-print-directory -C T7702plugin package.T7702 TOP={top}'),
    

  • testsuite/tests/typecheck/should_fail/T27844.hs
    1
    +-- Repro.hs
    
    2
    +-- The call to f forces c ~ (b, F c) inside the scope of the skolem b.
    
    3
    +-- Correct behaviour: a type error at the first argument of const
    
    4
    +-- (as GHC 9.12.4 reports).
    
    5
    +
    
    6
    +{-# LANGUAGE RankNTypes, TypeFamilies #-}
    
    7
    +module T27844 where
    
    8
    +
    
    9
    +type family F a
    
    10
    +
    
    11
    +f :: (forall b. b -> (b, F c)) -> c -> ()
    
    12
    +f _ _ = ()
    
    13
    +
    
    14
    +g x = f (\_ -> const x (show x)) x

  • testsuite/tests/typecheck/should_fail/T27844.stderr
    1
    +T27844.hs:13:22: error: [GHC-25897]
    
    2
    +    • Couldn't match expected type ‘(b, F c)’ with actual type ‘c’
    
    3
    +      ‘c’ is a rigid type variable bound by
    
    4
    +        the inferred type of g :: Show c => c -> ()
    
    5
    +        at T27844.hs:143:1-34
    
    6
    +    • In the first argument of ‘const’, namely ‘x’
    
    7
    +      In the expression: const x (show x)
    
    8
    +      In the first argument of ‘f’, namely ‘(\ _ -> const x (show x))’
    
    9
    +    • Relevant bindings include
    
    10
    +        x :: c (bound at T27844.hs:14:3)
    
    11
    +        g :: c -> () (bound at T27844.hs:14:1)

  • testsuite/tests/typecheck/should_fail/all.T
    ... ... @@ -763,3 +763,4 @@ test('T26861', normal, compile_fail, [''])
    763 763
     test('T26862', normal, compile_fail, [''])
    
    764 764
     test('T27210', normal, compile_fail, [''])
    
    765 765
     test('T26532', normal, compile_fail, [''])
    
    766
    +test('T27844', normal, compile_fail, [''])