Zubin pushed to branch wip/backports-9.12.4 at Glasgow Haskell Compiler / GHC
Commits:
-
451c6a43
by Simon Peyton Jones at 2026-03-04T12:15:09+05:30
-
85b0aae2
by Simon Peyton Jones at 2026-03-04T12:15:09+05:30
-
55885e4b
by Simon Peyton Jones at 2026-03-04T12:15:09+05:30
-
4fdab7ca
by sheaf at 2026-03-04T12:15:09+05:30
-
cfbec95d
by Rodrigo Mesquita at 2026-03-04T12:15:09+05:30
-
7d22504b
by Zubin Duggal at 2026-03-04T12:15:44+05:30
21 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Types/DefaultEnv.hs
- + docs/users_guide/9.12.4-notes.rst
- docs/users_guide/release-notes.rst
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- rts/Disassembler.c
- rts/Interpreter.c
- + testsuite/tests/default/T25775.hs
- + testsuite/tests/default/T25775.stderr
- testsuite/tests/default/all.T
- + testsuite/tests/typecheck/should_compile/T26451.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T12921.stderr
Changes:
| ... | ... | @@ -660,9 +660,22 @@ assembleI platform i = case i of |
| 660 | 660 | tick_addr <- addr tick_mod
|
| 661 | 661 | info_addr <- addr info_mod
|
| 662 | 662 | np <- addr cc
|
| 663 | + let -- cast that checks that round-tripping through
|
|
| 664 | + -- Word32 doesn't change the value
|
|
| 665 | + toW32 x = let r = fromIntegral x :: Word32
|
|
| 666 | + in if fromIntegral r == x
|
|
| 667 | + then r
|
|
| 668 | + else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr x)
|
|
| 669 | + tick32 = toW32 tickx
|
|
| 670 | + tick_hi = fromIntegral (tick32 `shiftR` 16)
|
|
| 671 | + tick_lo = fromIntegral (tick32 .&. 0xffff)
|
|
| 672 | + info32 = toW32 infox
|
|
| 673 | + info_hi = fromIntegral (info32 `shiftR` 16)
|
|
| 674 | + info_lo = fromIntegral (info32 .&. 0xffff)
|
|
| 663 | 675 | emit bci_BRK_FUN [ Op p1
|
| 664 | 676 | , Op tick_addr, Op info_addr
|
| 665 | - , SmallOp tickx, SmallOp infox
|
|
| 677 | + , SmallOp tick_hi, SmallOp tick_lo
|
|
| 678 | + , SmallOp info_hi, SmallOp info_lo
|
|
| 666 | 679 | , Op np
|
| 667 | 680 | ]
|
| 668 | 681 |
| ... | ... | @@ -1731,6 +1731,7 @@ simplCast env body co0 cont0 |
| 1731 | 1731 | , sc_hole_ty = coercionLKind co }) }
|
| 1732 | 1732 | -- NB! As the cast goes past, the
|
| 1733 | 1733 | -- type of the hole changes (#16312)
|
| 1734 | + |
|
| 1734 | 1735 | -- (f |> co) e ===> (f (e |> co1)) |> co2
|
| 1735 | 1736 | -- where co :: (s1->s2) ~ (t1->t2)
|
| 1736 | 1737 | -- co1 :: t1 ~ s1
|
| ... | ... | @@ -73,6 +73,7 @@ import GHC.Types.Tickish |
| 73 | 73 | import GHC.Types.Demand
|
| 74 | 74 | import GHC.Types.Var.Set
|
| 75 | 75 | import GHC.Types.Basic
|
| 76 | +import GHC.Types.Name.Env
|
|
| 76 | 77 | |
| 77 | 78 | import GHC.Data.OrdList ( isNilOL )
|
| 78 | 79 | import GHC.Data.FastString ( fsLit )
|
| ... | ... | @@ -82,9 +83,9 @@ import GHC.Utils.Monad |
| 82 | 83 | import GHC.Utils.Outputable
|
| 83 | 84 | import GHC.Utils.Panic
|
| 84 | 85 | |
| 85 | -import Control.Monad ( when )
|
|
| 86 | +import Control.Monad ( guard, when )
|
|
| 86 | 87 | import Data.List ( sortBy )
|
| 87 | -import GHC.Types.Name.Env
|
|
| 88 | +import Data.Maybe
|
|
| 88 | 89 | import Data.Graph
|
| 89 | 90 | |
| 90 | 91 | {- *********************************************************************
|
| ... | ... | @@ -2471,7 +2472,27 @@ Note [Eliminate Identity Case] |
| 2471 | 2472 | True -> True;
|
| 2472 | 2473 | False -> False
|
| 2473 | 2474 | |
| 2474 | -and similar friends.
|
|
| 2475 | +and similar friends. There are some tricky wrinkles:
|
|
| 2476 | + |
|
| 2477 | +(EIC1) Casts. We've seen this:
|
|
| 2478 | + case e of x { _ -> x `cast` c }
|
|
| 2479 | + And we definitely want to eliminate this case, to give
|
|
| 2480 | + e `cast` c
|
|
| 2481 | +(EIC2) Ticks. Similarly
|
|
| 2482 | + case e of x { _ -> Tick t x }
|
|
| 2483 | + At least if the tick is 'floatable' we want to eliminate the case
|
|
| 2484 | + to give
|
|
| 2485 | + Tick t e
|
|
| 2486 | + |
|
| 2487 | +So `check_eq` strips off enclosing casts and ticks from the RHS of the
|
|
| 2488 | +alternative, returning a wrapper function that will rebuild them around
|
|
| 2489 | +the scrutinee if case-elim is successful.
|
|
| 2490 | + |
|
| 2491 | +(EIC3) What if there are many alternatives, all identities. If casts
|
|
| 2492 | + are involved they must be the same cast, to make the types line up.
|
|
| 2493 | + In principle there could be different ticks in each RHS, but we just
|
|
| 2494 | + pick the ticks from the first alternative. (In the common case there
|
|
| 2495 | + is only one alternative.)
|
|
| 2475 | 2496 | |
| 2476 | 2497 | Note [Scrutinee Constant Folding]
|
| 2477 | 2498 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -2665,45 +2686,47 @@ mkCase mode scrut outer_bndr alts_ty alts |
| 2665 | 2686 | -- See Note [Eliminate Identity Case]
|
| 2666 | 2687 | --------------------------------------------------
|
| 2667 | 2688 | |
| 2668 | -mkCase1 _mode scrut case_bndr _ alts@(Alt _ _ rhs1 : alts') -- Identity case
|
|
| 2669 | - | all identity_alt alts
|
|
| 2689 | +mkCase1 _mode scrut case_bndr _ (alt1 : alts) -- Identity case
|
|
| 2690 | + | Just wrap <- identity_alt alt1 -- `wrap`: see (EIC1) and (EIC2)
|
|
| 2691 | + , all (isJust . identity_alt) alts -- See (EIC3) in Note [Eliminate Identity Case]
|
|
| 2670 | 2692 | = do { tick (CaseIdentity case_bndr)
|
| 2671 | - ; return (mkTicks ticks $ re_cast scrut rhs1) }
|
|
| 2693 | + ; return (wrap scrut) }
|
|
| 2672 | 2694 | where
|
| 2673 | - ticks = concatMap (\(Alt _ _ rhs) -> stripTicksT tickishFloatable rhs) alts'
|
|
| 2674 | - identity_alt (Alt con args rhs) = check_eq rhs con args
|
|
| 2675 | - |
|
| 2676 | - check_eq (Cast rhs co) con args -- See Note [RHS casts]
|
|
| 2677 | - = not (any (`elemVarSet` tyCoVarsOfCo co) args) && check_eq rhs con args
|
|
| 2678 | - check_eq (Tick t e) alt args
|
|
| 2679 | - = tickishFloatable t && check_eq e alt args
|
|
| 2680 | - |
|
| 2681 | - check_eq (Lit lit) (LitAlt lit') _ = lit == lit'
|
|
| 2682 | - check_eq (Var v) _ _ | v == case_bndr = True
|
|
| 2683 | - check_eq (Var v) (DataAlt con) args
|
|
| 2684 | - | null arg_tys, null args = v == dataConWorkId con
|
|
| 2685 | - -- Optimisation only
|
|
| 2686 | - check_eq rhs (DataAlt con) args = cheapEqExpr' tickishFloatable rhs $
|
|
| 2687 | - mkConApp2 con arg_tys args
|
|
| 2688 | - check_eq _ _ _ = False
|
|
| 2695 | + identity_alt :: CoreAlt -> Maybe (CoreExpr -> CoreExpr)
|
|
| 2696 | + identity_alt (Alt con args rhs) = check_eq con args rhs
|
|
| 2697 | + |
|
| 2698 | + check_eq :: AltCon -> [Var] -> CoreExpr -> Maybe (CoreExpr -> CoreExpr)
|
|
| 2699 | + -- (check_eq con args e) return True if
|
|
| 2700 | + -- e looks like (Tick (Cast (Tick (con args))))
|
|
| 2701 | + -- where (con args) is the LHS of the alternative
|
|
| 2702 | + -- In that case it returns (\e. Tick (Cast (Tick e))),
|
|
| 2703 | + -- a wrapper function that can rebuild the tick/cast stuff
|
|
| 2704 | + -- See (EIC1) and (EIC2) in Note [Eliminate Identity Case]
|
|
| 2705 | + check_eq alt_con args (Cast e co) -- See (EIC1)
|
|
| 2706 | + = do { guard (not (any (`elemVarSet` tyCoVarsOfCo co) args))
|
|
| 2707 | + ; wrap <- check_eq alt_con args e
|
|
| 2708 | + ; return (flip mkCast co . wrap) }
|
|
| 2709 | + check_eq alt_con args (Tick t e) -- See (EIC2)
|
|
| 2710 | + = do { guard (tickishFloatable t)
|
|
| 2711 | + ; wrap <- check_eq alt_con args e
|
|
| 2712 | + ; return (Tick t . wrap) }
|
|
| 2713 | + check_eq alt_con args e
|
|
| 2714 | + | is_id alt_con args e = Just (\e -> e)
|
|
| 2715 | + | otherwise = Nothing
|
|
| 2716 | + |
|
| 2717 | + is_id :: AltCon -> [Var] -> CoreExpr -> Bool
|
|
| 2718 | + is_id _ _ (Var v) | v == case_bndr = True
|
|
| 2719 | + is_id (LitAlt lit') _ (Lit lit) = lit == lit'
|
|
| 2720 | + is_id (DataAlt con) args rhs
|
|
| 2721 | + | Var v <- rhs -- Optimisation only
|
|
| 2722 | + , null arg_tys
|
|
| 2723 | + , null args = v == dataConWorkId con
|
|
| 2724 | + | otherwise = cheapEqExpr' tickishFloatable rhs $
|
|
| 2725 | + mkConApp2 con arg_tys args
|
|
| 2726 | + is_id _ _ _ = False
|
|
| 2689 | 2727 | |
| 2690 | 2728 | arg_tys = tyConAppArgs (idType case_bndr)
|
| 2691 | 2729 | |
| 2692 | - -- Note [RHS casts]
|
|
| 2693 | - -- ~~~~~~~~~~~~~~~~
|
|
| 2694 | - -- We've seen this:
|
|
| 2695 | - -- case e of x { _ -> x `cast` c }
|
|
| 2696 | - -- And we definitely want to eliminate this case, to give
|
|
| 2697 | - -- e `cast` c
|
|
| 2698 | - -- So we throw away the cast from the RHS, and reconstruct
|
|
| 2699 | - -- it at the other end. All the RHS casts must be the same
|
|
| 2700 | - -- if (all identity_alt alts) holds.
|
|
| 2701 | - --
|
|
| 2702 | - -- Don't worry about nested casts, because the simplifier combines them
|
|
| 2703 | - |
|
| 2704 | - re_cast scrut (Cast rhs co) = Cast (re_cast scrut rhs) co
|
|
| 2705 | - re_cast scrut _ = scrut
|
|
| 2706 | - |
|
| 2707 | 2730 | mkCase1 mode scrut bndr alts_ty alts = mkCase2 mode scrut bndr alts_ty alts
|
| 2708 | 2731 | |
| 2709 | 2732 |
| ... | ... | @@ -251,7 +251,7 @@ applyTypeToArgs pp_e op_ty args |
| 251 | 251 | |
| 252 | 252 | mkCastMCo :: CoreExpr -> MCoercionR -> CoreExpr
|
| 253 | 253 | mkCastMCo e MRefl = e
|
| 254 | -mkCastMCo e (MCo co) = Cast e co
|
|
| 254 | +mkCastMCo e (MCo co) = mkCast e co
|
|
| 255 | 255 | -- We are careful to use (MCo co) only when co is not reflexive
|
| 256 | 256 | -- Hence (Cast e co) rather than (mkCast e co)
|
| 257 | 257 | |
| ... | ... | @@ -302,40 +302,41 @@ mkCast expr co |
| 302 | 302 | -- | Wraps the given expression in the source annotation, dropping the
|
| 303 | 303 | -- annotation if possible.
|
| 304 | 304 | mkTick :: CoreTickish -> CoreExpr -> CoreExpr
|
| 305 | -mkTick t orig_expr = mkTick' id id orig_expr
|
|
| 305 | +mkTick t orig_expr = mkTick' id orig_expr
|
|
| 306 | 306 | where
|
| 307 | 307 | -- Some ticks (cost-centres) can be split in two, with the
|
| 308 | 308 | -- non-counting part having laxer placement properties.
|
| 309 | 309 | canSplit = tickishCanSplit t && tickishPlace (mkNoCount t) /= tickishPlace t
|
| 310 | + |
|
| 310 | 311 | -- mkTick' handles floating of ticks *into* the expression.
|
| 311 | - -- In this function, `top` is applied after adding the tick, and `rest` before.
|
|
| 312 | - -- This will result in applications that look like (top $ Tick t $ rest expr).
|
|
| 313 | - -- If we want to push the tick deeper, we pre-compose `top` with a function
|
|
| 314 | - -- adding the tick.
|
|
| 315 | - mkTick' :: (CoreExpr -> CoreExpr) -- apply after adding tick (float through)
|
|
| 316 | - -> (CoreExpr -> CoreExpr) -- apply before adding tick (float with)
|
|
| 317 | - -> CoreExpr -- current expression
|
|
| 312 | + mkTick' :: (CoreExpr -> CoreExpr) -- Apply before adding tick (float with)
|
|
| 313 | + -- Always a composition of (Tick t) wrappers
|
|
| 314 | + -> CoreExpr -- Current expression
|
|
| 318 | 315 | -> CoreExpr
|
| 319 | - mkTick' top rest expr = case expr of
|
|
| 316 | + -- So in the call (mkTick' rest e), the expression
|
|
| 317 | + -- (rest e)
|
|
| 318 | + -- has the same type as e
|
|
| 319 | + -- Returns an expression equivalent to (Tick t (rest e))
|
|
| 320 | + mkTick' rest expr = case expr of
|
|
| 320 | 321 | -- Float ticks into unsafe coerce the same way we would do with a cast.
|
| 321 | 322 | Case scrut bndr ty alts@[Alt ac abs _rhs]
|
| 322 | 323 | | Just rhs <- isUnsafeEqualityCase scrut bndr alts
|
| 323 | - -> top $ mkTick' (\e -> Case scrut bndr ty [Alt ac abs e]) rest rhs
|
|
| 324 | + -> Case scrut bndr ty [Alt ac abs (mkTick' rest rhs)]
|
|
| 324 | 325 | |
| 325 | 326 | -- Cost centre ticks should never be reordered relative to each
|
| 326 | 327 | -- other. Therefore we can stop whenever two collide.
|
| 327 | 328 | Tick t2 e
|
| 328 | - | ProfNote{} <- t2, ProfNote{} <- t -> top $ Tick t $ rest expr
|
|
| 329 | + | ProfNote{} <- t2, ProfNote{} <- t -> Tick t $ rest expr
|
|
| 329 | 330 | |
| 330 | 331 | -- Otherwise we assume that ticks of different placements float
|
| 331 | 332 | -- through each other.
|
| 332 | - | tickishPlace t2 /= tickishPlace t -> mkTick' (top . Tick t2) rest e
|
|
| 333 | + | tickishPlace t2 /= tickishPlace t -> Tick t2 $ mkTick' rest e
|
|
| 333 | 334 | |
| 334 | 335 | -- For annotations this is where we make sure to not introduce
|
| 335 | 336 | -- redundant ticks.
|
| 336 | - | tickishContains t t2 -> mkTick' top rest e
|
|
| 337 | - | tickishContains t2 t -> orig_expr
|
|
| 338 | - | otherwise -> mkTick' top (rest . Tick t2) e
|
|
| 337 | + | tickishContains t t2 -> mkTick' rest e -- Drop t2
|
|
| 338 | + | tickishContains t2 t -> rest e -- Drop t
|
|
| 339 | + | otherwise -> mkTick' (rest . Tick t2) e
|
|
| 339 | 340 | |
| 340 | 341 | -- Ticks don't care about types, so we just float all ticks
|
| 341 | 342 | -- through them. Note that it's not enough to check for these
|
| ... | ... | @@ -343,14 +344,14 @@ mkTick t orig_expr = mkTick' id id orig_expr |
| 343 | 344 | -- expressions below ticks, such constructs can be the result of
|
| 344 | 345 | -- unfoldings. We therefore make an effort to put everything into
|
| 345 | 346 | -- the right place no matter what we start with.
|
| 346 | - Cast e co -> mkTick' (top . flip Cast co) rest e
|
|
| 347 | - Coercion co -> Coercion co
|
|
| 347 | + Cast e co -> mkCast (mkTick' rest e) co
|
|
| 348 | + Coercion co -> Tick t $ rest (Coercion co)
|
|
| 348 | 349 | |
| 349 | 350 | Lam x e
|
| 350 | 351 | -- Always float through type lambdas. Even for non-type lambdas,
|
| 351 | 352 | -- floating is allowed for all but the most strict placement rule.
|
| 352 | 353 | | not (isRuntimeVar x) || tickishPlace t /= PlaceRuntime
|
| 353 | - -> mkTick' (top . Lam x) rest e
|
|
| 354 | + -> Lam x $ mkTick' rest e
|
|
| 354 | 355 | |
| 355 | 356 | -- If it is both counting and scoped, we split the tick into its
|
| 356 | 357 | -- two components, often allowing us to keep the counting tick on
|
| ... | ... | @@ -359,25 +360,25 @@ mkTick t orig_expr = mkTick' id id orig_expr |
| 359 | 360 | -- floated, and the lambda may then be in a position to be
|
| 360 | 361 | -- beta-reduced.
|
| 361 | 362 | | canSplit
|
| 362 | - -> top $ Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
|
|
| 363 | + -> Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
|
|
| 363 | 364 | |
| 364 | 365 | App f arg
|
| 365 | 366 | -- Always float through type applications.
|
| 366 | 367 | | not (isRuntimeArg arg)
|
| 367 | - -> mkTick' (top . flip App arg) rest f
|
|
| 368 | + -> App (mkTick' rest f) arg
|
|
| 368 | 369 | |
| 369 | 370 | -- We can also float through constructor applications, placement
|
| 370 | 371 | -- permitting. Again we can split.
|
| 371 | 372 | | isSaturatedConApp expr && (tickishPlace t==PlaceCostCentre || canSplit)
|
| 372 | 373 | -> if tickishPlace t == PlaceCostCentre
|
| 373 | - then top $ rest $ tickHNFArgs t expr
|
|
| 374 | - else top $ Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
|
|
| 374 | + then rest $ tickHNFArgs t expr
|
|
| 375 | + else Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
|
|
| 375 | 376 | |
| 376 | 377 | Var x
|
| 377 | 378 | | notFunction && tickishPlace t == PlaceCostCentre
|
| 378 | - -> orig_expr
|
|
| 379 | + -> rest expr -- Drop t
|
|
| 379 | 380 | | notFunction && canSplit
|
| 380 | - -> top $ Tick (mkNoScope t) $ rest expr
|
|
| 381 | + -> Tick (mkNoScope t) $ rest expr
|
|
| 381 | 382 | where
|
| 382 | 383 | -- SCCs can be eliminated on variables provided the variable
|
| 383 | 384 | -- is not a function. In these cases the SCC makes no difference:
|
| ... | ... | @@ -389,10 +390,10 @@ mkTick t orig_expr = mkTick' id id orig_expr |
| 389 | 390 | |
| 390 | 391 | Lit{}
|
| 391 | 392 | | tickishPlace t == PlaceCostCentre
|
| 392 | - -> orig_expr
|
|
| 393 | + -> rest expr -- Drop t
|
|
| 393 | 394 | |
| 394 | 395 | -- Catch-all: Annotate where we stand
|
| 395 | - _any -> top $ Tick t $ rest expr
|
|
| 396 | + _any -> Tick t $ rest expr
|
|
| 396 | 397 | |
| 397 | 398 | mkTicks :: [CoreTickish] -> CoreExpr -> CoreExpr
|
| 398 | 399 | mkTicks ticks expr = foldr mkTick expr ticks
|
| ... | ... | @@ -47,6 +47,7 @@ import GHC.Core.Make ( mkCharExpr, mkNaturalExpr, mkStringExprFS, mkCoreLams ) |
| 47 | 47 | import GHC.Core.DataCon
|
| 48 | 48 | import GHC.Core.TyCon
|
| 49 | 49 | import GHC.Core.Class
|
| 50 | +import GHC.Core.Utils( mkCast )
|
|
| 50 | 51 | |
| 51 | 52 | import GHC.Core ( Expr(..) )
|
| 52 | 53 | |
| ... | ... | @@ -456,7 +457,7 @@ matchWithDict [cls, mty] |
| 456 | 457 | mkCoreLams [ runtimeRep1TyVar, openAlphaTyVar, sv, k ] $
|
| 457 | 458 | Var k
|
| 458 | 459 | `App`
|
| 459 | - (Var sv `Cast` mkTransCo (mkSubCo co2) (mkSymCo co))
|
|
| 460 | + (Var sv `mkCast` mkTransCo (mkSubCo co2) (mkSymCo co))
|
|
| 460 | 461 | |
| 461 | 462 | ; tc <- tcLookupTyCon withDictClassName
|
| 462 | 463 | ; let Just withdict_data_con
|
| ... | ... | @@ -935,7 +936,7 @@ matchDataToTag dataToTagClass [levity, dty] = do |
| 935 | 936 | dataToTagDataCon = tyConSingleDataCon (classTyCon dataToTagClass)
|
| 936 | 937 | mk_ev _ = evDataConApp dataToTagDataCon
|
| 937 | 938 | [levity, dty]
|
| 938 | - [methodRep `Cast` methodCo]
|
|
| 939 | + [methodRep `mkCast` methodCo]
|
|
| 939 | 940 | -> addUsedDataCons rdr_env repTyCon -- See wrinkles DTW2 and DTW3
|
| 940 | 941 | $> OneInst { cir_new_theta = [] -- (Ignore stupid theta.)
|
| 941 | 942 | , cir_mk_ev = mk_ev
|
| ... | ... | @@ -93,7 +93,7 @@ import Control.Monad |
| 93 | 93 | import Control.Monad.Trans.Class ( lift )
|
| 94 | 94 | import Control.Monad.Trans.State.Strict ( StateT(runStateT), put )
|
| 95 | 95 | import Data.Foldable ( toList, traverse_ )
|
| 96 | -import Data.List ( partition, intersect )
|
|
| 96 | +import Data.List ( partition )
|
|
| 97 | 97 | import Data.List.NonEmpty ( NonEmpty(..), nonEmpty )
|
| 98 | 98 | import qualified Data.List.NonEmpty as NE
|
| 99 | 99 | import GHC.Data.Maybe ( isJust, mapMaybe, catMaybes )
|
| ... | ... | @@ -3755,32 +3755,74 @@ Type-class defaulting deals with the situation where we have unsolved |
| 3755 | 3755 | constraints like (Num alpha), where `alpha` is a unification variable. We want
|
| 3756 | 3756 | to pick a default for `alpha`, such as `alpha := Int` to resolve the ambiguity.
|
| 3757 | 3757 | |
| 3758 | -Type-class defaulting is guided by the `DefaultEnv`: see Note [Named default declarations]
|
|
| 3759 | -in GHC.Tc.Gen.Default
|
|
| 3758 | +The function 'tryTypeClassDefaulting' implements type-class defaulting. The
|
|
| 3759 | +algorithm for defaulting depends on whether certain extensions are enabled,
|
|
| 3760 | +such as -XOverloadedStrings or -XExtendedDefaultRules. To explain this, let us
|
|
| 3761 | +define the following:
|
|
| 3760 | 3762 | |
| 3761 | -The entry point for defaulting the unsolved constraints is `applyDefaultingRules`,
|
|
| 3762 | -which depends on `disambigGroup`, which in turn depends on workhorse
|
|
| 3763 | -`disambigProposalSequences`. The latter is also used by defaulting plugins through
|
|
| 3764 | -`disambigMultiGroup` (see Note [Defaulting plugins] below).
|
|
| 3763 | + Unary typeclass:
|
|
| 3764 | + a typeclass with a single visible type argument.
|
|
| 3765 | 3765 | |
| 3766 | -The algorithm works as follows. Let S be the complete set of unsolved
|
|
| 3767 | -constraints, and initialize Sx to an empty set of constraints. For every type
|
|
| 3768 | -variable `v` that is free in S:
|
|
| 3766 | + Examples:
|
|
| 3769 | 3767 | |
| 3770 | -1. Define Cv = { Ci v | Ci v ∈ S }, the subset of S consisting of all constraints in S of
|
|
| 3771 | - form (Ci v), where Ci is a single-parameter type class. (We do no defaulting for
|
|
| 3772 | - multi-parameter type classes.)
|
|
| 3768 | + Num :: Type -> Constraint
|
|
| 3769 | + Eq :: Type -> Constraint
|
|
| 3770 | + Foldable :: (Type -> Type) -> Constraint
|
|
| 3771 | + Typeable :: forall k. k -> Constraint -- NB: also has an /invisible/ argument
|
|
| 3773 | 3772 | |
| 3774 | -2. Define Dv, by extending Cv with the superclasses of every Ci in Cv
|
|
| 3773 | + Non-examples:
|
|
| 3775 | 3774 | |
| 3776 | -3. Define Ev, by filtering Dv to contain only classes with a default declaration.
|
|
| 3775 | + Nullary :: Constraint
|
|
| 3776 | + Binary :: Type -> Type -> Constraint
|
|
| 3777 | + Binary2 :: forall k -> k -> Constraint -- Two visible arguments
|
|
| 3777 | 3778 | |
| 3778 | -4. For each Ci in Ev, if Ci has a non-empty default list in the `DefaultEnv`, find the first
|
|
| 3779 | - type T in the default list for Ci for which, for every (Ci v) in Cv, the constraint (Ci T)
|
|
| 3780 | - is soluble.
|
|
| 3779 | + Defaultable class
|
|
| 3780 | + a typeclass which has at least one in-scope default declaration
|
|
| 3781 | 3781 | |
| 3782 | -5. If there is precisely one type T in the resulting type set, resolve the ambiguity by adding
|
|
| 3783 | - a constraint (v~ Ti) constraint to a set Sx; otherwise report a static error.
|
|
| 3782 | + This includes the two different categories of default declarations:
|
|
| 3783 | + |
|
| 3784 | + - Haskell 98 default declarations such as 'default (Integer, Float)'.
|
|
| 3785 | + |
|
| 3786 | + - `Num` is always defaultable; either the user says 'default( Integer, Float )'
|
|
| 3787 | + or (absent such a declaration) the system fills in a fallback default declaration.
|
|
| 3788 | + See Section 4.3.4 in https://www.haskell.org/onlinereport/haskell2010/haskellch4.html
|
|
| 3789 | + |
|
| 3790 | + - With `OverloadedStrings`, the class `IsString` is defaultable
|
|
| 3791 | + - With `ExtendedDefaultRules`, the classes `Show`, `Eq`, `Ord`, `Foldable` and `Traversable`
|
|
| 3792 | + are defaultable
|
|
| 3793 | + |
|
| 3794 | + - Named default declarations, which apply to the named class, e.g.
|
|
| 3795 | + 'default Cls(X, Y)' applies precisely to 'Cls'.
|
|
| 3796 | + Note that these may be locally defined, or they may be imported.
|
|
| 3797 | + |
|
| 3798 | + Standard class:
|
|
| 3799 | + a class defined in the Prelude or the standard library, as defined
|
|
| 3800 | + by the Haskell 98 report (section 4.3.4)
|
|
| 3801 | + |
|
| 3802 | + These are defined in GHC.Builtin.Names.standardClassKeys.
|
|
| 3803 | + |
|
| 3804 | +The rules for defaulting a collection 'S' of unsolved constraints are as follows:
|
|
| 3805 | + |
|
| 3806 | + 1. For each metavariable 'v' appearing in 'S', define
|
|
| 3807 | + |
|
| 3808 | + U_v = { C v | C v ∈ U, C is a unary typeclass }
|
|
| 3809 | + |
|
| 3810 | + We then process each 'U_v' in turn, in order to find a defaulting
|
|
| 3811 | + assignment 'v := ty' that solves all of 'U_v'.
|
|
| 3812 | + |
|
| 3813 | + 2. Unless -XExtendedDefaultRules is in effect, give up if 'v' appears:
|
|
| 3814 | + |
|
| 3815 | + - in any constraint that isn't a unary class constraint
|
|
| 3816 | + - in a class constraint which is non-standard and does not have
|
|
| 3817 | + a default declaration in scope.
|
|
| 3818 | + |
|
| 3819 | + 3. Compute candidate assignments: for each unary typeclass 'C' in 'U_v' which
|
|
| 3820 | + has a default declaration in scope, find the first type 'ty' in the list
|
|
| 3821 | + of in-scope default types for 'C' for which all of 'U_v' is soluble.
|
|
| 3822 | + |
|
| 3823 | + 4. If there is precisely one type candidate type assignment 'ty' that allows
|
|
| 3824 | + all of 'U_v' to be solved, we default 'v := ty'. Otherwise, do nothing
|
|
| 3825 | + ('v' remains ambiguous).
|
|
| 3784 | 3826 | |
| 3785 | 3827 | Note [Defaulting plugins]
|
| 3786 | 3828 | ~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -3919,8 +3961,8 @@ findDefaultableGroups (default_tys, extended_defaults) wanteds |
| 3919 | 3961 | |
| 3920 | 3962 | -- Finds unary type-class constraints
|
| 3921 | 3963 | -- But take account of polykinded classes like Typeable,
|
| 3922 | - -- which may look like (Typeable * (a:*)) (#8931)
|
|
| 3923 | - -- step (1) in Note [How type-class constraints are defaulted]
|
|
| 3964 | + -- which may look like (Typeable Type (a:Type)) (#8931)
|
|
| 3965 | + -- See step (1) in Note [How type-class constraints are defaulted]
|
|
| 3924 | 3966 | find_unary :: Ct -> Either (Ct, Class, TyVar) Ct
|
| 3925 | 3967 | find_unary cc
|
| 3926 | 3968 | | Just (cls,tys) <- getClassPredTys_maybe (ctPred cc)
|
| ... | ... | @@ -3932,21 +3974,42 @@ findDefaultableGroups (default_tys, extended_defaults) wanteds |
| 3932 | 3974 | = Left (cc, cls, tv)
|
| 3933 | 3975 | find_unary cc = Right cc -- Non unary or non dictionary
|
| 3934 | 3976 | |
| 3935 | - bad_tvs :: TcTyCoVarSet -- TyVars mentioned by non-unaries
|
|
| 3936 | - bad_tvs = mapUnionVarSet tyCoVarsOfCt non_unaries
|
|
| 3977 | + nonunary_tvs :: TcTyCoVarSet -- TyVars mentioned by non-unaries
|
|
| 3978 | + nonunary_tvs = mapUnionVarSet tyCoVarsOfCt non_unaries
|
|
| 3937 | 3979 | |
| 3938 | 3980 | cmp_tv (_,_,tv1) (_,_,tv2) = tv1 `compare` tv2
|
| 3939 | 3981 | |
| 3940 | 3982 | defaultable_tyvar :: TcTyVar -> Bool
|
| 3941 | 3983 | defaultable_tyvar tv
|
| 3942 | 3984 | = let b1 = isTyConableTyVar tv -- Note [Avoiding spurious errors]
|
| 3943 | - b2 = not (tv `elemVarSet` bad_tvs)
|
|
| 3985 | + b2 = not (tv `elemVarSet` nonunary_tvs)
|
|
| 3944 | 3986 | in b1 && (b2 || extended_defaults) -- Note [Multi-parameter defaults]
|
| 3945 | 3987 | |
| 3946 | - -- Determines if any of the given type class constructors is in default_tys
|
|
| 3947 | - -- step (3) in Note [How type-class constraints are defaulted]
|
|
| 3988 | + -- Determines whether the collection of class constraints permits defaulting.
|
|
| 3989 | + -- See step (2) in Note [How type-class constraints are defaulted]
|
|
| 3948 | 3990 | defaultable_classes :: [Class] -> Bool
|
| 3949 | - defaultable_classes clss = not . null . intersect clss $ map cd_class default_tys
|
|
| 3991 | + defaultable_classes clss =
|
|
| 3992 | + -- One of the classes has a default declaration in scope
|
|
| 3993 | + -- (this includes 'Num', and e.g. 'IsString' with -XOverloadedStrings)
|
|
| 3994 | + any (`elementOfUniqSet` classes_with_defaults) clss
|
|
| 3995 | + &&
|
|
| 3996 | + -- AND, either:
|
|
| 3997 | + -- - ExtendedDefaultRules is in effect, or
|
|
| 3998 | + -- - all the classes are standard or have a default declaration in scope
|
|
| 3999 | + (extended_defaults || all is_std_or_has_default clss)
|
|
| 4000 | + is_std_or_has_default :: Class -> Bool
|
|
| 4001 | + is_std_or_has_default cls =
|
|
| 4002 | + (getUnique cls `elem` standardClassKeys)
|
|
| 4003 | + ||
|
|
| 4004 | + (cls `elementOfUniqSet` classes_with_defaults)
|
|
| 4005 | + |
|
| 4006 | + -- All classes with a default declaration in scope; either:
|
|
| 4007 | + --
|
|
| 4008 | + -- - a named default declaration such as 'default C(Double, Bool)', or
|
|
| 4009 | + -- - a Haskell 98 default declaration such as 'default(Int, Float)',
|
|
| 4010 | + -- which adds defaults for Num, for IsString with OverloadedStrings,
|
|
| 4011 | + -- and for Foldable/Traversable/... with ExtendedDefaultRules
|
|
| 4012 | + classes_with_defaults = mkUniqSet $ map cd_class default_tys
|
|
| 3950 | 4013 | |
| 3951 | 4014 | ------------------------------
|
| 3952 | 4015 | |
| ... | ... | @@ -3996,14 +4059,14 @@ disambigProposalSequences orig_wanteds wanteds proposalSequences allConsistent |
| 3996 | 4059 | = do { traverse_ (traverse_ reportInvalidDefaultedTyVars . getProposalSequence) proposalSequences
|
| 3997 | 4060 | ; fake_ev_binds_var <- TcS.newTcEvBinds
|
| 3998 | 4061 | ; tclvl <- TcS.getTcLevel
|
| 3999 | - -- Step (4) in Note [How type-class constraints are defaulted]
|
|
| 4062 | + -- Step (3) in Note [How type-class constraints are defaulted]
|
|
| 4000 | 4063 | ; successes <- fmap catMaybes $
|
| 4001 | 4064 | nestImplicTcS fake_ev_binds_var (pushTcLevel tclvl) $
|
| 4002 | 4065 | mapM firstSuccess proposalSequences
|
| 4003 | 4066 | ; traceTcS "disambigProposalSequences" (vcat [ ppr wanteds
|
| 4004 | 4067 | , ppr proposalSequences
|
| 4005 | 4068 | , ppr successes ])
|
| 4006 | - -- Step (5) in Note [How type-class constraints are defaulted]
|
|
| 4069 | + -- Step (4) in Note [How type-class constraints are defaulted]
|
|
| 4007 | 4070 | ; case successes of
|
| 4008 | 4071 | success@(tvs, subst) : rest
|
| 4009 | 4072 | | allConsistent (success :| rest)
|
| ... | ... | @@ -102,28 +102,53 @@ solveDict dict_ct@(DictCt { di_ev = ev, di_cls = cls, di_tys = tys }) |
| 102 | 102 | ; stopWithStage (dictCtEvidence dict_ct) "Kept inert DictCt" }
|
| 103 | 103 | |
| 104 | 104 | updInertDicts :: DictCt -> TcS ()
|
| 105 | -updInertDicts dict_ct@(DictCt { di_cls = cls, di_ev = ev, di_tys = tys })
|
|
| 106 | - = do { traceTcS "Adding inert dict" (ppr dict_ct $$ ppr cls <+> ppr tys)
|
|
| 107 | - |
|
| 108 | - ; if | isGiven ev, Just (str_ty, _) <- isIPPred_maybe cls tys
|
|
| 109 | - -> -- See (SIP1) and (SIP2) in Note [Shadowing of implicit parameters]
|
|
| 110 | - -- Update /both/ inert_cans /and/ inert_solved_dicts.
|
|
| 111 | - updInertSet $ \ inerts@(IS { inert_cans = ics, inert_solved_dicts = solved }) ->
|
|
| 112 | - inerts { inert_cans = updDicts (filterDicts (does_not_mention_ip_for str_ty)) ics
|
|
| 113 | - , inert_solved_dicts = filterDicts (does_not_mention_ip_for str_ty) solved }
|
|
| 114 | - | otherwise
|
|
| 115 | - -> return ()
|
|
| 105 | +updInertDicts dict_ct
|
|
| 106 | + = do { traceTcS "Adding inert dict" (ppr dict_ct)
|
|
| 107 | + |
|
| 108 | + -- For Given implicit parameters (only), delete any existing
|
|
| 109 | + -- Givens for the same implicit parameter.
|
|
| 110 | + -- See Note [Shadowing of implicit parameters]
|
|
| 111 | + ; deleteGivenIPs dict_ct
|
|
| 116 | 112 | |
| 117 | 113 | -- Add the new constraint to the inert set
|
| 118 | 114 | ; updInertCans (updDicts (addDict dict_ct)) }
|
| 115 | + |
|
| 116 | +deleteGivenIPs :: DictCt -> TcS ()
|
|
| 117 | +-- Special magic when adding a Given implicit parameter to the inert set
|
|
| 118 | +-- For [G] ?x::ty, remove any existing /Givens/ mentioning ?x,
|
|
| 119 | +-- from /both/ inert_cans /and/ inert_solved_dicts (#23761)
|
|
| 120 | +-- See Note [Shadowing of implicit parameters]
|
|
| 121 | +deleteGivenIPs (DictCt { di_cls = cls, di_ev = ev, di_tys = tys })
|
|
| 122 | + | isGiven ev
|
|
| 123 | + , Just (str_ty, _) <- isIPPred_maybe cls tys
|
|
| 124 | + = updInertSet $ \ inerts@(IS { inert_cans = ics, inert_solved_dicts = solved }) ->
|
|
| 125 | + inerts { inert_cans = updDicts (filterDicts (keep_can str_ty)) ics
|
|
| 126 | + , inert_solved_dicts = filterDicts (keep_solved str_ty) solved }
|
|
| 127 | + | otherwise
|
|
| 128 | + = return ()
|
|
| 119 | 129 | where
|
| 120 | - -- Does this class constraint or any of its superclasses mention
|
|
| 121 | - -- an implicit parameter (?str :: ty) for the given 'str' and any type 'ty'?
|
|
| 122 | - does_not_mention_ip_for :: Type -> DictCt -> Bool
|
|
| 123 | - does_not_mention_ip_for str_ty (DictCt { di_cls = cls, di_tys = tys })
|
|
| 124 | - = not $ mentionsIP (not . typesAreApart str_ty) (const True) cls tys
|
|
| 125 | - -- See Note [Using typesAreApart when calling mentionsIP]
|
|
| 126 | - -- in GHC.Core.Predicate
|
|
| 130 | + keep_can, keep_solved :: Type -> DictCt -> Bool
|
|
| 131 | + -- keep_can: we keep an inert dictionary UNLESS
|
|
| 132 | + -- (1) it is a Given
|
|
| 133 | + -- (2) it binds an implicit parameter (?str :: ty) for the given 'str'
|
|
| 134 | + -- regardless of 'ty', possibly via its superclasses
|
|
| 135 | + -- The test is a bit conservative, hence `mentionsIP` and `typesAreApart`
|
|
| 136 | + -- See Note [Using typesAreApart when calling mentionsIP]
|
|
| 137 | + -- in GHC.Core.Predicate
|
|
| 138 | + --
|
|
| 139 | + -- keep_solved: same as keep_can, but for /all/ constraints not just Givens
|
|
| 140 | + --
|
|
| 141 | + -- Why two functions? See (SIP3) in Note [Shadowing of implicit parameters]
|
|
| 142 | + keep_can str (DictCt { di_ev = ev, di_cls = cls, di_tys = tys })
|
|
| 143 | + = not (isGiven ev -- (1)
|
|
| 144 | + && mentions_ip str cls tys) -- (2)
|
|
| 145 | + keep_solved str (DictCt { di_cls = cls, di_tys = tys })
|
|
| 146 | + = not (mentions_ip str cls tys)
|
|
| 147 | + |
|
| 148 | + -- mentions_ip: the inert constraint might provide evidence
|
|
| 149 | + -- for an implicit parameter (?str :: ty) for the given 'str'
|
|
| 150 | + mentions_ip str cls tys
|
|
| 151 | + = mentionsIP (not . typesAreApart str) (const True) cls tys
|
|
| 127 | 152 | |
| 128 | 153 | canDictCt :: CtEvidence -> Class -> [Type] -> SolverStage DictCt
|
| 129 | 154 | -- Once-only processing of Dict constraints:
|
| ... | ... | @@ -220,7 +245,9 @@ in two places: |
| 220 | 245 | * In `updInertDicts`, in this module, when adding [G] (?x :: ty), remove any
|
| 221 | 246 | existing [G] (?x :: ty'), regardless of ty'.
|
| 222 | 247 | |
| 223 | -* Wrinkle (SIP1): we must be careful of superclasses. Consider
|
|
| 248 | +There are wrinkles:
|
|
| 249 | + |
|
| 250 | +* Wrinkle (SIP1): we must be careful of superclasses (#14218). Consider
|
|
| 224 | 251 | f,g :: (?x::Int, C a) => a -> a
|
| 225 | 252 | f v = let ?x = 4 in g v
|
| 226 | 253 | |
| ... | ... | @@ -228,24 +255,31 @@ in two places: |
| 228 | 255 | We must /not/ solve this from the Given (?x::Int, C a), because of
|
| 229 | 256 | the intervening binding for (?x::Int). #14218.
|
| 230 | 257 | |
| 231 | - We deal with this by arranging that when we add [G] (?x::ty) we delete
|
|
| 258 | + We deal with this by arranging that when we add [G] (?x::ty) we /delete/
|
|
| 232 | 259 | * from the inert_cans, and
|
| 233 | 260 | * from the inert_solved_dicts
|
| 234 | 261 | any existing [G] (?x::ty) /and/ any [G] D tys, where (D tys) has a superclass
|
| 235 | 262 | with (?x::ty). See Note [Local implicit parameters] in GHC.Core.Predicate.
|
| 236 | 263 | |
| 237 | - An important special case is constraint tuples like [G] (% ?x::ty, Eq a %).
|
|
| 238 | - But it could happen for `class xx => D xx where ...` and the constraint D
|
|
| 239 | - (?x :: int). This corner (constraint-kinded variables instantiated with
|
|
| 240 | - implicit parameter constraints) is not well explored.
|
|
| 264 | + An very important special case is constraint tuples like [G] (% ?x::ty, Eq a %).
|
|
| 265 | + |
|
| 266 | + But it could also happen for `class xx => D xx where ...` and the constraint
|
|
| 267 | + D (?x :: int); again see Note [Local implicit parameters]. This corner
|
|
| 268 | + (constraint-kinded variables instantiated with implicit parameter constraints)
|
|
| 269 | + is not well explored.
|
|
| 241 | 270 | |
| 242 | - Example in #14218, and #23761
|
|
| 271 | + You might worry about whether deleting an /entire/ constraint just because
|
|
| 272 | + a distant superclass has an implicit parameter might make another Wanted for
|
|
| 273 | + that constraint un-solvable. Indeed so. But for constraint tuples it doesn't
|
|
| 274 | + matter -- their entire payload is their superclasses. And the other case is
|
|
| 275 | + the ill-explored corner above.
|
|
| 243 | 276 | |
| 244 | 277 | The code that accounts for (SIP1) is in updInertDicts; in particular the call to
|
| 245 | 278 | GHC.Core.Predicate.mentionsIP.
|
| 246 | 279 | |
| 247 | 280 | * Wrinkle (SIP2): we must apply this update semantics for `inert_solved_dicts`
|
| 248 | - as well as `inert_cans`.
|
|
| 281 | + as well as `inert_cans` (#23761).
|
|
| 282 | + |
|
| 249 | 283 | You might think that wouldn't be necessary, because an element of
|
| 250 | 284 | `inert_solved_dicts` is never an implicit parameter (see
|
| 251 | 285 | Note [Solved dictionaries] in GHC.Tc.Solver.InertSet).
|
| ... | ... | @@ -258,6 +292,19 @@ in two places: |
| 258 | 292 | Now (C (?x::Int)) has a superclass (?x::Int). This may look exotic, but it
|
| 259 | 293 | happens particularly for constraint tuples, like `(% ?x::Int, Eq a %)`.
|
| 260 | 294 | |
| 295 | +* Wrinkle (SIP3)
|
|
| 296 | + - Note that for the inert dictionaries, `inert_cans`, we must /only/ delete
|
|
| 297 | + existing /Givens/! Deleting an existing Wanted led to #26451; we just never
|
|
| 298 | + solved it!
|
|
| 299 | + |
|
| 300 | + - In contrast, the solved dictionaries, `inert_solved_dicts`, are really like
|
|
| 301 | + Givens; they may be "inherited" from outer scopes, so we must delete any
|
|
| 302 | + solved dictionaries for this implicit parameter for /both/ Givens /and/
|
|
| 303 | + Wanteds.
|
|
| 304 | + |
|
| 305 | + Otherwise the new Given doesn't properly shadow those inherited solved
|
|
| 306 | + dictionaries. Test T23761 showed this up.
|
|
| 307 | + |
|
| 261 | 308 | Example 1:
|
| 262 | 309 | |
| 263 | 310 | Suppose we have (typecheck/should_compile/ImplicitParamFDs)
|
| ... | ... | @@ -56,6 +56,7 @@ import GHC.Types.Var |
| 56 | 56 | import GHC.Types.Id( idScaledType )
|
| 57 | 57 | import GHC.Core.Coercion.Axiom
|
| 58 | 58 | import GHC.Core.Coercion
|
| 59 | +import GHC.Core.Utils( mkCast )
|
|
| 59 | 60 | import GHC.Core.Ppr () -- Instance OutputableBndr TyVar
|
| 60 | 61 | import GHC.Tc.Utils.TcType
|
| 61 | 62 | import GHC.Core.Type
|
| ... | ... | @@ -528,7 +529,7 @@ evCoercion co = EvExpr (Coercion co) |
| 528 | 529 | -- | d |> co
|
| 529 | 530 | evCast :: EvExpr -> TcCoercion -> EvTerm
|
| 530 | 531 | evCast et tc | isReflCo tc = EvExpr et
|
| 531 | - | otherwise = EvExpr (Cast et tc)
|
|
| 532 | + | otherwise = EvExpr (mkCast et tc)
|
|
| 532 | 533 | |
| 533 | 534 | -- Dictionary instance application
|
| 534 | 535 | evDFunApp :: DFunId -> [Type] -> [EvExpr] -> EvTerm
|
| ... | ... | @@ -31,9 +31,13 @@ import Data.List (sortBy) |
| 31 | 31 | import Data.Function (on)
|
| 32 | 32 | |
| 33 | 33 | -- See Note [Named default declarations] in GHC.Tc.Gen.Default
|
| 34 | + |
|
| 34 | 35 | -- | Default environment mapping class name @Name@ to their default type lists
|
| 36 | +--
|
|
| 37 | +-- NB: this includes Haskell98 default declarations, at the 'Num' key.
|
|
| 35 | 38 | type DefaultEnv = NameEnv ClassDefaults
|
| 36 | 39 | |
| 40 | +-- | Defaulting type assignments for the given class.
|
|
| 37 | 41 | data ClassDefaults
|
| 38 | 42 | = ClassDefaults { cd_class :: Class -- ^ The class whose defaults are being defined
|
| 39 | 43 | , cd_types :: [Type]
|
| 1 | +.. _release-9-12-4:
|
|
| 2 | + |
|
| 3 | +Version 9.12.4
|
|
| 4 | +==============
|
|
| 5 | + |
|
| 6 | +The significant changes to the various parts of the compiler are listed in the
|
|
| 7 | +following sections. See the `migration guide
|
|
| 8 | +<https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.12>`_ on the GHC Wiki
|
|
| 9 | +for specific guidance on migrating programs to this release.
|
|
| 10 | + |
|
| 11 | +Compiler
|
|
| 12 | +~~~~~~~~
|
|
| 13 | + |
|
| 14 | +- Fixed a bug in CSE where the in-scope set was not properly maintained (:ghc-ticket:`25468`)
|
|
| 15 | +- Fixed ``matchExpectedFunTys`` to use ``tcMkScaledFunTys`` (:ghc-ticket:`26277`)
|
|
| 16 | +- Fixed ``parenBreakableList`` usage in ``ppHsContext`` for better pretty-printing of contexts
|
|
| 17 | +- Improved error messages for bad record updates to allow out-of-scope data constructors (:ghc-ticket:`26391`)
|
|
| 18 | +- Fixed a missing InVar->OutVar lookup in ``SetLevels`` (:ghc-ticket:`26681`)
|
|
| 19 | +- Fixed split sections on Windows (:ghc-ticket:`26696`, :ghc-ticket:`26494`)
|
|
| 20 | +- Fixed split sections for the LLVM backend (:ghc-ticket:`26770`)
|
|
| 21 | +- Don't re-use stack slots for growing registers (:ghc-ticket:`26668`)
|
|
| 22 | +- Fixed cast worker/wrapper incorrectly firing on INLINE functions (:ghc-ticket:`26903`)
|
|
| 23 | +- Fixed non-determinism in ``TyLitMap`` by using deterministic maps for strings (:ghc-ticket:`26846`)
|
|
| 24 | +- Fixed non-determinism in ``WithHsDocIdentifiers`` binary instance by using a stable sort (:ghc-ticket:`26858`)
|
|
| 25 | +- Added ``-mcmodel=medium`` module flag to generated LLVM IR on LoongArch
|
|
| 26 | +- Pass the ``mcmodel=medium`` parameter to CC via GHC on LoongArch
|
|
| 27 | +- Pass the ``+evex512`` attribute to LLVM 18+ when ``-mavx512f`` is set (:ghc-ticket:`26410`)
|
|
| 28 | +- Improved error handling in ``getPackageArchives`` (:ghc-ticket:`26383`)
|
|
| 29 | +- Fixed a shadowing bug in implicit parameters (:ghc-ticket:`26451`)
|
|
| 30 | +- Fixed a subtle bug in ``GHC.Core.Utils.mkTick`` that could generate type-incorrect code (:ghc-ticket:`26772`)
|
|
| 31 | +- Fixed a long-standing interaction between ticks and casts in ``Eliminate Identity Cases``
|
|
| 32 | +- ``NamedDefaults``: require the class to be standard or have an in-scope default declaration (:ghc-ticket:`25775`, :ghc-ticket:`25778`)
|
|
| 33 | + |
|
| 34 | +Runtime System
|
|
| 35 | +~~~~~~~~~~~~~~
|
|
| 36 | + |
|
| 37 | +- Fixed a deadlock with eventlog flush interval and RTS shutdown (:ghc-ticket:`26573`)
|
|
| 38 | +- Fixed eager black holes: record mutated closure and fix assertion (:ghc-ticket:`26495`)
|
|
| 39 | +- Fixed object file format detection in ``loadArchive`` (:ghc-ticket:`26630`)
|
|
| 40 | +- Use ``INFO_TABLE_CONSTR`` for ``stg_dummy_ret_closure`` (:ghc-ticket:`26745`)
|
|
| 41 | +- Fixed lost wakeups in ``threadPaused`` for threads blocked on black holes (:ghc-ticket:`26324`)
|
|
| 42 | +- Fixed ``stg_AP_STACK`` to push the correct update frame (:ghc-ticket:`26324`)
|
|
| 43 | +- Fixed potential loop in heap reservation logic on certain kernels (:ghc-ticket:`26151`)
|
|
| 44 | +- Don't use CAS without ``PARALLEL_GC`` on
|
|
| 45 | +- Switch prim to use modern atomic compiler builtins (:ghc-ticket:`26729`)
|
|
| 46 | +- Removed obsolete ``CC_SUPPORTS_TLS``, ``HAS_VISIBILITY_HIDDEN``, ``COMPILING_WINDOWS_DLL``,
|
|
| 47 | + and ``__GNUC__``-related logic
|
|
| 48 | +- Removed the ``-O3`` pragma hack in ``Hash.c``
|
|
| 49 | +- Removed unnecessary Cabal flags
|
|
| 50 | + |
|
| 51 | +Code Generation
|
|
| 52 | +~~~~~~~~~~~~~~~
|
|
| 53 | + |
|
| 54 | +- NCG for PPC: add pattern for ``CmmRegOff`` to ``iselExpr64`` (:ghc-ticket:`26828`)
|
|
| 55 | +- PPC NCG: Use libcall for 64-bit ``cmpxchg`` on 32-bit PowerPC (:ghc-ticket:`23969`)
|
|
| 56 | + |
|
| 57 | +Bytecode Compiler
|
|
| 58 | +~~~~~~~~~~~~~~~~~
|
|
| 59 | + |
|
| 60 | +- Use 32 bits for breakpoint index (:ghc-ticket:`26325`)
|
|
| 61 | + |
|
| 62 | +``base`` library
|
|
| 63 | +~~~~~~~~~~~~~~~~
|
|
| 64 | + |
|
| 65 | +- Expose ``Backtraces`` constructor and fields (:ghc-ticket:`26049`)
|
|
| 66 | +- Store ``StackTrace`` and ``StackSnapshot`` in ``Backtraces``, deferring decoding until display
|
|
| 67 | +- Evaluate backtraces for ``error`` exceptions at the moment they are thrown
|
|
| 68 | + (`CLC proposal #383 <https://github.com/haskell/core-libraries-committee/issues/383>`__,
|
|
| 69 | + :ghc-ticket:`26751`)
|
|
| 70 | + |
|
| 71 | +``ghc-experimental`` library
|
|
| 72 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 73 | + |
|
| 74 | +- Fixed ``GHC.Exception.Backtrace.Experimental`` module
|
|
| 75 | +- Added ability to customise the collection of exception annotations
|
|
| 76 | + |
|
| 77 | +``ghc-pkg``
|
|
| 78 | +~~~~~~~~~~~~
|
|
| 79 | + |
|
| 80 | +- Removed ``traceId`` from ``ghc-pkg`` executable
|
|
| 81 | + |
|
| 82 | +``ghc-toolchain``
|
|
| 83 | +~~~~~~~~~~~~~~~~~
|
|
| 84 | + |
|
| 85 | +- Dropped ``ld.gold`` from merge object command
|
|
| 86 | + |
|
| 87 | +Build System
|
|
| 88 | +~~~~~~~~~~~~
|
|
| 89 | + |
|
| 90 | +- Added ``hpc`` to release script
|
|
| 91 | +- Use a response file to invoke GHC when analysing dependencies
|
|
| 92 | +- Fixed ``GHC.Platform.Host`` generation for cross stage1 (:ghc-ticket:`26449`)
|
|
| 93 | +- Fixed runtime error during ``users_guide`` build with Sphinx 9.1.0 (:ghc-ticket:`26810`)
|
|
| 94 | +- Added ``ghc-{experimental,internal}.cabal`` to the list of dependencies of the doc target (:ghc-ticket:`26738`)
|
|
| 95 | + |
|
| 96 | +Wasm Backend
|
|
| 97 | +~~~~~~~~~~~~
|
|
| 98 | + |
|
| 99 | +- Fixed dyld handling for forward declared ``GOT.func`` items (:ghc-ticket:`26430`)
|
|
| 100 | +- Ensure ``setKeepCAFs()`` is called in GHCi (:ghc-ticket:`26106`)
|
|
| 101 | +- Prevent bundlers from resolving ``import("node:timers")``
|
|
| 102 | +- Use ``import.meta.main`` for proper distinction of Node.js main modules (:ghc-ticket:`26916`)
|
|
| 103 | + |
|
| 104 | +Included libraries
|
|
| 105 | +~~~~~~~~~~~~~~~~~~
|
|
| 106 | + |
|
| 107 | +The package database provided with this distribution also contains a number of
|
|
| 108 | +packages other than GHC itself. See the changelogs provided with these packages
|
|
| 109 | +for further change information.
|
|
| 110 | + |
|
| 111 | +.. ghc-package-list::
|
|
| 112 | + |
|
| 113 | + compiler/ghc.cabal: The compiler itself
|
|
| 114 | + libraries/array/array.cabal: Dependency of ``ghc`` library
|
|
| 115 | + libraries/base/base.cabal: Core library
|
|
| 116 | + libraries/binary/binary.cabal: Dependency of ``ghc`` library
|
|
| 117 | + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library
|
|
| 118 | + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility
|
|
| 119 | + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility
|
|
| 120 | + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library
|
|
| 121 | + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library
|
|
| 122 | + libraries/directory/directory.cabal: Dependency of ``ghc`` library
|
|
| 123 | + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library
|
|
| 124 | + libraries/file-io/file-io.cabal: Dependency of ``directory`` library
|
|
| 125 | + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library
|
|
| 126 | + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library
|
|
| 127 | + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library
|
|
| 128 | + libraries/ghc-compact/ghc-compact.cabal: Core library
|
|
| 129 | + libraries/ghc-experimental/ghc-experimental.cabal: Core library
|
|
| 130 | + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library
|
|
| 131 | + libraries/ghci/ghci.cabal: The REPL interface
|
|
| 132 | + libraries/ghc-internal/ghc-internal.cabal: Core library
|
|
| 133 | + libraries/ghc-platform/ghc-platform.cabal: Internal library
|
|
| 134 | + libraries/ghc-prim/ghc-prim.cabal: Core library
|
|
| 135 | + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable
|
|
| 136 | + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable
|
|
| 137 | + libraries/integer-gmp/integer-gmp.cabal: Core library
|
|
| 138 | + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library
|
|
| 139 | + libraries/os-string/os-string.cabal: Dependency of ``filepath`` library
|
|
| 140 | + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library
|
|
| 141 | + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library
|
|
| 142 | + libraries/process/process.cabal: Dependency of ``ghc`` library
|
|
| 143 | + libraries/semaphore-compat/semaphore-compat.cabal: Dependency of ``ghc`` library
|
|
| 144 | + libraries/stm/stm.cabal: Dependency of ``haskeline`` library
|
|
| 145 | + libraries/template-haskell/template-haskell.cabal: Core library
|
|
| 146 | + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library
|
|
| 147 | + libraries/text/text.cabal: Dependency of ``Cabal`` library
|
|
| 148 | + libraries/time/time.cabal: Dependency of ``ghc`` library
|
|
| 149 | + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library
|
|
| 150 | + libraries/unix/unix.cabal: Dependency of ``ghc`` library
|
|
| 151 | + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library
|
|
| 152 | + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable
|
|
| 153 | + utils/haddock/haddock-api/haddock-api.cabal: Dependency of ``haddock`` executable
|
|
| 154 | + utils/haddock/haddock-library/haddock-library.cabal: Dependency of ``haddock`` executable |
| ... | ... | @@ -7,3 +7,4 @@ Release notes |
| 7 | 7 | 9.12.1-notes
|
| 8 | 8 | 9.12.2-notes
|
| 9 | 9 | 9.12.3-notes
|
| 10 | + 9.12.4-notes |
| ... | ... | @@ -4,7 +4,7 @@ cabal-version: 3.0 |
| 4 | 4 | -- Make sure you are editing ghc-experimental.cabal.in, not ghc-experimental.cabal
|
| 5 | 5 | |
| 6 | 6 | name: base
|
| 7 | -version: 4.21.1.0
|
|
| 7 | +version: 4.21.2.0
|
|
| 8 | 8 | -- NOTE: Don't forget to update ./changelog.md
|
| 9 | 9 | |
| 10 | 10 | license: BSD-3-Clause
|
| 1 | 1 | # Changelog for [`base` package](http://hackage.haskell.org/package/base)
|
| 2 | 2 | |
| 3 | -## 4.21.2.0 *TBA*
|
|
| 4 | - * Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
|
|
| 3 | +## 4.21.2.0 *March 2026*
|
|
| 4 | + * Expose `Backtraces` constructor and fields ([CLC proposal #199](https://github.com/haskell/core-libraries-committee/issues/199), [#26049](https://gitlab.haskell.org/ghc/ghc/-/issues/26049))
|
|
| 5 | + * Store `StackTrace` and `StackSnapshot` in `Backtraces`, deferring decoding until display
|
|
| 6 | + * Evaluate backtraces for "error" exceptions at the moment they are thrown ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383), [#26751](https://gitlab.haskell.org/ghc/ghc/-/issues/26751))
|
|
| 5 | 7 | |
| 6 | 8 | ## 4.21.1.0 *Sept 2024*
|
| 7 | 9 | * Fix incorrect results of `integerPowMod` when the base is 0 and the exponent is negative, and `integerRecipMod` when the modulus is zero ([#26017](https://gitlab.haskell.org/ghc/ghc/-/issues/26017)).
|
| ... | ... | @@ -87,12 +87,12 @@ disInstr ( StgBCO *bco, int pc ) |
| 87 | 87 | case bci_BRK_FUN:
|
| 88 | 88 | debugBelch ("BRK_FUN " ); printPtr( ptrs[instrs[pc]] );
|
| 89 | 89 | debugBelch (" %d ", instrs[pc+1]); printPtr( ptrs[instrs[pc+2]] );
|
| 90 | - CostCentre* cc = (CostCentre*)literals[instrs[pc+5]];
|
|
| 90 | + CostCentre* cc = (CostCentre*)literals[instrs[pc+7]];
|
|
| 91 | 91 | if (cc) {
|
| 92 | 92 | debugBelch(" %s", cc->label);
|
| 93 | 93 | }
|
| 94 | 94 | debugBelch("\n");
|
| 95 | - pc += 6;
|
|
| 95 | + pc += 8;
|
|
| 96 | 96 | break;
|
| 97 | 97 | case bci_SWIZZLE: {
|
| 98 | 98 | W_ stkoff = BCO_GET_LARGE_ARG;
|
| ... | ... | @@ -1286,8 +1286,8 @@ run_BCO: |
| 1286 | 1286 | arg1_brk_array = BCO_GET_LARGE_ARG;
|
| 1287 | 1287 | arg2_tick_mod = BCO_GET_LARGE_ARG;
|
| 1288 | 1288 | arg3_info_mod = BCO_GET_LARGE_ARG;
|
| 1289 | - arg4_tick_index = BCO_NEXT;
|
|
| 1290 | - arg5_info_index = BCO_NEXT;
|
|
| 1289 | + arg4_tick_index = BCO_READ_NEXT_32;
|
|
| 1290 | + arg5_info_index = BCO_READ_NEXT_32;
|
|
| 1291 | 1291 | #if defined(PROFILING)
|
| 1292 | 1292 | arg6_cc = BCO_GET_LARGE_ARG;
|
| 1293 | 1293 | #else
|
| 1 | + |
|
| 2 | + |
|
| 3 | +module T25775 where
|
|
| 4 | + |
|
| 5 | +import Data.Kind
|
|
| 6 | + |
|
| 7 | +default (Int)
|
|
| 8 | + |
|
| 9 | +type NonStd :: Type -> Constraint
|
|
| 10 | +class NonStd a where
|
|
| 11 | + |
|
| 12 | +f :: (Num a, NonStd a) => a -> a
|
|
| 13 | +f = (+1)
|
|
| 14 | + |
|
| 15 | +x :: String
|
|
| 16 | +x = show (f 0)
|
|
| 17 | + -- We should NOT default 0 to type Int, despite the top-level default
|
|
| 18 | + -- declaration in this module, because of the presence of the
|
|
| 19 | + -- non-standard class 'NonStd'. |
| 1 | +T25775.hs:16:5: error: [GHC-39999]
|
|
| 2 | + • Ambiguous type variable ‘a0’ arising from a use of ‘show’
|
|
| 3 | + prevents the constraint ‘(Show a0)’ from being solved.
|
|
| 4 | + Probable fix: use a type annotation to specify what ‘a0’ should be.
|
|
| 5 | + Potentially matching instances:
|
|
| 6 | + instance Show Ordering -- Defined in ‘GHC.Internal.Show’
|
|
| 7 | + instance Show Integer -- Defined in ‘GHC.Internal.Show’
|
|
| 8 | + ...plus 25 others
|
|
| 9 | + ...plus 13 instances involving out-of-scope types
|
|
| 10 | + (use -fprint-potential-instances to see them all)
|
|
| 11 | + • In the expression: show (f 0)
|
|
| 12 | + In an equation for ‘x’: x = show (f 0)
|
|
| 13 | + |
|
| 14 | +T25775.hs:16:11: error: [GHC-39999]
|
|
| 15 | + • No instance for ‘NonStd a0’ arising from a use of ‘f’
|
|
| 16 | + • In the first argument of ‘show’, namely ‘(f 0)’
|
|
| 17 | + In the expression: show (f 0)
|
|
| 18 | + In an equation for ‘x’: x = show (f 0)
|
|
| 19 | + |
| ... | ... | @@ -30,6 +30,7 @@ test('default-fail05', normal, compile_fail, ['']) |
| 30 | 30 | test('default-fail06', normal, compile_fail, [''])
|
| 31 | 31 | test('default-fail07', normal, compile_fail, [''])
|
| 32 | 32 | test('default-fail08', normal, compile_fail, [''])
|
| 33 | +test('T25775', normal, compile_fail, [''])
|
|
| 33 | 34 | test('T25206', [extra_files(['T25206_helper.hs'])], multimod_compile, ['T25206', ''])
|
| 34 | 35 | test('T25858', normal, compile_and_run, [''])
|
| 35 | 36 | test('T25858v1', [extra_files(['T25858v1_helper.hs'])], multimod_compile_and_run, ['T25858v1', ''])
|
| 1 | +{-# LANGUAGE ImplicitParams, TypeFamilies, FunctionalDependencies, ScopedTypeVariables #-}
|
|
| 2 | + |
|
| 3 | +module T26451 where
|
|
| 4 | + |
|
| 5 | +type family F a
|
|
| 6 | +type instance F Bool = [Char]
|
|
| 7 | + |
|
| 8 | +class C a b | b -> a
|
|
| 9 | +instance C Bool Bool
|
|
| 10 | +instance C Char Char
|
|
| 11 | + |
|
| 12 | +eq :: forall a b. C a b => a -> b -> ()
|
|
| 13 | +eq p q = ()
|
|
| 14 | + |
|
| 15 | +g :: a -> F a
|
|
| 16 | +g = g
|
|
| 17 | + |
|
| 18 | +f (x::tx) (y::ty) -- x :: alpha y :: beta
|
|
| 19 | + = let ?v = g x -- ?ip :: F alpha
|
|
| 20 | + in (?v::[ty], eq x True)
|
|
| 21 | + |
|
| 22 | + |
|
| 23 | +{- tx, and ty are unification variables
|
|
| 24 | + |
|
| 25 | +Inert: [G] dg :: IP "v" (F tx)
|
|
| 26 | + [W] dw :: IP "v" [ty]
|
|
| 27 | +Work-list: [W] dc1 :: C tx Bool
|
|
| 28 | + [W] dc2 :: C ty Char
|
|
| 29 | + |
|
| 30 | +* Solve dc1, we get tx := Bool from fundep
|
|
| 31 | +* Kick out dg
|
|
| 32 | +* Solve dg to get [G] dc : IP "v" [Char]
|
|
| 33 | +* Add that new dg to the inert set: that simply deletes dw!!!
|
|
| 34 | +-} |
| ... | ... | @@ -938,3 +938,4 @@ test('T23501b', normal, compile, ['']) |
| 938 | 938 | test('T25597', normal, compile, [''])
|
| 939 | 939 | test('T25960', normal, compile, [''])
|
| 940 | 940 | test('T26256a', normal, compile, [''])
|
| 941 | +test('T26451', normal, compile, ['']) |
| 1 | +T12921.hs:4:1: error: [GHC-39999]
|
|
| 2 | + • Ambiguous type variable ‘a0’ arising from an annotation
|
|
| 3 | + prevents the constraint ‘(GHC.Internal.Data.Data.Data
|
|
| 4 | + a0)’ from being solved.
|
|
| 5 | + Probable fix: use a type annotation to specify what ‘a0’ should be.
|
|
| 6 | + Potentially matching instances:
|
|
| 7 | + instance (GHC.Internal.Data.Data.Data a,
|
|
| 8 | + GHC.Internal.Data.Data.Data b) =>
|
|
| 9 | + GHC.Internal.Data.Data.Data (Either a b)
|
|
| 10 | + -- Defined in ‘GHC.Internal.Data.Data’
|
|
| 11 | + instance GHC.Internal.Data.Data.Data Ordering
|
|
| 12 | + -- Defined in ‘GHC.Internal.Data.Data’
|
|
| 13 | + ...plus 17 others
|
|
| 14 | + ...plus 49 instances involving out-of-scope types
|
|
| 15 | + (use -fprint-potential-instances to see them all)
|
|
| 16 | + • In the annotation:
|
|
| 17 | + {-# ANN module "HLint: ignore Reduce duplication" #-}
|
|
| 18 | + |
|
| 19 | +T12921.hs:4:16: error: [GHC-39999]
|
|
| 20 | + • Ambiguous type variable ‘a0’ arising from the literal ‘"HLint: ignore Reduce duplication"’
|
|
| 21 | + prevents the constraint ‘(GHC.Internal.Data.String.IsString
|
|
| 22 | + a0)’ from being solved.
|
|
| 23 | + Probable fix: use a type annotation to specify what ‘a0’ should be.
|
|
| 24 | + Potentially matching instance:
|
|
| 25 | + instance (a ~ Char) => GHC.Internal.Data.String.IsString [a]
|
|
| 26 | + -- Defined in ‘GHC.Internal.Data.String’
|
|
| 27 | + ...plus two instances involving out-of-scope types
|
|
| 28 | + (use -fprint-potential-instances to see them all)
|
|
| 29 | + • In the annotation:
|
|
| 30 | + {-# ANN module "HLint: ignore Reduce duplication" #-}
|
|
| 1 | 31 | |
| 2 | 32 | T12921.hs:7:8: error: [GHC-88464]
|
| 3 | 33 | Variable not in scope: choice :: [a0] -> Int -> Int
|
| 34 | + |