Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
-
d8f1c49d
by Simon Peyton Jones at 2025-10-21T17:00:59+01:00
-
c3413786
by Simon Peyton Jones at 2025-10-21T17:00:59+01:00
-
23988363
by Simon Peyton Jones at 2025-10-21T17:00:59+01:00
-
5f0af575
by Simon Peyton Jones at 2025-10-21T17:00:59+01:00
9 changed files:
- compiler/GHC/Core/Opt/CallArity.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Types/Unique/DSM.hs
- + compiler/GHC/Utils/EndoOS.hs
- compiler/ghc.cabal.in
Changes:
| ... | ... | @@ -598,9 +598,8 @@ callArityBind boring_vars ae_body int (NonRec v rhs) |
| 598 | 598 | |
| 599 | 599 | -- Recursive let. See Note [Recursion and fixpointing]
|
| 600 | 600 | callArityBind boring_vars ae_body int b@(Rec binds)
|
| 601 | - = -- (if length binds > 300 then
|
|
| 602 | - -- pprTrace "callArityBind:Rec"
|
|
| 603 | - -- (vcat [ppr (Rec binds'), ppr ae_body, ppr int, ppr ae_rhs]) else id) $
|
|
| 601 | + = -- pprTrace "callArityBind:Rec"
|
|
| 602 | + -- (vcat [ppr (map fst binds), ppr ae_body, ppr int, ppr ae_rhs]) $
|
|
| 604 | 603 | (final_ae, Rec binds')
|
| 605 | 604 | where
|
| 606 | 605 | -- See Note [Taking boring variables into account]
|
| ... | ... | @@ -614,7 +613,9 @@ callArityBind boring_vars ae_body int b@(Rec binds) |
| 614 | 613 | |
| 615 | 614 | fix :: [(Id, Maybe (Bool, Arity, CallArityRes), CoreExpr)] -> (CallArityRes, [(Id, CoreExpr)])
|
| 616 | 615 | fix ann_binds
|
| 617 | - | -- pprTrace "callArityBind:fix" (vcat [ppr ann_binds, ppr any_change, ppr ae]) $
|
|
| 616 | + | -- pprTrace "callArityBind:fix" (vcat
|
|
| 617 | + -- [ text "binds" <+> vcat [ppr (id,stuff) | (id,stuff,_rhs) <- ann_binds]
|
|
| 618 | + -- , ppr any_change, ppr ae]) $
|
|
| 618 | 619 | any_change
|
| 619 | 620 | = fix ann_binds'
|
| 620 | 621 | | otherwise
|
| ... | ... | @@ -650,7 +651,12 @@ callArityBind boring_vars ae_body int b@(Rec binds) |
| 650 | 651 | | safe_arity == 0 = ae_rhs -- If it is not a function, its body is evaluated only once
|
| 651 | 652 | | otherwise = calledMultipleTimes ae_rhs
|
| 652 | 653 | |
| 653 | - i' = i `setIdCallArity` trimmed_arity
|
|
| 654 | + i' = -- (if trimmed_arity == new_arity then id else
|
|
| 655 | + -- pprTrace "trimming"
|
|
| 656 | + -- (vcat [ ppr i <+> ppr new_arity <+> ppr trimmed_arity
|
|
| 657 | + -- , text "safe" <+> ppr safe_arity
|
|
| 658 | + -- , text "is_thunk" <+> ppr is_thunk ])) $
|
|
| 659 | + i `setIdCallArity` trimmed_arity
|
|
| 654 | 660 | |
| 655 | 661 | in (True, (i', Just (called_once, new_arity, ae_rhs'), rhs'))
|
| 656 | 662 | where
|
| ... | ... | @@ -66,7 +66,10 @@ import GHC.Types.Unique.Set |
| 66 | 66 | |
| 67 | 67 | import GHC.Types.Var.Set
|
| 68 | 68 | import GHC.Types.Var.Env
|
| 69 | + |
|
| 69 | 70 | import GHC.Utils.Misc
|
| 71 | +import GHC.Utils.EndoOS
|
|
| 72 | + |
|
| 70 | 73 | import GHC.Data.Pair
|
| 71 | 74 | |
| 72 | 75 | import Data.Semigroup
|
| ... | ... | @@ -285,9 +288,9 @@ done by the Call Arity pass. |
| 285 | 288 | TL;DR: check this regularly!
|
| 286 | 289 | -}
|
| 287 | 290 | |
| 288 | -runTyCoVars :: Endo TyCoVarSet -> TyCoVarSet
|
|
| 291 | +runTyCoVars :: EndoOS TyCoVarSet -> TyCoVarSet
|
|
| 289 | 292 | {-# INLINE runTyCoVars #-}
|
| 290 | -runTyCoVars f = appEndo f emptyVarSet
|
|
| 293 | +runTyCoVars f = appEndoOS f emptyVarSet
|
|
| 291 | 294 | |
| 292 | 295 | {- *********************************************************************
|
| 293 | 296 | * *
|
| ... | ... | @@ -320,28 +323,37 @@ tyCoVarsOfMCo (MCo co) = tyCoVarsOfCo co |
| 320 | 323 | tyCoVarsOfCos :: [Coercion] -> TyCoVarSet
|
| 321 | 324 | tyCoVarsOfCos cos = runTyCoVars (deep_cos cos)
|
| 322 | 325 | |
| 323 | -deep_ty :: Type -> Endo TyCoVarSet
|
|
| 324 | -deep_tys :: [Type] -> Endo TyCoVarSet
|
|
| 325 | -deep_co :: Coercion -> Endo TyCoVarSet
|
|
| 326 | -deep_cos :: [Coercion] -> Endo TyCoVarSet
|
|
| 326 | +deep_ty :: Type -> EndoOS TyCoVarSet
|
|
| 327 | +deep_tys :: [Type] -> EndoOS TyCoVarSet
|
|
| 328 | +deep_co :: Coercion -> EndoOS TyCoVarSet
|
|
| 329 | +deep_cos :: [Coercion] -> EndoOS TyCoVarSet
|
|
| 327 | 330 | (deep_ty, deep_tys, deep_co, deep_cos) = foldTyCo deepTcvFolder emptyVarSet
|
| 328 | 331 | |
| 329 | -deepTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet)
|
|
| 332 | +deepTcvFolder :: TyCoFolder TyCoVarSet (EndoOS TyCoVarSet)
|
|
| 333 | +-- It's important that we use a one-shot EndoOS, to ensure that all
|
|
| 334 | +-- the free-variable finders are eta-expanded. Lacking the one-shot-ness
|
|
| 335 | +-- led to some big slow downs. See Note [The one-shot state monad trick]
|
|
| 336 | +-- in GHC.Utils.Monad
|
|
| 330 | 337 | deepTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
|
| 331 | 338 | , tcf_tyvar = do_tcv, tcf_covar = do_tcv
|
| 332 | 339 | , tcf_hole = do_hole, tcf_tycobinder = do_bndr }
|
| 333 | 340 | where
|
| 334 | - do_tcv is v = Endo do_it
|
|
| 341 | + do_tcv is v = EndoOS do_it
|
|
| 335 | 342 | where
|
| 336 | 343 | do_it acc | v `elemVarSet` is = acc
|
| 337 | 344 | | v `elemVarSet` acc = acc
|
| 338 | - | otherwise = appEndo (deep_ty (varType v)) $
|
|
| 345 | + | otherwise = appEndoOS (deep_ty (varType v)) $
|
|
| 339 | 346 | acc `extendVarSet` v
|
| 340 | 347 | |
| 348 | + do_bndr :: TyCoVarSet -> TyVar -> ForAllTyFlag -> TyCoVarSet
|
|
| 341 | 349 | do_bndr is tcv _ = extendVarSet is tcv
|
| 342 | - do_hole is hole = do_tcv is (coHoleCoVar hole)
|
|
| 343 | - -- See Note [CoercionHoles and coercion free variables]
|
|
| 344 | - -- in GHC.Core.TyCo.Rep
|
|
| 350 | + |
|
| 351 | + do_hole :: VarSet -> CoercionHole -> EndoOS TyCoVarSet
|
|
| 352 | + do_hole _is hole = deep_ty (varType (coHoleCoVar hole))
|
|
| 353 | + -- We don't collect the CoercionHole itself, but we /do/
|
|
| 354 | + -- need to collect the free variables of its /kind/
|
|
| 355 | + -- See (CHFV1) in Note [CoercionHoles and coercion free variables]
|
|
| 356 | + -- in GHC.Core.TyCo.Rep
|
|
| 345 | 357 | |
| 346 | 358 | {- *********************************************************************
|
| 347 | 359 | * *
|
| ... | ... | @@ -378,18 +390,18 @@ shallowTyCoVarsOfCoVarEnv cos = shallowTyCoVarsOfCos (nonDetEltsUFM cos) |
| 378 | 390 | -- It's OK to use nonDetEltsUFM here because we immediately
|
| 379 | 391 | -- forget the ordering by returning a set
|
| 380 | 392 | |
| 381 | -shallow_ty :: Type -> Endo TyCoVarSet
|
|
| 382 | -shallow_tys :: [Type] -> Endo TyCoVarSet
|
|
| 383 | -shallow_co :: Coercion -> Endo TyCoVarSet
|
|
| 384 | -shallow_cos :: [Coercion] -> Endo TyCoVarSet
|
|
| 393 | +shallow_ty :: Type -> EndoOS TyCoVarSet
|
|
| 394 | +shallow_tys :: [Type] -> EndoOS TyCoVarSet
|
|
| 395 | +shallow_co :: Coercion -> EndoOS TyCoVarSet
|
|
| 396 | +shallow_cos :: [Coercion] -> EndoOS TyCoVarSet
|
|
| 385 | 397 | (shallow_ty, shallow_tys, shallow_co, shallow_cos) = foldTyCo shallowTcvFolder emptyVarSet
|
| 386 | 398 | |
| 387 | -shallowTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet)
|
|
| 399 | +shallowTcvFolder :: TyCoFolder TyCoVarSet (EndoOS TyCoVarSet)
|
|
| 388 | 400 | shallowTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
|
| 389 | 401 | , tcf_tyvar = do_tcv, tcf_covar = do_tcv
|
| 390 | 402 | , tcf_hole = do_hole, tcf_tycobinder = do_bndr }
|
| 391 | 403 | where
|
| 392 | - do_tcv is v = Endo do_it
|
|
| 404 | + do_tcv is v = EndoOS do_it
|
|
| 393 | 405 | where
|
| 394 | 406 | do_it acc | v `elemVarSet` is = acc
|
| 395 | 407 | | v `elemVarSet` acc = acc
|
| ... | ... | @@ -427,13 +439,13 @@ coVarsOfTypes tys = runTyCoVars (deep_cv_tys tys) |
| 427 | 439 | coVarsOfCo co = runTyCoVars (deep_cv_co co)
|
| 428 | 440 | coVarsOfCos cos = runTyCoVars (deep_cv_cos cos)
|
| 429 | 441 | |
| 430 | -deep_cv_ty :: Type -> Endo CoVarSet
|
|
| 431 | -deep_cv_tys :: [Type] -> Endo CoVarSet
|
|
| 432 | -deep_cv_co :: Coercion -> Endo CoVarSet
|
|
| 433 | -deep_cv_cos :: [Coercion] -> Endo CoVarSet
|
|
| 442 | +deep_cv_ty :: Type -> EndoOS CoVarSet
|
|
| 443 | +deep_cv_tys :: [Type] -> EndoOS CoVarSet
|
|
| 444 | +deep_cv_co :: Coercion -> EndoOS CoVarSet
|
|
| 445 | +deep_cv_cos :: [Coercion] -> EndoOS CoVarSet
|
|
| 434 | 446 | (deep_cv_ty, deep_cv_tys, deep_cv_co, deep_cv_cos) = foldTyCo deepCoVarFolder emptyVarSet
|
| 435 | 447 | |
| 436 | -deepCoVarFolder :: TyCoFolder TyCoVarSet (Endo CoVarSet)
|
|
| 448 | +deepCoVarFolder :: TyCoFolder TyCoVarSet (EndoOS CoVarSet)
|
|
| 437 | 449 | deepCoVarFolder = TyCoFolder { tcf_view = noView
|
| 438 | 450 | , tcf_tyvar = do_tyvar, tcf_covar = do_covar
|
| 439 | 451 | , tcf_hole = do_hole, tcf_tycobinder = do_bndr }
|
| ... | ... | @@ -445,17 +457,18 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView |
| 445 | 457 | -- the tyvar won't end up in the accumulator, so
|
| 446 | 458 | -- we'd look repeatedly. Blargh.
|
| 447 | 459 | |
| 448 | - do_covar is v = Endo do_it
|
|
| 460 | + do_bndr is tcv _ = extendVarSet is tcv
|
|
| 461 | + |
|
| 462 | + do_covar is v = EndoOS do_it
|
|
| 449 | 463 | where
|
| 450 | 464 | do_it acc | v `elemVarSet` is = acc
|
| 451 | 465 | | v `elemVarSet` acc = acc
|
| 452 | - | otherwise = appEndo (deep_cv_ty (varType v)) $
|
|
| 466 | + | otherwise = appEndoOS (deep_cv_ty (varType v)) $
|
|
| 453 | 467 | acc `extendVarSet` v
|
| 454 | 468 | |
| 455 | - do_bndr is tcv _ = extendVarSet is tcv
|
|
| 456 | - do_hole is hole = do_covar is (coHoleCoVar hole)
|
|
| 457 | - -- See Note [CoercionHoles and coercion free variables]
|
|
| 458 | - -- in GHC.Core.TyCo.Rep
|
|
| 469 | + do_hole _ _ = mempty
|
|
| 470 | + -- See (CHFV1) in Note [CoercionHoles and coercion free variables]
|
|
| 471 | + -- in GHC.Core.TyCo.Rep
|
|
| 459 | 472 | |
| 460 | 473 | ------- Same again, but for DCoVarSet ----------
|
| 461 | 474 | -- But this time the free vars are shallow
|
| ... | ... | @@ -480,7 +493,7 @@ closeOverKinds :: TyCoVarSet -> TyCoVarSet |
| 480 | 493 | -- add the deep free variables of its kind
|
| 481 | 494 | closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs
|
| 482 | 495 | where
|
| 483 | - do_one v acc = appEndo (deep_ty (varType v)) acc
|
|
| 496 | + do_one v acc = appEndoOS (deep_ty (varType v)) acc
|
|
| 484 | 497 | |
| 485 | 498 | {- --------------- Alternative version 1 (using FV) ------------
|
| 486 | 499 | closeOverKinds = fvVarSet . closeOverKindsFV . nonDetEltsUniqSet
|
| ... | ... | @@ -661,9 +674,8 @@ tyCoFVsOfCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) fv_cand in_sc |
| 661 | 674 | = (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2 `unionFV` tyCoFVsOfCo w) fv_cand in_scope acc
|
| 662 | 675 | tyCoFVsOfCo (CoVarCo v) fv_cand in_scope acc
|
| 663 | 676 | = tyCoFVsOfCoVar v fv_cand in_scope acc
|
| 664 | -tyCoFVsOfCo (HoleCo h) fv_cand in_scope acc
|
|
| 665 | - = tyCoFVsOfCoVar (coHoleCoVar h) fv_cand in_scope acc
|
|
| 666 | - -- See Note [CoercionHoles and coercion free variables]
|
|
| 677 | +tyCoFVsOfCo (HoleCo {}) fv_cand in_scope acc = emptyFV fv_cand in_scope acc
|
|
| 678 | + -- Ignore holes: see (CHFV1) in Note [CoercionHoles and coercion free variables]
|
|
| 667 | 679 | tyCoFVsOfCo (AxiomCo _ cs) fv_cand in_scope acc = tyCoFVsOfCos cs fv_cand in_scope acc
|
| 668 | 680 | tyCoFVsOfCo (UnivCo { uco_lty = t1, uco_rty = t2, uco_deps = deps}) fv_cand in_scope acc
|
| 669 | 681 | = (tyCoFVsOfCos deps `unionFV` tyCoFVsOfType t1
|
| ... | ... | @@ -1804,17 +1804,23 @@ Other notes about HoleCo: |
| 1804 | 1804 | |
| 1805 | 1805 | Note [CoercionHoles and coercion free variables]
|
| 1806 | 1806 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1807 | -Why does a CoercionHole contain a CoVar, as well as reference to
|
|
| 1808 | -fill in? Because we want to treat that CoVar as a free variable of
|
|
| 1809 | -the coercion. See #14584, and Note [What prevents a
|
|
| 1810 | -constraint from floating] in GHC.Tc.Solver, item (4):
|
|
| 1807 | +Why does a CoercionHole contain a CoVar, as well as reference to fill in?
|
|
| 1808 | + * It really helps for debug pretty-printing.
|
|
| 1809 | + * It carries a type which makes `coercionKind` and `coercionRole` work
|
|
| 1810 | + * It has a Unique, which gives the hole an identity; see calls to `ctEvEvId`
|
|
| 1811 | + |
|
| 1812 | +(CHFV1) We do not treat a CoercionHole as a free variable of a coercion.
|
|
| 1813 | + In the past we did: See #14584, and Note [What prevents a constraint from floating]
|
|
| 1814 | + in GHC.Tc.Solver, item (4):
|
|
| 1811 | 1815 | |
| 1812 | 1816 | forall k. [W] co1 :: t1 ~# t2 |> co2
|
| 1813 | 1817 | [W] co2 :: k ~# *
|
| 1814 | 1818 | |
| 1815 | -Here co2 is a CoercionHole. But we /must/ know that it is free in
|
|
| 1816 | -co1, because that's all that stops it floating outside the
|
|
| 1817 | -implication.
|
|
| 1819 | + Here co2 is a CoercionHole. But we /must/ know that it is free in
|
|
| 1820 | + co1, because that's all that stops it floating outside the
|
|
| 1821 | + implication.
|
|
| 1822 | + |
|
| 1823 | + But nowadays this is all irrelevant because we don't float constraints.
|
|
| 1818 | 1824 | |
| 1819 | 1825 | Note [CoercionHoles and CoHoleSets]
|
| 1820 | 1826 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -554,24 +554,21 @@ can_eq_nc_forall ev eq_rel s1 s2 |
| 554 | 554 | ; traceTcS "Trying to solve the implication" (ppr s1 $$ ppr s2 $$ ppr wanteds)
|
| 555 | 555 | |
| 556 | 556 | -- Solve the `wanteds` in a nested context
|
| 557 | - ; ev_binds_var <- newNoTcEvBinds
|
|
| 557 | + -- Use the /same/ TcEvBinds var as the context; we do not expect any dict binds
|
|
| 558 | + -- but we do want to record any used Given coercions (in `evb_tcvs`) so that
|
|
| 559 | + -- they are kept alive by `neededEvVars`. Admittedly they are free in `all_co`,
|
|
| 560 | + -- but only if we zonk it, which `neededEvVars` does not do (see test T7196).
|
|
| 561 | + ; ev_binds_var <- getTcEvBindsVar
|
|
| 558 | 562 | ; residual_wanted <- nestImplicTcS skol_info_anon ev_binds_var tclvl $
|
| 559 | 563 | solveSimpleWanteds wanteds
|
| 560 | 564 | |
| 561 | 565 | ; return (all_co, isSolvedWC residual_wanted) }
|
| 562 | 566 | |
| 563 | - |
|
| 564 | 567 | -- Kick out any inerts constraints that mention unified type variables
|
| 565 | 568 | ; kickOutAfterUnification unifs
|
| 566 | 569 | |
| 567 | 570 | ; if solved
|
| 568 | - then do { all_co <- zonkCo all_co
|
|
| 569 | - -- setWantedEq will add `all_co` to the `ebv_tcvs`, to record
|
|
| 570 | - -- that `all_co` is used. But if `all_co` contains filled
|
|
| 571 | - -- CoercionHoles, from the nested solve, and we may miss the
|
|
| 572 | - -- use of CoVars. Test T7196 showed this up
|
|
| 573 | - |
|
| 574 | - ; setWantedEq orig_dest emptyCoHoleSet all_co
|
|
| 571 | + then do { setWantedEq orig_dest emptyCoHoleSet all_co
|
|
| 575 | 572 | -- emptyCoHoleSet: fully solved, so all_co has no holes
|
| 576 | 573 | ; stopWith ev "Polytype equality: solved" }
|
| 577 | 574 | |
| ... | ... | @@ -2935,8 +2932,7 @@ lookup_eq_in_qcis :: CtEvidence -> EqRel -> TcType -> TcType -> SolverStage () |
| 2935 | 2932 | -- [W] t1 ~# t2
|
| 2936 | 2933 | -- and a Given quantified contraint like (forall a b. blah => a ~ b)
|
| 2937 | 2934 | -- Why? See Note [Looking up primitive equalities in quantified constraints]
|
| 2938 | --- See also GHC.Tc.Solver.Dict
|
|
| 2939 | --- Note [Equality superclasses in quantified constraints]
|
|
| 2935 | +-- See also GHC.Tc.Solver.Dict Note [Equality superclasses in quantified constraints]
|
|
| 2940 | 2936 | lookup_eq_in_qcis (CtGiven {}) _ _ _
|
| 2941 | 2937 | = nopStage ()
|
| 2942 | 2938 | |
| ... | ... | @@ -2952,10 +2948,18 @@ lookup_eq_in_qcis ev@(CtWanted (WantedCt { ctev_dest = dest, ctev_loc = loc })) |
| 2952 | 2948 | where
|
| 2953 | 2949 | hole = case dest of
|
| 2954 | 2950 | HoleDest hole -> hole -- Equality constraints have HoleDest
|
| 2955 | - _ -> pprPanic "lookup_eq_in_qcis" (ppr dest)
|
|
| 2951 | + _ -> pprPanic "lookup_eq_in_qcis" (ppr dest)
|
|
| 2956 | 2952 | |
| 2957 | 2953 | try :: SwapFlag -> SolverStage ()
|
| 2958 | - try swap -- First try looking for (lhs ~ rhs)
|
|
| 2954 | + -- E.g. We are trying to solve (say)
|
|
| 2955 | + -- [W] g : [Int] ~# b)
|
|
| 2956 | + -- from [G] forall x. blah => b ~ [x] -- A quantified constraint
|
|
| 2957 | + -- We can solve it like this
|
|
| 2958 | + -- d::b~[Int] := $df @Int blah -- Apply the quantified constraint
|
|
| 2959 | + -- g'::b~#[Int] := sc_sel d -- Binding, extract the coercion from d
|
|
| 2960 | + -- g(co-hole) := sym g' -- Fill the original coercion hole
|
|
| 2961 | + -- Here g' is a fresh coercion variable.
|
|
| 2962 | + try swap
|
|
| 2959 | 2963 | | Just (cls, tys) <- unSwap swap (boxEqPred eq_rel) lhs rhs
|
| 2960 | 2964 | = Stage $
|
| 2961 | 2965 | do { let cls_pred = mkClassPred cls tys
|
| ... | ... | @@ -2965,7 +2969,7 @@ lookup_eq_in_qcis ev@(CtWanted (WantedCt { ctev_dest = dest, ctev_loc = loc })) |
| 2965 | 2969 | OneInst {}
|
| 2966 | 2970 | -> do { dict_ev <- newWantedEvVarNC loc emptyCoHoleSet cls_pred
|
| 2967 | 2971 | ; chooseInstance dict_ev res
|
| 2968 | - ; let co_var = coHoleCoVar hole
|
|
| 2972 | + ; co_var <- newEvVar (unSwap swap (mkEqPred eq_rel) lhs rhs)
|
|
| 2969 | 2973 | ; setEvBind (mkWantedEvBind co_var EvCanonical (mk_sc_sel cls tys dict_ev))
|
| 2970 | 2974 | ; fillCoercionHole hole emptyCoHoleSet $
|
| 2971 | 2975 | maybeSymCo swap (mkCoVarCo co_var)
|
| ... | ... | @@ -392,6 +392,8 @@ data EvBindsVar |
| 392 | 392 | -- so that we can report unused given constraints,
|
| 393 | 393 | -- in GHC.Tc.Solver.neededEvVars
|
| 394 | 394 | -- See Note [Tracking redundant constraints] in GHC.Tc.Solver
|
| 395 | + -- Also: we garbage-collect unused bindings in `neededEvVars`,
|
|
| 396 | + -- so this matters for correctness too.
|
|
| 395 | 397 | }
|
| 396 | 398 | |
| 397 | 399 | | CoEvBindsVar { -- See Note [Coercion evidence only]
|
| ... | ... | @@ -234,9 +234,11 @@ import GHC.Builtin.Names |
| 234 | 234 | import GHC.Builtin.Types ( coercibleClass, eqClass, heqClass, unitTyConKey
|
| 235 | 235 | , listTyCon, constraintKind )
|
| 236 | 236 | import GHC.Types.Basic
|
| 237 | -import GHC.Utils.Misc
|
|
| 238 | 237 | import GHC.Data.Maybe
|
| 239 | 238 | import GHC.Data.List.SetOps ( getNth, findDupsEq )
|
| 239 | + |
|
| 240 | +import GHC.Utils.Misc
|
|
| 241 | +import GHC.Utils.EndoOS
|
|
| 240 | 242 | import GHC.Utils.Outputable
|
| 241 | 243 | import GHC.Utils.Panic
|
| 242 | 244 | |
| ... | ... | @@ -1176,11 +1178,11 @@ exactTyCoVarsOfTypes :: [Type] -> TyCoVarSet |
| 1176 | 1178 | exactTyCoVarsOfType ty = runTyCoVars (exact_ty ty)
|
| 1177 | 1179 | exactTyCoVarsOfTypes tys = runTyCoVars (exact_tys tys)
|
| 1178 | 1180 | |
| 1179 | -exact_ty :: Type -> Endo TyCoVarSet
|
|
| 1180 | -exact_tys :: [Type] -> Endo TyCoVarSet
|
|
| 1181 | +exact_ty :: Type -> EndoOS TyCoVarSet
|
|
| 1182 | +exact_tys :: [Type] -> EndoOS TyCoVarSet
|
|
| 1181 | 1183 | (exact_ty, exact_tys, _, _) = foldTyCo exactTcvFolder emptyVarSet
|
| 1182 | 1184 | |
| 1183 | -exactTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet)
|
|
| 1185 | +exactTcvFolder :: TyCoFolder TyCoVarSet (EndoOS TyCoVarSet)
|
|
| 1184 | 1186 | exactTcvFolder = deepTcvFolder { tcf_view = coreView }
|
| 1185 | 1187 | -- This is the key line
|
| 1186 | 1188 |
| ... | ... | @@ -168,7 +168,7 @@ instance MonadGetUnique USM.UniqSM where |
| 168 | 168 | newtype UniqDSMT m result = UDSMT' (DUniqSupply -> m (result, DUniqSupply))
|
| 169 | 169 | deriving (Functor)
|
| 170 | 170 | |
| 171 | --- Similar to GHC.Utils.Monad.State.Strict, using Note [The one-shot state monad trick]
|
|
| 171 | +-- Similar to GHC.Utils.Monad, using Note [The one-shot state monad trick]
|
|
| 172 | 172 | -- Using the one-shot trick is necessary for performance.
|
| 173 | 173 | -- Using transfomer's strict `StateT` regressed some performance tests in 1-2%.
|
| 174 | 174 | -- The one-shot trick here fixes those regressions.
|
| 1 | +{-# LANGUAGE PatternSynonyms #-}
|
|
| 2 | + |
|
| 3 | +-- | One-shot endomorphisms
|
|
| 4 | +-- Mostly for backwards compatibility.
|
|
| 5 | + |
|
| 6 | +-- One-shot endomorphisms
|
|
| 7 | +-- Like GHC.Internal.Data.Semigroup.Internal.Endo, but uting
|
|
| 8 | +-- the one-shot trick from
|
|
| 9 | +-- Note [The one-shot state monad trick] in GHC.Utils.Monad.
|
|
| 10 | + |
|
| 11 | +module GHC.Utils.EndoOS( EndoOS(EndoOS, appEndoOS ) ) where
|
|
| 12 | + |
|
| 13 | +import GHC.Prelude
|
|
| 14 | + |
|
| 15 | +import Data.Semigroup
|
|
| 16 | +import GHC.Exts (oneShot)
|
|
| 17 | + |
|
| 18 | +newtype EndoOS a = EndoOS' { appEndoOS :: a -> a }
|
|
| 19 | + |
|
| 20 | + |
|
| 21 | +instance Semigroup (EndoOS a) where
|
|
| 22 | + f <> g = EndoOS (appEndoOS f . appEndoOS g)
|
|
| 23 | + |
|
| 24 | +instance Monoid (EndoOS a) where
|
|
| 25 | + mempty = EndoOS id
|
|
| 26 | + |
|
| 27 | +pattern EndoOS :: (a->a) -> EndoOS a
|
|
| 28 | +pattern EndoOS f <- EndoOS' f
|
|
| 29 | + where
|
|
| 30 | + EndoOS f = EndoOS' (oneShot f)
|
|
| 31 | + -- ^^^^^^ The one-shot trick! |
| ... | ... | @@ -997,6 +997,7 @@ Library |
| 997 | 997 | GHC.Utils.Containers.Internal.BitUtil
|
| 998 | 998 | GHC.Utils.Containers.Internal.StrictPair
|
| 999 | 999 | GHC.Utils.Error
|
| 1000 | + GHC.Utils.EndoOS
|
|
| 1000 | 1001 | GHC.Utils.Exception
|
| 1001 | 1002 | GHC.Utils.Fingerprint
|
| 1002 | 1003 | GHC.Utils.FV
|