Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
-
17e57012
by Simon Peyton Jones at 2025-10-14T22:22:20+01:00
-
addfb498
by Simon Peyton Jones at 2025-10-15T22:26:30+01:00
11 changed files:
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/Irred.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Types/Constraint.hs
- testsuite/tests/perf/compiler/T8095.hs
- testsuite/tests/perf/compiler/T9872a.hs
Changes:
| ... | ... | @@ -1690,6 +1690,8 @@ data CoercionHole |
| 1690 | 1690 | -- See Note [CoercionHoles and coercion free variables]
|
| 1691 | 1691 | |
| 1692 | 1692 | , ch_ref :: IORef (Maybe (Coercion, RewriterSet))
|
| 1693 | + -- The RewriterSet is (possibly a superset of)
|
|
| 1694 | + -- the free coercion holes of the coercion
|
|
| 1693 | 1695 | }
|
| 1694 | 1696 | |
| 1695 | 1697 | coHoleCoVar :: CoercionHole -> CoVar
|
| ... | ... | @@ -447,7 +447,7 @@ defaultExceptionContext ct |
| 447 | 447 | ; empty_ec_id <- lookupId emptyExceptionContextName
|
| 448 | 448 | ; let ev = ctEvidence ct
|
| 449 | 449 | ev_tm = EvExpr (evWrapIPE (ctEvPred ev) (Var empty_ec_id))
|
| 450 | - ; setEvBindIfWanted ev EvCanonical ev_tm
|
|
| 450 | + ; setDictIfWanted ev EvCanonical ev_tm
|
|
| 451 | 451 | -- EvCanonical: see Note [CallStack and ExceptionContext hack]
|
| 452 | 452 | -- in GHC.Tc.Solver.Dict
|
| 453 | 453 | ; return True }
|
| ... | ... | @@ -541,8 +541,7 @@ defaultEquality encl_eqs ct |
| 541 | 541 | = do { traceTcS "defaultEquality success:" (ppr rhs_ty)
|
| 542 | 542 | ; unifyTyVar lhs_tv rhs_ty -- NB: unifyTyVar adds to the
|
| 543 | 543 | -- TcS unification counter
|
| 544 | - ; setEvBindIfWanted (ctEvidence ct) EvCanonical $
|
|
| 545 | - evCoercion (mkReflCo Nominal rhs_ty)
|
|
| 544 | + ; setEqIfWanted (ctEvidence ct) emptyRewriterSet (mkReflCo Nominal rhs_ty)
|
|
| 546 | 545 | ; return True
|
| 547 | 546 | }
|
| 548 | 547 | |
| ... | ... | @@ -567,8 +566,7 @@ defaultEquality encl_eqs ct |
| 567 | 566 | -- See Note [Defaulting representational equalities].
|
| 568 | 567 | ; if null new_eqs
|
| 569 | 568 | then do { traceTcS "defaultEquality ReprEq } (yes)" empty
|
| 570 | - ; setEvBindIfWanted (ctEvidence ct) EvCanonical $
|
|
| 571 | - evCoercion $ mkSubCo co
|
|
| 569 | + ; setEqIfWanted (ctEvidence ct) emptyRewriterSet (mkSubCo co)
|
|
| 572 | 570 | ; return True }
|
| 573 | 571 | else do { traceTcS "defaultEquality ReprEq } (no)" empty
|
| 574 | 572 | ; return False } }
|
| ... | ... | @@ -178,7 +178,7 @@ solveCallStack ev ev_cs |
| 178 | 178 | -- `IP ip CallStack`. See Note [Overview of implicit CallStacks]
|
| 179 | 179 | = do { inner_stk <- evCallStack pred ev_cs
|
| 180 | 180 | ; let ev_tm = EvExpr (evWrapIPE pred inner_stk)
|
| 181 | - ; setEvBindIfWanted ev EvCanonical ev_tm }
|
|
| 181 | + ; setDictIfWanted ev EvCanonical ev_tm }
|
|
| 182 | 182 | -- EvCanonical: see Note [CallStack and ExceptionContext hack]
|
| 183 | 183 | where
|
| 184 | 184 | pred = ctEvPred ev
|
| ... | ... | @@ -394,9 +394,18 @@ There are two more similar "equality classes" like this. The full list is |
| 394 | 394 | * Coercible coercibleTyCon
|
| 395 | 395 | (See Note [The equality types story] in GHC.Builtin.Types.Prim.)
|
| 396 | 396 | |
| 397 | -(EQC1) For Givens, when expanding the superclasses of a equality class,
|
|
| 398 | - we can /replace/ the constraint with its superclasses (which, remember, are
|
|
| 399 | - equally powerful) rather than /adding/ them. This can make a huge difference.
|
|
| 397 | +(EQC1) For a Given (boxed) equality like (t1 ~ t2), we /replace/ the constraint
|
|
| 398 | + with its superclass (which, remember, is equally powerful) rather than /adding/
|
|
| 399 | + it. Thus, we turn [G] d : t1 ~ t2 into
|
|
| 400 | + [G] g : t1 ~# t2
|
|
| 401 | + g := sc_sel d -- Extend the evidence bindings
|
|
| 402 | + |
|
| 403 | + We achieve this by
|
|
| 404 | + (a) not expanding superclasses for equality classes at all;
|
|
| 405 | + see the `isEqualityClass` test in `mk_strict_superclasses`
|
|
| 406 | + (b) special logic to solve (t1 ~ t2) in the Given case of `solveEqualityDict`.
|
|
| 407 | + |
|
| 408 | + Using replacement rather than adding can make a huge difference.
|
|
| 400 | 409 | Consider T17836, which has a constraint like
|
| 401 | 410 | forall b,c. a ~ (b,c) =>
|
| 402 | 411 | forall d,e. c ~ (d,e) =>
|
| ... | ... | @@ -411,11 +420,6 @@ There are two more similar "equality classes" like this. The full list is |
| 411 | 420 | pattern matching. Its compile-time allocation decreased by 40% when
|
| 412 | 421 | I added the "replace" rather than "add" semantics.)
|
| 413 | 422 | |
| 414 | - We achieve this by
|
|
| 415 | - (a) not expanding superclasses for equality classes at all;
|
|
| 416 | - see the `isEqualityClass` test in `mk_strict_superclasses`
|
|
| 417 | - (b) special logic to solve (t1 ~ t2) in `solveEqualityDict`.
|
|
| 418 | - |
|
| 419 | 423 | (EQC2) Faced with [W] t1 ~ t2, it's always OK to reduce it to [W] t1 ~# t2,
|
| 420 | 424 | without worrying about Note [Instance and Given overlap]. Why? Because
|
| 421 | 425 | if we had [G] s1 ~ s2, then we'd get the superclass [G] s1 ~# s2, and
|
| ... | ... | @@ -468,26 +472,29 @@ solveEqualityDict :: CtEvidence -> Class -> [Type] -> SolverStage Void |
| 468 | 472 | -- See Note [Solving equality classes]
|
| 469 | 473 | -- Precondition: (isEqualityClass cls) True, so cls is (~), (~~), or Coercible
|
| 470 | 474 | solveEqualityDict ev cls tys
|
| 475 | + | CtGiven (GivenCt { ctev_evar = ev_id }) <- ev
|
|
| 476 | + , [sel_id] <- classSCSelIds cls -- Equality classes have just one superclass
|
|
| 477 | + = Stage $
|
|
| 478 | + do { let loc = ctEvLoc ev
|
|
| 479 | + sc_pred = classMethodInstTy sel_id tys
|
|
| 480 | + ev_expr = EvExpr $ Var sel_id `mkTyApps` tys `App` evId ev_id
|
|
| 481 | + -- See (EQC1) in Note [Solving equality classes]
|
|
| 482 | + -- This call to newGivenEv makes the evidence binding for the (unboxed) coercion
|
|
| 483 | + ; given_ev <- newGivenEv loc (sc_pred, ev_expr)
|
|
| 484 | + ; startAgainWith (mkNonCanonical $ CtGiven given_ev) }
|
|
| 485 | + |
|
| 471 | 486 | | CtWanted (WantedCt { ctev_dest = dest }) <- ev
|
| 472 | 487 | = Stage $
|
| 473 | 488 | do { let (role, t1, t2) = matchEqualityInst cls tys
|
| 474 | 489 | -- Unify t1~t2, putting anything that can't be solved
|
| 475 | 490 | -- immediately into the work list
|
| 476 | - ; co <- wrapUnifierAndEmit ev role $ \uenv ->
|
|
| 477 | - uType uenv t1 t2
|
|
| 491 | + ; (co,_rws) <- wrapUnifierAndEmit ev role $ \uenv ->
|
|
| 492 | + uType uenv t1 t2
|
|
| 478 | 493 | -- Set d :: (t1~t2) = Eq# co
|
| 479 | 494 | ; setWantedDict dest EvCanonical $
|
| 480 | 495 | evDictApp cls tys [Coercion co]
|
| 481 | 496 | ; stopWith ev "Solved wanted lifted equality" }
|
| 482 | 497 | |
| 483 | - | CtGiven (GivenCt { ctev_evar = ev_id }) <- ev
|
|
| 484 | - , [sel_id] <- classSCSelIds cls -- Equality classes have just one superclass
|
|
| 485 | - = Stage $
|
|
| 486 | - do { let loc = ctEvLoc ev
|
|
| 487 | - sc_pred = classMethodInstTy sel_id tys
|
|
| 488 | - ev_expr = EvExpr $ Var sel_id `mkTyApps` tys `App` evId ev_id
|
|
| 489 | - ; given_ev <- newGivenEv loc (sc_pred, ev_expr)
|
|
| 490 | - ; startAgainWith (mkNonCanonical $ CtGiven given_ev) }
|
|
| 491 | 498 | | otherwise
|
| 492 | 499 | = pprPanic "solveEqualityDict" (ppr cls)
|
| 493 | 500 | |
| ... | ... | @@ -730,10 +737,10 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys |
| 730 | 737 | | otherwise -- We can either solve the inert from the work-item or vice-versa.
|
| 731 | 738 | -> case solveOneFromTheOther (CDictCan dict_i) (CDictCan dict_w) of
|
| 732 | 739 | KeepInert -> do { traceTcS "lookupInertDict:KeepInert" (ppr dict_w)
|
| 733 | - ; setEvBindIfWanted ev_w EvCanonical (ctEvTerm ev_i)
|
|
| 740 | + ; setDictIfWanted ev_w EvCanonical (ctEvTerm ev_i)
|
|
| 734 | 741 | ; return $ Stop ev_w (text "Dict equal" <+> ppr dict_w) }
|
| 735 | 742 | KeepWork -> do { traceTcS "lookupInertDict:KeepWork" (ppr dict_w)
|
| 736 | - ; setEvBindIfWanted ev_i EvCanonical (ctEvTerm ev_w)
|
|
| 743 | + ; setDictIfWanted ev_i EvCanonical (ctEvTerm ev_w)
|
|
| 737 | 744 | ; updInertCans (updDicts $ delDict dict_w)
|
| 738 | 745 | ; continueWith () } }
|
| 739 | 746 | |
| ... | ... | @@ -796,7 +803,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls |
| 796 | 803 | -- See Note [No Given/Given fundeps]
|
| 797 | 804 | |
| 798 | 805 | | Just solved_ev <- lookupSolvedDict inerts cls xis -- Cached
|
| 799 | - = do { setEvBindIfWanted ev EvCanonical (ctEvTerm solved_ev)
|
|
| 806 | + = do { setDictIfWanted ev EvCanonical (ctEvTerm solved_ev)
|
|
| 800 | 807 | ; stopWith ev "Dict/Top (cached)" }
|
| 801 | 808 | |
| 802 | 809 | | otherwise -- Wanted, but not cached
|
| ... | ... | @@ -828,7 +835,7 @@ chooseInstance work_item |
| 828 | 835 | ; assertPprM (getTcEvBindsVar >>= return . not . isCoEvBindsVar)
|
| 829 | 836 | (ppr work_item)
|
| 830 | 837 | ; evc_vars <- mapM (newWanted deeper_loc (ctEvRewriters work_item)) theta
|
| 831 | - ; setEvBindIfWanted work_item canonical (mk_ev (map getEvExpr evc_vars))
|
|
| 838 | + ; setDictIfWanted work_item canonical (mk_ev (map getEvExpr evc_vars))
|
|
| 832 | 839 | ; emitWorkNC (map CtWanted $ freshGoals evc_vars)
|
| 833 | 840 | ; stopWith work_item "Dict/Top (solved wanted)" }
|
| 834 | 841 | where
|
| ... | ... | @@ -10,7 +10,7 @@ module GHC.Tc.Solver.Equality( |
| 10 | 10 | |
| 11 | 11 | import GHC.Prelude
|
| 12 | 12 | |
| 13 | -import {-# SOURCE #-} GHC.Tc.Solver.Solve( trySolveImplication )
|
|
| 13 | +import {-# SOURCE #-} GHC.Tc.Solver.Solve( solveSimpleWanteds )
|
|
| 14 | 14 | |
| 15 | 15 | import GHC.Tc.Solver.Irred( solveIrred )
|
| 16 | 16 | import GHC.Tc.Solver.Dict( matchLocalInst, chooseInstance )
|
| ... | ... | @@ -372,7 +372,7 @@ can_eq_nc rewritten rdr_env envs ev eq_rel ty1 ps_ty1 (CastTy ty2 co2) _ |
| 372 | 372 | -- Literals
|
| 373 | 373 | can_eq_nc _rewritten _rdr_env _envs ev eq_rel ty1@(LitTy l1) _ (LitTy l2) _
|
| 374 | 374 | | l1 == l2
|
| 375 | - = do { setEvBindIfWanted ev EvCanonical (evCoercion $ mkReflCo (eqRelRole eq_rel) ty1)
|
|
| 375 | + = do { setEqIfWanted ev emptyRewriterSet (mkReflCo (eqRelRole eq_rel) ty1)
|
|
| 376 | 376 | ; stopWith ev "Equal LitTy" }
|
| 377 | 377 | |
| 378 | 378 | -- Decompose FunTy: (s -> t) and (c => t)
|
| ... | ... | @@ -485,7 +485,7 @@ can_eq_nc_forall :: CtEvidence -> EqRel |
| 485 | 485 | -- See Note [Solving forall equalities]
|
| 486 | 486 | |
| 487 | 487 | can_eq_nc_forall ev eq_rel s1 s2
|
| 488 | - | CtWanted (WantedCt { ctev_dest = orig_dest, ctev_rewriters = rws, ctev_loc = loc }) <- ev
|
|
| 488 | + | CtWanted (WantedCt { ctev_dest = orig_dest }) <- ev
|
|
| 489 | 489 | = do { let (bndrs1, phi1, bndrs2, phi2) = split_foralls s1 s2
|
| 490 | 490 | flags1 = binderFlags bndrs1
|
| 491 | 491 | flags2 = binderFlags bndrs2
|
| ... | ... | @@ -541,36 +541,40 @@ can_eq_nc_forall ev eq_rel s1 s2 |
| 541 | 541 | |
| 542 | 542 | ; traceTcS "Generating wanteds" (ppr s1 $$ ppr s2)
|
| 543 | 543 | |
| 544 | - -- Generate the constraints that live in the body of the implication
|
|
| 545 | - -- See (SF5) in Note [Solving forall equalities]
|
|
| 546 | - ; (unifs, (lvl, (all_co, wanteds)))
|
|
| 547 | - <- reportFineGrainUnifications $
|
|
| 548 | - pushLevelNoWorkList (ppr skol_info) $
|
|
| 549 | - wrapUnifier ev (eqRelRole eq_rel) $ \uenv ->
|
|
| 550 | - go uenv skol_tvs init_subst2 bndrs1 bndrs2
|
|
| 544 | + -- Generate and solve the constraints that live in the body of the implication
|
|
| 545 | + -- See (SF5) and (SF6) in Note [Solving forall equalities]
|
|
| 546 | + ; (unifs, (all_co, solved))
|
|
| 547 | + <- reportFineGrainUnifications $
|
|
| 548 | + do { -- Generate constraints
|
|
| 549 | + (tclvl, (all_co, wanteds))
|
|
| 550 | + <- pushLevelNoWorkList (ppr skol_info) $
|
|
| 551 | + wrapUnifier ev (eqRelRole eq_rel) $ \uenv ->
|
|
| 552 | + go uenv skol_tvs init_subst2 bndrs1 bndrs2
|
|
| 553 | + |
|
| 554 | + ; traceTcS "Trying to solve the implication" (ppr s1 $$ ppr s2 $$ ppr wanteds)
|
|
| 555 | + |
|
| 556 | + -- Solve the `wanteds` in a nested context
|
|
| 557 | + ; ev_binds_var <- newNoTcEvBinds
|
|
| 558 | + ; residual_wanted <- nestImplicTcS skol_info_anon ev_binds_var tclvl $
|
|
| 559 | + solveSimpleWanteds wanteds
|
|
| 560 | + |
|
| 561 | + ; return (all_co, isSolvedWC residual_wanted) }
|
|
| 562 | + |
|
| 551 | 563 | |
| 552 | 564 | -- Kick out any inerts constraints that mention unified type variables
|
| 553 | 565 | ; kickOutAfterUnification unifs
|
| 554 | 566 | |
| 555 | - -- Solve the implication right away, using `trySolveImplication`
|
|
| 556 | - -- See (SF6) in Note [Solving forall equalities]
|
|
| 557 | - ; traceTcS "Trying to solve the implication" (ppr s1 $$ ppr s2 $$ ppr wanteds)
|
|
| 558 | - ; ev_binds_var <- newNoTcEvBinds
|
|
| 559 | - ; solved <- trySolveImplication $
|
|
| 560 | - (implicationPrototype (ctLocEnv loc))
|
|
| 561 | - { ic_tclvl = lvl
|
|
| 562 | - , ic_binds = ev_binds_var
|
|
| 563 | - , ic_info = skol_info_anon
|
|
| 564 | - , ic_warn_inaccessible = False
|
|
| 565 | - , ic_skols = skol_tvs
|
|
| 566 | - , ic_given = []
|
|
| 567 | - , ic_wanted = emptyWC { wc_simple = wanteds } }
|
|
| 568 | - |
|
| 569 | 567 | ; if solved
|
| 570 | - then do { -- all_co <- zonkCo all_co
|
|
| 571 | - -- -- ToDo: explain this zonk
|
|
| 572 | - setWantedEq orig_dest rws all_co
|
|
| 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 emptyRewriterSet all_co
|
|
| 575 | + -- emptyRewriterSet: fully solved, so all_co has no holes
|
|
| 573 | 576 | ; stopWith ev "Polytype equality: solved" }
|
| 577 | + |
|
| 574 | 578 | else canEqSoftFailure IrredShapeReason ev s1 s2 } }
|
| 575 | 579 | |
| 576 | 580 | | otherwise
|
| ... | ... | @@ -592,11 +596,12 @@ can_eq_nc_forall ev eq_rel s1 s2 |
| 592 | 596 | in (bndr1:bndrs1, phi1, bndr2:bndrs2, phi2)
|
| 593 | 597 | split_foralls s1 s2 = ([], s1, [], s2)
|
| 594 | 598 | |
| 599 | + |
|
| 595 | 600 | {- Note [Solving forall equalities]
|
| 596 | 601 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 597 | 602 | To solve an equality between foralls
|
| 598 | 603 | [W] (forall a. t1) ~ (forall b. t2)
|
| 599 | -the basic plan is simple: use `trySolveImplication` to solve the
|
|
| 604 | +the basic plan is simple: behave rather as if we were solving the
|
|
| 600 | 605 | implication constraint
|
| 601 | 606 | [W] forall a. { t1 ~ (t2[a/b]) }
|
| 602 | 607 | |
| ... | ... | @@ -643,19 +648,15 @@ There are lots of wrinkles of course: |
| 643 | 648 | because we want to /gather/ the equality constraint (to put in the implication)
|
| 644 | 649 | rather than /emit/ them into the monad, as `wrapUnifierAndEmit` does.
|
| 645 | 650 | |
| 646 | -(SF6) We solve the implication on the spot, using `trySolveImplication`. In
|
|
| 647 | - the past we instead generated an `Implication` to be solved later. Nice in
|
|
| 648 | - some ways but it added complexity:
|
|
| 649 | - - We needed a `wl_implics` field of `WorkList` to collect
|
|
| 650 | - these emitted implications
|
|
| 651 | - - The types of `solveSimpleWanteds` and friends were more complicated
|
|
| 652 | - - Trickily, an `EvFun` had to contain an `EvBindsVar` ref-cell, which made
|
|
| 653 | - `evVarsOfTerm` harder. Now an `EvFun` just contains the bindings.
|
|
| 654 | - The disadvantage of solve-on-the-spot is that if we fail we are simply
|
|
| 655 | - left with an unsolved (forall a. blah) ~ (forall b. blah), and it may
|
|
| 656 | - not be clear /why/ we couldn't solve it. But on balance the error messages
|
|
| 657 | - improve: it is easier to undertand that
|
|
| 658 | - (forall a. a->a) ~ (forall b. b->Int)
|
|
| 651 | +(SF6) We solve the nested constraints right away. In the past we instead generated
|
|
| 652 | + an `Implication` to be solved later, but we no longer have a convenient place
|
|
| 653 | + to accumulate such an implication for later solving. Instead we just try to solve
|
|
| 654 | + them on the spot, and abandon the attempt if we fail.
|
|
| 655 | + |
|
| 656 | + In the latter case we are left with an unsolved (forall a. blah) ~ (forall b. blah),
|
|
| 657 | + and it may not be clear /why/ we couldn't solve it. But on balance the error
|
|
| 658 | + messages improve: it is easier to understand that
|
|
| 659 | + (forall a. a->a) ~ (forall b. b->Int)
|
|
| 659 | 660 | is insoluble than it is to understand a message about matching `a` with `Int`.
|
| 660 | 661 | -}
|
| 661 | 662 | |
| ... | ... | @@ -809,11 +810,11 @@ can_eq_app :: CtEvidence -- :: s1 t1 ~N s2 t2 |
| 809 | 810 | -- to an irreducible constraint; see typecheck/should_compile/T10494
|
| 810 | 811 | -- See Note [Decomposing AppTy equalities]
|
| 811 | 812 | can_eq_app ev s1 t1 s2 t2
|
| 812 | - | CtWanted (WantedCt { ctev_dest = dest, ctev_rewriters = rws }) <- ev
|
|
| 813 | + | CtWanted (WantedCt { ctev_dest = dest }) <- ev
|
|
| 813 | 814 | = do { traceTcS "can_eq_app" (vcat [ text "s1:" <+> ppr s1, text "t1:" <+> ppr t1
|
| 814 | 815 | , text "s2:" <+> ppr s2, text "t2:" <+> ppr t2
|
| 815 | 816 | , text "vis:" <+> ppr (isNextArgVisible s1) ])
|
| 816 | - ; co <- wrapUnifierAndEmit ev Nominal $ \uenv ->
|
|
| 817 | + ; (co,rws) <- wrapUnifierAndEmit ev Nominal $ \uenv ->
|
|
| 817 | 818 | -- Unify arguments t1/t2 before function s1/s2, because
|
| 818 | 819 | -- the former have smaller kinds, and hence simpler error messages
|
| 819 | 820 | -- c.f. GHC.Tc.Utils.Unify.uType (go_app)
|
| ... | ... | @@ -1374,11 +1375,11 @@ canDecomposableTyConAppOK ev eq_rel tc (ty1,tys1) (ty2,tys2) |
| 1374 | 1375 | do { traceTcS "canDecomposableTyConAppOK"
|
| 1375 | 1376 | (ppr ev $$ ppr eq_rel $$ ppr tc $$ ppr tys1 $$ ppr tys2)
|
| 1376 | 1377 | ; case ev of
|
| 1377 | - CtWanted (WantedCt { ctev_dest = dest, ctev_rewriters = rws })
|
|
| 1378 | + CtWanted (WantedCt { ctev_dest = dest })
|
|
| 1378 | 1379 | -- new_locs and tc_roles are both infinite, so we are
|
| 1379 | 1380 | -- guaranteed that cos has the same length as tys1 and tys2
|
| 1380 | 1381 | -- See Note [Fast path when decomposing TyConApps]
|
| 1381 | - -> do { co <- wrapUnifierAndEmit ev role $ \uenv ->
|
|
| 1382 | + -> do { (co,rws) <- wrapUnifierAndEmit ev role $ \uenv ->
|
|
| 1382 | 1383 | do { cos <- zipWith4M (u_arg uenv) new_locs tc_roles tys1 tys2
|
| 1383 | 1384 | -- zipWith4M: see Note [Work-list ordering]
|
| 1384 | 1385 | ; return (mkTyConAppCo role tc cos) }
|
| ... | ... | @@ -1432,8 +1433,8 @@ canDecomposableFunTy ev eq_rel af f1@(ty1,m1,a1,r1) f2@(ty2,m2,a2,r2) |
| 1432 | 1433 | = do { traceTcS "canDecomposableFunTy"
|
| 1433 | 1434 | (ppr ev $$ ppr eq_rel $$ ppr f1 $$ ppr f2)
|
| 1434 | 1435 | ; case ev of
|
| 1435 | - CtWanted (WantedCt { ctev_dest = dest, ctev_rewriters = rws })
|
|
| 1436 | - -> do { co <- wrapUnifierAndEmit ev Nominal $ \ uenv ->
|
|
| 1436 | + CtWanted (WantedCt { ctev_dest = dest })
|
|
| 1437 | + -> do { (co,rws) <- wrapUnifierAndEmit ev Nominal $ \ uenv ->
|
|
| 1437 | 1438 | do { let mult_env = uenv `updUEnvLoc` toInvisibleLoc InvisibleMultiplicity
|
| 1438 | 1439 | `setUEnvRole` funRole role SelMult
|
| 1439 | 1440 | ; mult <- uType mult_env m1 m2
|
| ... | ... | @@ -2011,6 +2012,7 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs |
| 2011 | 2012 | then return ev
|
| 2012 | 2013 | else rewriteEqEvidence emptyRewriterSet ev swapped
|
| 2013 | 2014 | (mkReflRedn Nominal (mkTyVarTy tv)) rhs_redn
|
| 2015 | + -- emptyRewriterSet: rhs_redn has no CoercionHoles
|
|
| 2014 | 2016 | |
| 2015 | 2017 | ; let tv_ty = mkTyVarTy tv
|
| 2016 | 2018 | final_rhs = reductionReducedType rhs_redn
|
| ... | ... | @@ -2026,8 +2028,7 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs |
| 2026 | 2028 | |
| 2027 | 2029 | -- Provide Refl evidence for the constraint
|
| 2028 | 2030 | -- Ignore 'swapped' because it's Refl!
|
| 2029 | - ; setEvBindIfWanted new_ev EvCanonical $
|
|
| 2030 | - evCoercion (mkNomReflCo final_rhs)
|
|
| 2031 | + ; setEqIfWanted new_ev emptyRewriterSet (mkNomReflCo final_rhs)
|
|
| 2031 | 2032 | |
| 2032 | 2033 | -- Kick out any constraints that can now be rewritten
|
| 2033 | 2034 | ; kickOutAfterUnification (unitVarSet tv)
|
| ... | ... | @@ -2147,8 +2148,7 @@ canEqReflexive :: CtEvidence -- ty ~ ty |
| 2147 | 2148 | -> TcType -- ty
|
| 2148 | 2149 | -> TcS (StopOrContinue a) -- always Stop
|
| 2149 | 2150 | canEqReflexive ev eq_rel ty
|
| 2150 | - = do { setEvBindIfWanted ev EvCanonical $
|
|
| 2151 | - evCoercion (mkReflCo (eqRelRole eq_rel) ty)
|
|
| 2151 | + = do { setEqIfWanted ev emptyRewriterSet (mkReflCo (eqRelRole eq_rel) ty)
|
|
| 2152 | 2152 | ; stopWith ev "Solved by reflexivity" }
|
| 2153 | 2153 | |
| 2154 | 2154 | {- Note [Equalities with heterogeneous kinds]
|
| ... | ... | @@ -2649,10 +2649,11 @@ rewriteEqEvidence new_rewriters old_ev swapped (Reduction lhs_co nlhs) (Reductio |
| 2649 | 2649 | |
| 2650 | 2650 | | CtWanted (WantedCt { ctev_dest = dest, ctev_rewriters = rewriters }) <- old_ev
|
| 2651 | 2651 | = do { let rewriters' = rewriters S.<> new_rewriters
|
| 2652 | - ; (new_ev, hole_co) <- newWantedEq loc rewriters' (ctEvRewriteRole old_ev) nlhs nrhs
|
|
| 2652 | + ; (new_ev, hole) <- newWantedEq loc rewriters' (ctEvRewriteRole old_ev) nlhs nrhs
|
|
| 2653 | 2653 | ; let co = maybeSymCo swapped $
|
| 2654 | - lhs_co `mkTransCo` hole_co `mkTransCo` mkSymCo rhs_co
|
|
| 2655 | - ; setWantedEq dest rewriters' co
|
|
| 2654 | + lhs_co `mkTransCo` mkHoleCo hole `mkTransCo` mkSymCo rhs_co
|
|
| 2655 | + -- new_rewriters has all the holes from lhs_co and rhs_co
|
|
| 2656 | + ; setWantedEq dest (new_rewriters `mappend` unitRewriterSet hole) co
|
|
| 2656 | 2657 | ; traceTcS "rewriteEqEvidence" (vcat [ ppr old_ev
|
| 2657 | 2658 | , ppr nlhs
|
| 2658 | 2659 | , ppr nrhs
|
| ... | ... | @@ -2730,11 +2731,11 @@ tryInertEqs work_item@(EqCt { eq_ev = ev, eq_eq_rel = eq_rel }) |
| 2730 | 2731 | = Stage $
|
| 2731 | 2732 | do { inerts <- getInertCans
|
| 2732 | 2733 | ; if | Just (ev_i, swapped) <- inertsEqsCanDischarge inerts work_item
|
| 2733 | - -> do { setEvBindIfWanted ev EvCanonical $
|
|
| 2734 | - evCoercion (maybeSymCo swapped $
|
|
| 2735 | - downgradeRole (eqRelRole eq_rel)
|
|
| 2736 | - (ctEvRewriteRole ev_i)
|
|
| 2737 | - (ctEvCoercion ev_i))
|
|
| 2734 | + -> do { setEqIfWanted ev (ctEvRewriterSet ev_i) $
|
|
| 2735 | + maybeSymCo swapped $
|
|
| 2736 | + downgradeRole (eqRelRole eq_rel)
|
|
| 2737 | + (ctEvRewriteRole ev_i)
|
|
| 2738 | + (ctEvCoercion ev_i)
|
|
| 2738 | 2739 | ; stopWith ev "Solved from inert" }
|
| 2739 | 2740 | |
| 2740 | 2741 | | otherwise
|
| ... | ... | @@ -14,11 +14,10 @@ import GHC.Tc.Solver.Dict( matchLocalInst, chooseInstance ) |
| 14 | 14 | import GHC.Tc.Solver.Monad
|
| 15 | 15 | import GHC.Tc.Types.Evidence
|
| 16 | 16 | |
| 17 | -import GHC.Core.Coercion
|
|
| 18 | - |
|
| 19 | 17 | import GHC.Types.Basic( SwapFlag(..) )
|
| 20 | 18 | |
| 21 | 19 | import GHC.Utils.Outputable
|
| 20 | +import GHC.Utils.Panic
|
|
| 22 | 21 | |
| 23 | 22 | import GHC.Data.Bag
|
| 24 | 23 | |
| ... | ... | @@ -69,9 +68,9 @@ try_inert_irreds inerts irred_w@(IrredCt { ir_ev = ev_w, ir_reason = reason }) |
| 69 | 68 | vcat [ text "wanted:" <+> (ppr ct_w $$ ppr (ctOrigin ct_w))
|
| 70 | 69 | , text "inert: " <+> (ppr ct_i $$ ppr (ctOrigin ct_i)) ]
|
| 71 | 70 | ; case solveOneFromTheOther ct_i ct_w of
|
| 72 | - KeepInert -> do { setEvBindIfWanted ev_w EvCanonical (swap_me swap ev_i)
|
|
| 71 | + KeepInert -> do { setIrredIfWanted ev_w swap ev_i
|
|
| 73 | 72 | ; return (Stop ev_w (text "Irred equal:KeepInert" <+> ppr ct_w)) }
|
| 74 | - KeepWork -> do { setEvBindIfWanted ev_i EvCanonical (swap_me swap ev_w)
|
|
| 73 | + KeepWork -> do { setIrredIfWanted ev_i swap ev_w
|
|
| 75 | 74 | ; updInertCans (updIrreds (\_ -> others))
|
| 76 | 75 | ; continueWith () } }
|
| 77 | 76 | |
| ... | ... | @@ -81,12 +80,19 @@ try_inert_irreds inerts irred_w@(IrredCt { ir_ev = ev_w, ir_reason = reason }) |
| 81 | 80 | where
|
| 82 | 81 | ct_w = CIrredCan irred_w
|
| 83 | 82 | |
| 84 | - swap_me :: SwapFlag -> CtEvidence -> EvTerm
|
|
| 85 | - swap_me swap ev
|
|
| 86 | - = case swap of
|
|
| 87 | - NotSwapped -> ctEvTerm ev
|
|
| 88 | - IsSwapped -> evCoercion (mkSymCo (evTermCoercion (ctEvTerm ev)))
|
|
| 89 | - |
|
| 83 | +setIrredIfWanted :: CtEvidence -> SwapFlag -> CtEvidence -> TcS ()
|
|
| 84 | +-- Irreds can be equalities or dictionaries
|
|
| 85 | +setIrredIfWanted ev_dest swap ev_source
|
|
| 86 | + | CtWanted (WantedCt { ctev_dest = dest }) <- ev_dest
|
|
| 87 | + = case dest of
|
|
| 88 | + HoleDest {} -> setWantedEq dest (ctEvRewriterSet ev_source)
|
|
| 89 | + (maybeSymCo swap (ctEvCoercion ev_source))
|
|
| 90 | + |
|
| 91 | + EvVarDest {} -> assertPpr (swap==NotSwapped) (ppr ev_dest $$ ppr ev_source) $
|
|
| 92 | + -- findMatchingIrreds only returns IsSwapped for equalities
|
|
| 93 | + setWantedDict dest EvCanonical (ctEvTerm ev_source)
|
|
| 94 | + | otherwise
|
|
| 95 | + = return ()
|
|
| 90 | 96 | |
| 91 | 97 | {- Note [Multiple matching irreds]
|
| 92 | 98 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -50,13 +50,12 @@ module GHC.Tc.Solver.Monad ( |
| 50 | 50 | CanonicalEvidence(..),
|
| 51 | 51 | |
| 52 | 52 | newTcEvBinds, newNoTcEvBinds,
|
| 53 | - newWantedEq, emitNewWantedEq,
|
|
| 53 | + newWantedEq,
|
|
| 54 | 54 | newWanted,
|
| 55 | 55 | newWantedNC, newWantedEvVarNC,
|
| 56 | 56 | newBoundEvVarId,
|
| 57 | 57 | unifyTyVar, reportFineGrainUnifications, reportCoarseGrainUnifications,
|
| 58 | - setEvBind, setWantedEq, setWantedDict,
|
|
| 59 | - setWantedEvTerm, setEvBindIfWanted,
|
|
| 58 | + setEvBind, setWantedEq, setWantedDict, setEqIfWanted, setDictIfWanted,
|
|
| 60 | 59 | newEvVar, newGivenEv, emitNewGivens,
|
| 61 | 60 | emitChildEqs, checkReductionDepth,
|
| 62 | 61 | |
| ... | ... | @@ -1209,12 +1208,28 @@ setTcLevelTcS :: TcLevel -> TcS a -> TcS a |
| 1209 | 1208 | setTcLevelTcS lvl (TcS thing_inside)
|
| 1210 | 1209 | = TcS $ \ env -> TcM.setTcLevel lvl (thing_inside env)
|
| 1211 | 1210 | |
| 1211 | +{- Note [nestImplicTcS]
|
|
| 1212 | +~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1213 | +`nestImplicTcS` is used to build a nested scope when we begin solving an implication.
|
|
| 1214 | + |
|
| 1215 | +(NI1) One subtle point is that `nestImplicTcS` uses `resetInertCans` to
|
|
| 1216 | + initialise the `InertSet` of the nested scope to the `inert_givens` (/not/
|
|
| 1217 | + the `inert_cans`) of the current inert set. It is super-important not to
|
|
| 1218 | + pollute the sub-solving problem with the unsolved Wanteds of the current
|
|
| 1219 | + scope.
|
|
| 1220 | + |
|
| 1221 | + Whenever we do `solveSimpleGivens`, we snapshot the `inert_cans` into `inert_givens`.
|
|
| 1222 | + (At that moment there should be no Wanteds.)
|
|
| 1223 | +-}
|
|
| 1224 | + |
|
| 1212 | 1225 | nestImplicTcS :: SkolemInfoAnon -> EvBindsVar
|
| 1213 | 1226 | -> TcLevel -> TcS a
|
| 1214 | 1227 | -> TcS a
|
| 1228 | +-- See Note [nestImplicTcS]
|
|
| 1215 | 1229 | nestImplicTcS skol_info ev_binds_var inner_tclvl (TcS thing_inside)
|
| 1216 | 1230 | = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var }) ->
|
| 1217 | - do { nest_inert <- mk_nested_inert_set skol_info old_inert_var
|
|
| 1231 | + do { old_inerts <- TcM.readTcRef old_inert_var
|
|
| 1232 | + ; let nest_inert = mk_nested_inerts old_inerts
|
|
| 1218 | 1233 | ; new_inert_var <- TcM.newTcRef nest_inert
|
| 1219 | 1234 | ; new_wl_var <- TcM.newTcRef emptyWorkList
|
| 1220 | 1235 | ; let nest_env = env { tcs_ev_binds = ev_binds_var
|
| ... | ... | @@ -1233,24 +1248,18 @@ nestImplicTcS skol_info ev_binds_var inner_tclvl (TcS thing_inside) |
| 1233 | 1248 | #endif
|
| 1234 | 1249 | ; return res }
|
| 1235 | 1250 | where
|
| 1236 | - mk_nested_inert_set skol_info old_inert_var
|
|
| 1251 | + mk_nested_inerts old_inerts
|
|
| 1237 | 1252 | -- For an implication that comes from a static form (static e),
|
| 1238 | 1253 | -- start with a completely empty inert set; in particular, no Givens
|
| 1239 | 1254 | -- See (SF3) in Note [Grand plan for static forms]
|
| 1240 | 1255 | -- in GHC.Iface.Tidy.StaticPtrTable
|
| 1241 | 1256 | | StaticFormSkol <- skol_info
|
| 1242 | - = return (emptyInertSet inner_tclvl)
|
|
| 1257 | + = emptyInertSet inner_tclvl
|
|
| 1243 | 1258 | |
| 1244 | 1259 | | otherwise
|
| 1245 | - = do { inerts <- TcM.readTcRef old_inert_var
|
|
| 1246 | - |
|
| 1247 | - -- resetInertCans: initialise the inert_cans from the inert_givens of the
|
|
| 1248 | - -- parent so that the child is not polluted with the parent's inert Wanteds
|
|
| 1249 | - -- See Note [trySolveImplication] in GHC.Tc.Solver.Solve
|
|
| 1250 | - -- All other InertSet fields are inherited
|
|
| 1251 | - ; return (pushCycleBreakerVarStack $
|
|
| 1252 | - resetInertCans $
|
|
| 1253 | - inerts) }
|
|
| 1260 | + = pushCycleBreakerVarStack $
|
|
| 1261 | + resetInertCans $ -- See (NI1) in Note [nestImplicTcS]
|
|
| 1262 | + old_inerts
|
|
| 1254 | 1263 | |
| 1255 | 1264 | nestFunDepsTcS :: TcS a -> TcS a
|
| 1256 | 1265 | nestFunDepsTcS (TcS thing_inside)
|
| ... | ... | @@ -1950,64 +1959,40 @@ addUsedCoercion co |
| 1950 | 1959 | = do { ev_binds_var <- getTcEvBindsVar
|
| 1951 | 1960 | ; wrapTcS (TcM.updTcRef (ebv_tcvs ev_binds_var) (co :)) }
|
| 1952 | 1961 | |
| 1962 | +setEqIfWanted :: CtEvidence -> RewriterSet -> TcCoercion -> TcS ()
|
|
| 1963 | +setEqIfWanted ev rewriters co
|
|
| 1964 | + = case ev of
|
|
| 1965 | + CtWanted (WantedCt { ctev_dest = dest })
|
|
| 1966 | + -> setWantedEq dest rewriters co
|
|
| 1967 | + _ -> return ()
|
|
| 1968 | + |
|
| 1953 | 1969 | setWantedEq :: HasDebugCallStack => TcEvDest -> RewriterSet -> TcCoercion -> TcS ()
|
| 1954 | 1970 | -- ^ Equalities only
|
| 1955 | -setWantedEq (HoleDest hole) rewriters co
|
|
| 1956 | - = do { addUsedCoercion co
|
|
| 1957 | - ; fillCoercionHole hole rewriters co }
|
|
| 1958 | -setWantedEq (EvVarDest ev) _ _ = pprPanic "setWantedEq: EvVarDest" (ppr ev)
|
|
| 1971 | +setWantedEq dest rewriters co
|
|
| 1972 | + = case dest of
|
|
| 1973 | + HoleDest hole -> fillCoercionHole hole rewriters co
|
|
| 1974 | + EvVarDest ev -> pprPanic "setWantedEq: EvVarDest" (ppr ev)
|
|
| 1975 | + |
|
| 1976 | +setDictIfWanted :: CtEvidence -> CanonicalEvidence -> EvTerm -> TcS ()
|
|
| 1977 | +setDictIfWanted ev canonical tm
|
|
| 1978 | + = case ev of
|
|
| 1979 | + CtWanted (WantedCt { ctev_dest = dest })
|
|
| 1980 | + -> setWantedDict dest canonical tm
|
|
| 1981 | + _ -> return ()
|
|
| 1959 | 1982 | |
| 1960 | 1983 | setWantedDict :: TcEvDest -> CanonicalEvidence -> EvTerm -> TcS ()
|
| 1961 | 1984 | -- ^ Dictionaries only
|
| 1962 | -setWantedDict (EvVarDest ev_id) canonical tm
|
|
| 1963 | - = setEvBind (mkWantedEvBind ev_id canonical tm)
|
|
| 1964 | -setWantedDict (HoleDest h) _ _ = pprPanic "setWantedEq: HoleDest" (ppr h)
|
|
| 1965 | - |
|
| 1966 | -setWantedEvTerm :: TcEvDest -> RewriterSet -> CanonicalEvidence -> EvTerm -> TcS ()
|
|
| 1967 | --- ^ Good for both equalities and non-equalities
|
|
| 1968 | -setWantedEvTerm (EvVarDest ev_id) _rewriters canonical tm
|
|
| 1969 | - = setEvBind (mkWantedEvBind ev_id canonical tm)
|
|
| 1970 | -setWantedEvTerm (HoleDest hole) rewriters _canonical tm
|
|
| 1971 | - | Just co <- evTermCoercion_maybe tm
|
|
| 1972 | - = do { addUsedCoercion co
|
|
| 1973 | - ; fillCoercionHole hole rewriters co }
|
|
| 1974 | - | otherwise
|
|
| 1975 | - = -- See Note [Yukky eq_sel for a HoleDest]
|
|
| 1976 | - do { let co_var = coHoleCoVar hole
|
|
| 1977 | - ; setEvBind (mkWantedEvBind co_var EvCanonical tm)
|
|
| 1978 | - ; fillCoercionHole hole rewriters (mkCoVarCo co_var) }
|
|
| 1979 | - |
|
| 1980 | -{- Note [Yukky eq_sel for a HoleDest]
|
|
| 1981 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1982 | -How can it be that a Wanted with HoleDest gets evidence that isn't
|
|
| 1983 | -just a coercion? i.e. evTermCoercion_maybe returns Nothing.
|
|
| 1984 | - |
|
| 1985 | -Consider [G] forall a. blah => a ~ T
|
|
| 1986 | - [W] S ~# T
|
|
| 1987 | - |
|
| 1988 | -Then doTopReactEqPred carefully looks up the (boxed) constraint (S ~ T)
|
|
| 1989 | -in the quantified constraints, and wraps the (boxed) evidence it
|
|
| 1990 | -gets back in an eq_sel to extract the unboxed (S ~# T). We can't put
|
|
| 1991 | -that term into a coercion, so we add a value binding
|
|
| 1992 | - h = eq_sel (...)
|
|
| 1993 | -and the coercion variable h to fill the coercion hole.
|
|
| 1994 | -We even re-use the CoHole's Id for this binding!
|
|
| 1995 | - |
|
| 1996 | -Yuk!
|
|
| 1997 | --}
|
|
| 1985 | +setWantedDict dest canonical tm
|
|
| 1986 | + = case dest of
|
|
| 1987 | + EvVarDest ev_id -> setEvBind (mkWantedEvBind ev_id canonical tm)
|
|
| 1988 | + HoleDest h -> pprPanic "setWantedEq: HoleDest" (ppr h)
|
|
| 1998 | 1989 | |
| 1999 | 1990 | fillCoercionHole :: CoercionHole -> RewriterSet -> Coercion -> TcS ()
|
| 2000 | 1991 | fillCoercionHole hole rewriters co
|
| 2001 | - = do { wrapTcS $ TcM.fillCoercionHole hole (co, rewriters)
|
|
| 1992 | + = do { addUsedCoercion co
|
|
| 1993 | + ; wrapTcS $ TcM.fillCoercionHole hole (co, rewriters)
|
|
| 2002 | 1994 | ; kickOutAfterFillingCoercionHole hole rewriters }
|
| 2003 | 1995 | |
| 2004 | -setEvBindIfWanted :: CtEvidence -> CanonicalEvidence -> EvTerm -> TcS ()
|
|
| 2005 | -setEvBindIfWanted ev canonical tm
|
|
| 2006 | - = case ev of
|
|
| 2007 | - CtWanted (WantedCt { ctev_dest = dest, ctev_rewriters = rewriters })
|
|
| 2008 | - -> setWantedEvTerm dest rewriters canonical tm
|
|
| 2009 | - _ -> return ()
|
|
| 2010 | - |
|
| 2011 | 1996 | newTcEvBinds :: TcS EvBindsVar
|
| 2012 | 1997 | newTcEvBinds = wrapTcS TcM.newTcEvBinds
|
| 2013 | 1998 | |
| ... | ... | @@ -2019,9 +2004,11 @@ newEvVar pred = wrapTcS (TcM.newEvVar pred) |
| 2019 | 2004 | |
| 2020 | 2005 | newGivenEv :: CtLoc -> (TcPredType, EvTerm) -> TcS GivenCtEvidence
|
| 2021 | 2006 | -- Make a new variable of the given PredType,
|
| 2022 | --- immediately bind it to the given term
|
|
| 2023 | --- and return its CtEvidence
|
|
| 2007 | +-- immediately bind it to the given term, and return its CtEvidence
|
|
| 2024 | 2008 | -- See Note [Bind new Givens immediately] in GHC.Tc.Types.Constraint
|
| 2009 | +--
|
|
| 2010 | +-- The `pred` can be an /equality predicate/ t1 ~# t2;
|
|
| 2011 | +-- see (EQC1) in Note [Solving equality classes] in GHC.Tc.Solver.Dict
|
|
| 2025 | 2012 | newGivenEv loc (pred, rhs)
|
| 2026 | 2013 | = do { new_ev <- newBoundEvVarId pred rhs
|
| 2027 | 2014 | ; return $ GivenCt { ctev_pred = pred, ctev_evar = new_ev, ctev_loc = loc } }
|
| ... | ... | @@ -2044,13 +2031,6 @@ emitNewGivens loc pts |
| 2044 | 2031 | , not (ty1 `tcEqType` ty2) ] -- Kill reflexive Givens at birth
|
| 2045 | 2032 | ; emitWorkNC (map CtGiven gs) }
|
| 2046 | 2033 | |
| 2047 | -emitNewWantedEq :: CtLoc -> RewriterSet -> Role -> TcType -> TcType -> TcS Coercion
|
|
| 2048 | --- | Emit a new Wanted equality into the work-list
|
|
| 2049 | -emitNewWantedEq loc rewriters role ty1 ty2
|
|
| 2050 | - = do { (wtd, co) <- newWantedEq loc rewriters role ty1 ty2
|
|
| 2051 | - ; updWorkListTcS (extendWorkListEq rewriters (mkNonCanonical $ CtWanted wtd))
|
|
| 2052 | - ; return co }
|
|
| 2053 | - |
|
| 2054 | 2034 | emitChildEqs :: CtEvidence -> Cts -> TcS ()
|
| 2055 | 2035 | -- Emit a bunch of equalities into the work list
|
| 2056 | 2036 | -- See Note [Work-list ordering] in GHC.Tc.Solver.Equality
|
| ... | ... | @@ -2067,14 +2047,14 @@ emitChildEqs ev eqs |
| 2067 | 2047 | -- | Create a new Wanted constraint holding a coercion hole
|
| 2068 | 2048 | -- for an equality between the two types at the given 'Role'.
|
| 2069 | 2049 | newWantedEq :: CtLoc -> RewriterSet -> Role -> TcType -> TcType
|
| 2070 | - -> TcS (WantedCtEvidence, Coercion)
|
|
| 2050 | + -> TcS (WantedCtEvidence, CoercionHole)
|
|
| 2071 | 2051 | newWantedEq loc rewriters role ty1 ty2
|
| 2072 | 2052 | = do { hole <- wrapTcS $ TcM.newCoercionHole pty
|
| 2073 | 2053 | ; let wtd = WantedCt { ctev_pred = pty
|
| 2074 | 2054 | , ctev_dest = HoleDest hole
|
| 2075 | 2055 | , ctev_loc = loc
|
| 2076 | 2056 | , ctev_rewriters = rewriters }
|
| 2077 | - ; return (wtd, mkHoleCo hole) }
|
|
| 2057 | + ; return (wtd, hole) }
|
|
| 2078 | 2058 | where
|
| 2079 | 2059 | pty = mkEqPredRole role ty1 ty2
|
| 2080 | 2060 | |
| ... | ... | @@ -2214,10 +2194,11 @@ uPairsTcM uenv eqns = mapM_ (\(Pair ty1 ty2) -> uType uenv ty1 ty2) eqns |
| 2214 | 2194 | |
| 2215 | 2195 | wrapUnifierAndEmit :: CtEvidence -> Role
|
| 2216 | 2196 | -> (UnifyEnv -> TcM a) -- Some calls to uType
|
| 2217 | - -> TcS a
|
|
| 2197 | + -> TcS (a, RewriterSet)
|
|
| 2218 | 2198 | -- Like wrapUnifier, but
|
| 2219 | 2199 | -- emits any unsolved equalities into the work-list
|
| 2220 | 2200 | -- kicks out any inert constraints that mention unified variables
|
| 2201 | +-- returns a RewriterSet describing the new unsolved goals
|
|
| 2221 | 2202 | wrapUnifierAndEmit ev role do_unifications
|
| 2222 | 2203 | = do { (unifs, (res, eqs)) <- reportFineGrainUnifications $
|
| 2223 | 2204 | wrapUnifier ev role do_unifications
|
| ... | ... | @@ -2228,7 +2209,7 @@ wrapUnifierAndEmit ev role do_unifications |
| 2228 | 2209 | -- Kick out any inert constraints mentioning the unified variables
|
| 2229 | 2210 | ; kickOutAfterUnification unifs
|
| 2230 | 2211 | |
| 2231 | - ; return res }
|
|
| 2212 | + ; return (res, rewriterSetFromCts eqs) }
|
|
| 2232 | 2213 | |
| 2233 | 2214 | wrapUnifier :: CtEvidence -> Role
|
| 2234 | 2215 | -> (UnifyEnv -> TcM a) -- Some calls to uType
|
| ... | ... | @@ -7,7 +7,6 @@ module GHC.Tc.Solver.Solve ( |
| 7 | 7 | solveWanteds, -- Solves WantedConstraints
|
| 8 | 8 | solveSimpleGivens, -- Solves [Ct]
|
| 9 | 9 | solveSimpleWanteds, -- Solves Cts
|
| 10 | - trySolveImplication,
|
|
| 11 | 10 | |
| 12 | 11 | setImplicationStatus
|
| 13 | 12 | ) where
|
| ... | ... | @@ -369,35 +368,6 @@ solveNestedImplications implics |
| 369 | 368 | |
| 370 | 369 | ; return unsolved_implics }
|
| 371 | 370 | |
| 372 | -{- Note [trySolveImplication]
|
|
| 373 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 374 | -`trySolveImplication` may be invoked while solving simple wanteds, notably from
|
|
| 375 | -`solveWantedForAll`. It returns a Bool to say if solving succeeded or failed.
|
|
| 376 | - |
|
| 377 | -It uses `nestImplicTcS` to build a nested scope. One subtle point is that
|
|
| 378 | -`nestImplicTcS` uses the `inert_givens` (not the `inert_cans`) of the current
|
|
| 379 | -inert set to initialse the `InertSet` of the nested scope. It is super-important not
|
|
| 380 | -to pollute the sub-solving problem with the unsolved Wanteds of the current scope.
|
|
| 381 | - |
|
| 382 | -Whenever we do `solveSimpleGivens`, we snapshot the `inert_cans` into `inert_givens`.
|
|
| 383 | -(At that moment there should be no Wanteds.)
|
|
| 384 | --}
|
|
| 385 | - |
|
| 386 | -trySolveImplication :: Implication -> TcS Bool
|
|
| 387 | --- See Note [trySolveImplication]
|
|
| 388 | -trySolveImplication (Implic { ic_tclvl = tclvl
|
|
| 389 | - , ic_binds = ev_binds_var
|
|
| 390 | - , ic_given = given_ids
|
|
| 391 | - , ic_wanted = wanteds
|
|
| 392 | - , ic_env = ct_loc_env
|
|
| 393 | - , ic_info = info })
|
|
| 394 | - = nestImplicTcS info ev_binds_var tclvl $
|
|
| 395 | - do { let loc = mkGivenLoc tclvl info ct_loc_env
|
|
| 396 | - givens = mkGivens loc given_ids
|
|
| 397 | - ; solveSimpleGivens givens
|
|
| 398 | - ; residual_wanted <- solveWanteds wanteds
|
|
| 399 | - ; return (isSolvedWC residual_wanted) }
|
|
| 400 | - |
|
| 401 | 371 | solveImplication :: Implication -- Wanted
|
| 402 | 372 | -> TcS Implication -- Simplified implication
|
| 403 | 373 | -- Precondition: The TcS monad contains an empty worklist and given-only inerts
|
| ... | ... | @@ -1091,7 +1061,7 @@ solveSimpleGivens givens |
| 1091 | 1061 | |
| 1092 | 1062 | -- Capture the Givens in the inert_givens of the inert set
|
| 1093 | 1063 | -- for use by subsequent calls of nestImplicTcS
|
| 1094 | - -- See Note [trySolveImplication]
|
|
| 1064 | + -- See Note [nestImplicTcS] in GHc.Tc.Solver.Monad
|
|
| 1095 | 1065 | ; updInertSet (\is -> is { inert_givens = inert_cans is })
|
| 1096 | 1066 | |
| 1097 | 1067 | ; cans <- getInertCans
|
| ... | ... | @@ -1273,7 +1243,7 @@ solveCt (CEqCan (EqCt { eq_ev = ev, eq_eq_rel = eq_rel |
| 1273 | 1243 | = solveEquality ev eq_rel (canEqLHSType lhs) rhs
|
| 1274 | 1244 | |
| 1275 | 1245 | solveCt (CQuantCan qci@(QCI { qci_ev = ev }))
|
| 1276 | - = do { ev' <- rewriteEvidence ev
|
|
| 1246 | + = do { ev' <- rewriteDictEvidence ev
|
|
| 1277 | 1247 | -- It is (much) easier to rewrite and re-classify than to
|
| 1278 | 1248 | -- rewrite the pieces and build a Reduction that will rewrite
|
| 1279 | 1249 | -- the whole constraint
|
| ... | ... | @@ -1284,7 +1254,7 @@ solveCt (CQuantCan qci@(QCI { qci_ev = ev })) |
| 1284 | 1254 | _ -> pprPanic "SolveCt" (ppr ev) }
|
| 1285 | 1255 | |
| 1286 | 1256 | solveCt (CDictCan (DictCt { di_ev = ev, di_pend_sc = pend_sc }))
|
| 1287 | - = do { ev <- rewriteEvidence ev
|
|
| 1257 | + = do { ev <- rewriteDictEvidence ev
|
|
| 1288 | 1258 | -- It is easier to rewrite and re-classify than to rewrite
|
| 1289 | 1259 | -- the pieces and build a Reduction that will rewrite the
|
| 1290 | 1260 | -- whole constraint
|
| ... | ... | @@ -1309,7 +1279,7 @@ solveNC ev |
| 1309 | 1279 | _ ->
|
| 1310 | 1280 | |
| 1311 | 1281 | -- Do rewriting on the constraint, especially zonking
|
| 1312 | - do { ev <- rewriteEvidence ev
|
|
| 1282 | + do { ev <- rewriteDictEvidence ev
|
|
| 1313 | 1283 | |
| 1314 | 1284 | -- And then re-classify
|
| 1315 | 1285 | ; case classifyPredType (ctEvPred ev) of
|
| ... | ... | @@ -1582,7 +1552,7 @@ try_inert_qcs (QCI { qci_ev = ev_w }) inerts = |
| 1582 | 1552 | ; continueWith () }
|
| 1583 | 1553 | ev_i:_ ->
|
| 1584 | 1554 | do { traceTcS "tryInertQCs:KeepInert" (ppr ev_i)
|
| 1585 | - ; setEvBindIfWanted ev_w EvCanonical (ctEvTerm ev_i)
|
|
| 1555 | + ; setDictIfWanted ev_w EvCanonical (ctEvTerm ev_i)
|
|
| 1586 | 1556 | ; stopWith ev_w "Solved Wanted forall-constraint from inert" }
|
| 1587 | 1557 | where
|
| 1588 | 1558 | matching_inert (QCI { qci_ev = ev_i })
|
| ... | ... | @@ -1689,10 +1659,12 @@ solveWantedQCI _ ct = return (Left ct) |
| 1689 | 1659 | ************************************************************************
|
| 1690 | 1660 | -}
|
| 1691 | 1661 | |
| 1692 | -rewriteEvidence :: CtEvidence -> SolverStage CtEvidence
|
|
| 1693 | --- (rewriteEvidence old_ev new_pred co do_next)
|
|
| 1662 | +rewriteDictEvidence :: CtEvidence -> SolverStage CtEvidence
|
|
| 1663 | +-- (rewriteDictEvidence old_ev new_pred co do_next)
|
|
| 1694 | 1664 | -- Main purpose: create new evidence for new_pred;
|
| 1695 | 1665 | -- unless new_pred is cached already
|
| 1666 | +-- Precondition: new_pred is not an equality: the evidence is a term-level
|
|
| 1667 | +-- thing, hence "Dict".
|
|
| 1696 | 1668 | -- * Calls do_next with (new_ev :: new_pred), with same wanted/given flag as old_ev
|
| 1697 | 1669 | -- * If old_ev was wanted, create a binding for old_ev, in terms of new_ev
|
| 1698 | 1670 | -- * If old_ev was given, AND not cached, create a binding for new_ev, in terms of old_ev
|
| ... | ... | @@ -1723,8 +1695,8 @@ the rewriter set. We check this with an assertion. |
| 1723 | 1695 | -}
|
| 1724 | 1696 | |
| 1725 | 1697 | |
| 1726 | -rewriteEvidence ev
|
|
| 1727 | - = Stage $ do { traceTcS "rewriteEvidence" (ppr ev)
|
|
| 1698 | +rewriteDictEvidence ev
|
|
| 1699 | + = Stage $ do { traceTcS "rewriteDictEvidence" (ppr ev)
|
|
| 1728 | 1700 | ; (redn, rewriters) <- rewrite ev (ctEvPred ev)
|
| 1729 | 1701 | ; finish_rewrite ev redn rewriters }
|
| 1730 | 1702 | |
| ... | ... | @@ -1761,8 +1733,8 @@ finish_rewrite |
| 1761 | 1733 | ev_rw_role = ctEvRewriteRole ev
|
| 1762 | 1734 | ; mb_new_ev <- newWanted loc rewriters' new_pred
|
| 1763 | 1735 | ; massert (coercionRole co == ev_rw_role)
|
| 1764 | - ; setWantedEvTerm dest rewriters' EvCanonical $
|
|
| 1765 | - evCast (getEvExpr mb_new_ev) $
|
|
| 1736 | + ; setWantedDict dest EvCanonical $
|
|
| 1737 | + evCast (getEvExpr mb_new_ev) $
|
|
| 1766 | 1738 | downgradeRole Representational ev_rw_role (mkSymCo co)
|
| 1767 | 1739 | ; case mb_new_ev of
|
| 1768 | 1740 | Fresh new_ev -> continueWith $ CtWanted new_ev
|
| ... | ... | @@ -1826,17 +1798,22 @@ runTcPluginsWanted wanted |
| 1826 | 1798 | listToBag unsolved_wanted `andCts`
|
| 1827 | 1799 | listToBag insols
|
| 1828 | 1800 | |
| 1829 | - ; mapM_ setEv solved_wanted
|
|
| 1801 | + ; mapM_ setPluginEv solved_wanted
|
|
| 1830 | 1802 | |
| 1831 | 1803 | ; traceTcS "Finished plugins }" (ppr new_wanted)
|
| 1832 | 1804 | ; return ( notNull (pluginNewCts p), all_new_wanted ) } }
|
| 1833 | - where
|
|
| 1834 | - setEv :: (EvTerm,Ct) -> TcS ()
|
|
| 1835 | - setEv (ev,ct) = case ctEvidence ct of
|
|
| 1836 | - CtWanted (WantedCt { ctev_dest = dest, ctev_rewriters = rewriters })
|
|
| 1837 | - -> setWantedEvTerm dest rewriters EvCanonical ev
|
|
| 1838 | - -- TODO: plugins should be able to signal non-canonicity
|
|
| 1839 | - _ -> panic "runTcPluginsWanted.setEv: attempt to solve non-wanted!"
|
|
| 1805 | + |
|
| 1806 | +setPluginEv :: (EvTerm,Ct) -> TcS ()
|
|
| 1807 | +setPluginEv (tm,ct)
|
|
| 1808 | + = case ctEvidence ct of
|
|
| 1809 | + CtWanted (WantedCt { ctev_dest = dest })
|
|
| 1810 | + -> case dest of
|
|
| 1811 | + EvVarDest {} -> setWantedDict dest EvCanonical tm
|
|
| 1812 | + -- TODO: plugins should be able to signal non-canonicity
|
|
| 1813 | + HoleDest {} -> setWantedEq dest emptyRewriterSet (evTermCoercion tm)
|
|
| 1814 | + -- TODO: should we try to track rewriters?
|
|
| 1815 | + |
|
| 1816 | + CtGiven {} -> panic "runTcPluginsWanted.setEv: attempt to solve non-wanted!"
|
|
| 1840 | 1817 | |
| 1841 | 1818 | -- | A pair of (given, wanted) constraints to pass to plugins
|
| 1842 | 1819 | type SplitCts = ([Ct], [Ct])
|
| 1 | 1 | module GHC.Tc.Solver.Solve where
|
| 2 | 2 | |
| 3 | -import Prelude( Bool )
|
|
| 4 | 3 | import GHC.Tc.Solver.Monad( TcS )
|
| 5 | -import GHC.Tc.Types.Constraint( Cts, Implication, WantedConstraints )
|
|
| 4 | +import GHC.Tc.Types.Constraint( Cts, WantedConstraints )
|
|
| 6 | 5 | |
| 7 | 6 | solveSimpleWanteds :: Cts -> TcS WantedConstraints |
| 8 | -trySolveImplication :: Implication -> TcS Bool |
| ... | ... | @@ -80,7 +80,8 @@ module GHC.Tc.Types.Constraint ( |
| 80 | 80 | ctEvExpr, ctEvTerm,
|
| 81 | 81 | ctEvCoercion, givenCtEvCoercion,
|
| 82 | 82 | ctEvEvId, wantedCtEvEvId,
|
| 83 | - ctEvRewriters, setWantedCtEvRewriters, ctEvUnique, tcEvDestUnique,
|
|
| 83 | + ctEvRewriters, ctEvRewriterSet, setWantedCtEvRewriters,
|
|
| 84 | + ctEvUnique, tcEvDestUnique,
|
|
| 84 | 85 | ctEvRewriteRole, ctEvRewriteEqRel, setCtEvPredType, setCtEvLoc,
|
| 85 | 86 | tyCoVarsOfCtEvList, tyCoVarsOfCtEv, tyCoVarsOfCtEvsList,
|
| 86 | 87 | |
| ... | ... | @@ -2291,7 +2292,8 @@ For Givens we make new EvVars and bind them immediately. Two main reasons: |
| 2291 | 2292 | f :: C a b => ....
|
| 2292 | 2293 | Then in f's Givens we have g:(C a b) and the superclass sc(g,0):a~b.
|
| 2293 | 2294 | But that superclass selector can't (yet) appear in a coercion
|
| 2294 | - (see evTermCoercion), so the easy thing is to bind it to an Id.
|
|
| 2295 | + (see evTermCoercion), so the easy thing is to bind it to a (coercion) Id.
|
|
| 2296 | + This happens in GHC.Tc.Solver.Dict.solveEqualityDict.
|
|
| 2295 | 2297 | |
| 2296 | 2298 | So a Given has EvVar inside it rather than (as previously) an EvTerm.
|
| 2297 | 2299 | |
| ... | ... | @@ -2393,6 +2395,12 @@ wantedCtHasNoRewriters (WantedCt { ctev_rewriters = rws }) |
| 2393 | 2395 | setWantedCtEvRewriters :: WantedCtEvidence -> RewriterSet -> WantedCtEvidence
|
| 2394 | 2396 | setWantedCtEvRewriters ev rs = ev { ctev_rewriters = rs }
|
| 2395 | 2397 | |
| 2398 | +ctEvRewriterSet :: CtEvidence -> RewriterSet
|
|
| 2399 | +-- Returns the set of holes (empty or singleton) for the evidence itself
|
|
| 2400 | +-- Note the difference from ctEvRewriters!
|
|
| 2401 | +ctEvRewriterSet (CtWanted (WantedCt { ctev_dest = HoleDest hole })) = unitRewriterSet hole
|
|
| 2402 | +ctEvRewriterSet _ = emptyRewriterSet
|
|
| 2403 | + |
|
| 2396 | 2404 | rewriterSetFromCts :: Bag Ct -> RewriterSet
|
| 2397 | 2405 | -- Take a bag of Wanted equalities, and collect them as a RewriterSet
|
| 2398 | 2406 | rewriterSetFromCts cts
|
| ... | ... | @@ -2404,8 +2412,8 @@ rewriterSetFromCts cts |
| 2404 | 2412 | _ -> rw_set
|
| 2405 | 2413 | |
| 2406 | 2414 | ctEvExpr :: HasDebugCallStack => CtEvidence -> EvExpr
|
| 2407 | -ctEvExpr (CtWanted ev@(WantedCt { ctev_dest = HoleDest _ }))
|
|
| 2408 | - = Coercion $ ctEvCoercion (CtWanted ev)
|
|
| 2415 | +ctEvExpr (CtWanted (WantedCt { ctev_dest = HoleDest hole }))
|
|
| 2416 | + = Coercion $ mkHoleCo hole
|
|
| 2409 | 2417 | ctEvExpr ev = evId (ctEvEvId ev)
|
| 2410 | 2418 | |
| 2411 | 2419 | givenCtEvCoercion :: GivenCtEvidence -> TcCoercion
|
| ... | ... | @@ -13,7 +13,9 @@ class Class a where |
| 13 | 13 | data Data (xs::a) = X | Y
|
| 14 | 14 | deriving (Read,Show)
|
| 15 | 15 | main = print test1
|
| 16 | -instance (xs ~ Replicate1 ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Zero ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) ()) => Class (Data xs) where
|
|
| 16 | +-- instance (xs ~ Replicate1 ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Zero ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) ()) => Class (Data xs) where
|
|
| 17 | +instance (xs ~ Replicate1 ( Succ ( Succ ( Succ ( Succ ( Succ (Succ (Succ Zero ))))))) ()) => Class (Data xs) where
|
|
| 17 | 18 | f X = Y
|
| 18 | 19 | f Y = X
|
| 19 | -test1 = f (X :: Data ( Replicate1 ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Zero ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) () )) |
|
| 20 | +test1 = f (X :: Data ( Replicate1 ( Succ ( Succ ( Succ ( Succ (Succ (Succ (Succ Zero))))))) () ))
|
|
| 21 | +-- test1 = f (X :: Data ( Replicate1 ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Succ ( Zero ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) () )) |
| ... | ... | @@ -140,7 +140,8 @@ type Cube2 = Cube W G B W R R |
| 140 | 140 | type Cube3 = Cube G W R B R R
|
| 141 | 141 | type Cube4 = Cube B R G G W W
|
| 142 | 142 | |
| 143 | -type Cubes = Cons Cube1 (Cons Cube2 (Cons Cube3 (Cons Cube4 Nil)))
|
|
| 143 | +-- type Cubes = Cons Cube1 (Cons Cube2 (Cons Cube3 (Cons Cube4 Nil)))
|
|
| 144 | +type Cubes = Cons Cube1 Nil
|
|
| 144 | 145 | |
| 145 | 146 | type family Compatible c d :: *
|
| 146 | 147 | type instance Compatible (Cube u1 f1 r1 b1 l1 d1) (Cube u2 f2 r2 b2 l2 d2) =
|