Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
-
dc8360ef
by Simon Peyton Jones at 2025-09-11T13:59:30+01:00
10 changed files:
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Tc/Instance/FunDeps.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/Unify.hs
Changes:
| ... | ... | @@ -1282,6 +1282,7 @@ isNoParent _ = False |
| 1282 | 1282 | data Injectivity
|
| 1283 | 1283 | = NotInjective
|
| 1284 | 1284 | | Injective [Bool] -- 1-1 with tyConTyVars (incl kind vars)
|
| 1285 | + -- INVARIANT: not all False
|
|
| 1285 | 1286 | deriving( Eq )
|
| 1286 | 1287 | |
| 1287 | 1288 | -- | Information pertaining to the expansion of a type synonym (@type@)
|
| ... | ... | @@ -94,7 +94,7 @@ an equality for the RHS. |
| 94 | 94 | |
| 95 | 95 | Wrinkles:
|
| 96 | 96 | |
| 97 | -(1) meta_tvs: sometimes the instance mentions variables in the RHS that
|
|
| 97 | +(IMP1) fd_qtvs: sometimes the instance mentions variables in the RHS that
|
|
| 98 | 98 | are not bound in the LHS. For example
|
| 99 | 99 | |
| 100 | 100 | class C a b | a -> b
|
| ... | ... | @@ -109,7 +109,7 @@ Wrinkles: |
| 109 | 109 | Note that the fd_qtvs can be free in the /first/ component of the Pair,
|
| 110 | 110 | but not in the second (which comes from the [W] constraint).
|
| 111 | 111 | |
| 112 | -(2) Multi-range fundeps. When these meta_tvs are involved, there is a subtle
|
|
| 112 | +(IMP2) Multi-range fundeps. When these meta_tvs are involved, there is a subtle
|
|
| 113 | 113 | difference between the fundep (a -> b c) and the two fundeps (a->b, a->c).
|
| 114 | 114 | Consider
|
| 115 | 115 | class D a b c | a -> b c
|
| ... | ... | @@ -125,15 +125,15 @@ Wrinkles: |
| 125 | 125 | FDEqn { fd_qtvs = [x2], fd_eqs = [ Maybe x2 ~ ty ] }
|
| 126 | 126 | with two FDEqns, generating two separate unification variables.
|
| 127 | 127 | |
| 128 | -(3) improveFromInstEnv doesn't return any equations that already hold.
|
|
| 129 | - Reason: then we know if any actual improvement has happened, in
|
|
| 130 | - which case we need to iterate the solver
|
|
| 128 | +(IMP3) improveFromInstEnv doesn't return any equations that already hold.
|
|
| 129 | + Reason: just an optimisation; the caller does the same thing, but
|
|
| 130 | + with a bit more ceremony.
|
|
| 131 | 131 | -}
|
| 132 | 132 | |
| 133 | 133 | data FunDepEqn
|
| 134 | 134 | = FDEqn { fd_qtvs :: [TyVar] -- Instantiate these type and kind vars
|
| 135 | 135 | -- to fresh unification vars,
|
| 136 | - -- Non-empty only for FunDepEqns arising from instance decls
|
|
| 136 | + -- See (IMP2) in Note [Improving against instances]
|
|
| 137 | 137 | |
| 138 | 138 | , fd_eqs :: [TypeEqn] -- Make these pairs of types equal
|
| 139 | 139 | -- Invariant: In each (Pair ty1 ty2), the fd_qtvs may be
|
| ... | ... | @@ -193,7 +193,8 @@ zipAndComputeFDEqs :: (Type -> Type -> Bool) -- Discard this FDEq if true |
| 193 | 193 | -- Create a list of (Type,Type) pairs from two lists of types,
|
| 194 | 194 | -- making sure that the types are not already equal
|
| 195 | 195 | zipAndComputeFDEqs discard (ty1:tys1) (ty2:tys2)
|
| 196 | - | discard ty1 ty2 = zipAndComputeFDEqs discard tys1 tys2
|
|
| 196 | + | discard ty1 ty2 = -- See (IMP3) in Note [Improving against instances]
|
|
| 197 | + zipAndComputeFDEqs discard tys1 tys2
|
|
| 197 | 198 | | otherwise = Pair ty1 ty2 : zipAndComputeFDEqs discard tys1 tys2
|
| 198 | 199 | zipAndComputeFDEqs _ _ _ = []
|
| 199 | 200 |
| ... | ... | @@ -543,10 +543,9 @@ defaultEquality ct |
| 543 | 543 | -- This handles cases such as @IO alpha[tau] ~R# IO Int@
|
| 544 | 544 | -- by defaulting @alpha := Int@, which is useful in practice
|
| 545 | 545 | -- (see Note [Defaulting representational equalities]).
|
| 546 | - ; (co, new_eqs, _unifs) <-
|
|
| 547 | - wrapUnifierX (ctEvidence ct) Nominal $ \uenv ->
|
|
| 548 | - -- NB: nominal equality!
|
|
| 549 | - uType uenv z_ty1 z_ty2
|
|
| 546 | + ; (co, new_eqs) <- wrapUnifier (ctEvidence ct) Nominal $ \uenv ->
|
|
| 547 | + -- NB: nominal equality!
|
|
| 548 | + uType uenv z_ty1 z_ty2
|
|
| 550 | 549 | |
| 551 | 550 | -- Only accept this solution if no new equalities are produced
|
| 552 | 551 | -- by the unifier.
|
| ... | ... | @@ -473,8 +473,8 @@ solveEqualityDict ev cls tys |
| 473 | 473 | do { let (role, t1, t2) = matchEqualityInst cls tys
|
| 474 | 474 | -- Unify t1~t2, putting anything that can't be solved
|
| 475 | 475 | -- immediately into the work list
|
| 476 | - ; (co, _, _) <- wrapUnifierTcS ev role $ \uenv ->
|
|
| 477 | - uType uenv t1 t2
|
|
| 476 | + ; co <- wrapUnifierAndEmit ev role $ \uenv ->
|
|
| 477 | + uType uenv t1 t2
|
|
| 478 | 478 | -- Set d :: (t1~t2) = Eq# co
|
| 479 | 479 | ; setWantedEvTerm dest EvCanonical $
|
| 480 | 480 | evDictApp cls tys [Coercion co]
|
| ... | ... | @@ -544,7 +544,7 @@ can_eq_nc_forall ev eq_rel s1 s2 |
| 544 | 544 | -- Generate the constraints that live in the body of the implication
|
| 545 | 545 | -- See (SF5) in Note [Solving forall equalities]
|
| 546 | 546 | ; (lvl, (all_co, wanteds)) <- pushLevelNoWorkList (ppr skol_info) $
|
| 547 | - unifyForAllBody ev (eqRelRole eq_rel) $ \uenv ->
|
|
| 547 | + wrapUnifier ev (eqRelRole eq_rel) $ \uenv ->
|
|
| 548 | 548 | go uenv skol_tvs init_subst2 bndrs1 bndrs2
|
| 549 | 549 | |
| 550 | 550 | -- Solve the implication right away, using `trySolveImplication`
|
| ... | ... | @@ -634,9 +634,9 @@ There are lots of wrinkles of course: |
| 634 | 634 | |
| 635 | 635 | (SF5) Rather than manually gather the constraints needed in the body of the
|
| 636 | 636 | implication, we use `uType`. That way we can solve some of them on the fly,
|
| 637 | - especially Refl ones. We use the `unifyForAllBody` wrapper for `uType`,
|
|
| 637 | + especially Refl ones. We use the `wrapUnifier` wrapper for `uType`,
|
|
| 638 | 638 | because we want to /gather/ the equality constraint (to put in the implication)
|
| 639 | - rather than /emit/ them into the monad, as `wrapUnifierTcS` does.
|
|
| 639 | + rather than /emit/ them into the monad, as `wrapUnifierAndEmit` does.
|
|
| 640 | 640 | |
| 641 | 641 | (SF6) We solve the implication on the spot, using `trySolveImplication`. In
|
| 642 | 642 | the past we instead generated an `Implication` to be solved later. Nice in
|
| ... | ... | @@ -808,7 +808,7 @@ can_eq_app ev s1 t1 s2 t2 |
| 808 | 808 | = do { traceTcS "can_eq_app" (vcat [ text "s1:" <+> ppr s1, text "t1:" <+> ppr t1
|
| 809 | 809 | , text "s2:" <+> ppr s2, text "t2:" <+> ppr t2
|
| 810 | 810 | , text "vis:" <+> ppr (isNextArgVisible s1) ])
|
| 811 | - ; (co,_,_) <- wrapUnifierTcS ev Nominal $ \uenv ->
|
|
| 811 | + ; co <- wrapUnifierAndEmit ev Nominal $ \uenv ->
|
|
| 812 | 812 | -- Unify arguments t1/t2 before function s1/s2, because
|
| 813 | 813 | -- the former have smaller kinds, and hence simpler error messages
|
| 814 | 814 | -- c.f. GHC.Tc.Utils.Unify.uType (go_app)
|
| ... | ... | @@ -966,7 +966,7 @@ then we will just decompose s1~s2, and it might be better to |
| 966 | 966 | do so on the spot. An important special case is where s1=s2,
|
| 967 | 967 | and we get just Refl.
|
| 968 | 968 | |
| 969 | -So canDecomposableTyConAppOK uses wrapUnifierTcS etc to short-cut
|
|
| 969 | +So canDecomposableTyConAppOK uses wrapUnifierAndEmit etc to short-cut
|
|
| 970 | 970 | that work. See also Note [Work-list ordering].
|
| 971 | 971 | |
| 972 | 972 | Note [Decomposing TyConApp equalities]
|
| ... | ... | @@ -1090,7 +1090,7 @@ up in the complexities of canEqLHSHetero. To do this: |
| 1090 | 1090 | * `uType` keeps the bag of emitted constraints in the same
|
| 1091 | 1091 | left-to-right order. See the use of `snocBag` in `uType_defer`.
|
| 1092 | 1092 | |
| 1093 | -* `wrapUnifierTcS` adds the bag of deferred constraints from
|
|
| 1093 | +* `wrapUnifierAndEmit` adds the bag of deferred constraints from
|
|
| 1094 | 1094 | `do_unifications` to the work-list using `extendWorkListChildEqs`.
|
| 1095 | 1095 | |
| 1096 | 1096 | * `extendWorkListChildEqs` and `selectWorkItem` together arrange that the
|
| ... | ... | @@ -1394,7 +1394,7 @@ canDecomposableTyConAppOK ev eq_rel tc (ty1,tys1) (ty2,tys2) |
| 1394 | 1394 | -- new_locs and tc_roles are both infinite, so we are
|
| 1395 | 1395 | -- guaranteed that cos has the same length as tys1 and tys2
|
| 1396 | 1396 | -- See Note [Fast path when decomposing TyConApps]
|
| 1397 | - -> do { (co, _, _) <- wrapUnifierTcS ev role $ \uenv ->
|
|
| 1397 | + -> do { co <- wrapUnifierAndEmit ev role $ \uenv ->
|
|
| 1398 | 1398 | do { cos <- zipWith4M (u_arg uenv) new_locs tc_roles tys1 tys2
|
| 1399 | 1399 | -- zipWith4M: see Note [Work-list ordering]
|
| 1400 | 1400 | ; return (mkTyConAppCo role tc cos) }
|
| ... | ... | @@ -1449,7 +1449,7 @@ canDecomposableFunTy ev eq_rel af f1@(ty1,m1,a1,r1) f2@(ty2,m2,a2,r2) |
| 1449 | 1449 | (ppr ev $$ ppr eq_rel $$ ppr f1 $$ ppr f2)
|
| 1450 | 1450 | ; case ev of
|
| 1451 | 1451 | CtWanted (WantedCt { ctev_dest = dest })
|
| 1452 | - -> do { (co, _, _) <- wrapUnifierTcS ev Nominal $ \ uenv ->
|
|
| 1452 | + -> do { co <- wrapUnifierAndEmit ev Nominal $ \ uenv ->
|
|
| 1453 | 1453 | do { let mult_env = uenv `updUEnvLoc` toInvisibleLoc
|
| 1454 | 1454 | `setUEnvRole` funRole role SelMult
|
| 1455 | 1455 | ; mult <- uType mult_env m1 m2
|
| ... | ... | @@ -1694,12 +1694,18 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 |
| 1694 | 1694 | ; finish emptyRewriterSet (givenCtEvCoercion kind_ev) }
|
| 1695 | 1695 | |
| 1696 | 1696 | CtWanted {}
|
| 1697 | - -> do { (kind_co, cts, unifs) <- wrapUnifierTcS ev Nominal $ \uenv ->
|
|
| 1698 | - let uenv' = updUEnvLoc uenv (mkKindEqLoc xi1 xi2)
|
|
| 1699 | - in unSwap swapped (uType uenv') ki1 ki2
|
|
| 1697 | + -> do { (unifs, (kind_co, cts)) <- reportUnifications $
|
|
| 1698 | + wrapUnifier ev Nominal $ \uenv ->
|
|
| 1699 | + let uenv' = updUEnvLoc uenv (mkKindEqLoc xi1 xi2)
|
|
| 1700 | + in unSwap swapped (uType uenv') ki1 ki2
|
|
| 1700 | 1701 | -- mkKindEqLoc: any new constraints, arising from the kind
|
| 1701 | 1702 | -- unification, say they thay come from unifying xi1~xi2
|
| 1702 | - ; if not (null unifs)
|
|
| 1703 | + |
|
| 1704 | + -- Emit any unsolved kind equalities
|
|
| 1705 | + ; unless (isEmptyBag cts) $
|
|
| 1706 | + updWorkListTcS (extendWorkListChildEqs ev cts)
|
|
| 1707 | + |
|
| 1708 | + ; if unifs
|
|
| 1703 | 1709 | then -- Unifications happened, so start again to do the zonking
|
| 1704 | 1710 | -- Otherwise we might put something in the inert set that isn't inert
|
| 1705 | 1711 | startAgainWith (mkNonCanonical ev)
|
| ... | ... | @@ -2037,9 +2043,6 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs |
| 2037 | 2043 | ; setEvBindIfWanted new_ev EvCanonical $
|
| 2038 | 2044 | evCoercion (mkNomReflCo final_rhs)
|
| 2039 | 2045 | |
| 2040 | - -- Kick out any constraints that can now be rewritten
|
|
| 2041 | - ; recordUnification tv
|
|
| 2042 | - |
|
| 2043 | 2046 | ; return (Stop new_ev (text "Solved by unification")) }
|
| 2044 | 2047 | |
| 2045 | 2048 | ---------------------------
|
| ... | ... | @@ -2405,7 +2408,7 @@ FamAppBreaker. |
| 2405 | 2408 | Why TauTvs? See [Why TauTvs] below.
|
| 2406 | 2409 | |
| 2407 | 2410 | Critically, we emit the two new constraints (the last two above)
|
| 2408 | -directly instead of calling wrapUnifierTcS. (Otherwise, we'd end up
|
|
| 2411 | +directly instead of calling wrapUnifier. (Otherwise, we'd end up
|
|
| 2409 | 2412 | unifying cbv1 and cbv2 immediately, achieving nothing.) Next, we
|
| 2410 | 2413 | unify alpha := cbv1 -> cbv2, having eliminated the occurs check. This
|
| 2411 | 2414 | unification happens immediately following a successful call to
|
| ... | ... | @@ -20,7 +20,6 @@ import GHC.Tc.Utils.Unify( UnifyEnv(..) ) |
| 20 | 20 | import GHC.Tc.Utils.Monad as TcM
|
| 21 | 21 | import GHC.Tc.Types.Evidence
|
| 22 | 22 | import GHC.Tc.Types.Constraint
|
| 23 | -import GHC.Tc.Types.CtLoc
|
|
| 24 | 23 | |
| 25 | 24 | import GHC.Core.FamInstEnv
|
| 26 | 25 | import GHC.Core.Coercion
|
| ... | ... | @@ -39,27 +38,57 @@ import GHC.Utils.Misc( filterOut ) |
| 39 | 38 | import GHC.Data.Pair
|
| 40 | 39 | |
| 41 | 40 | |
| 42 | -{- *********************************************************************
|
|
| 43 | -* *
|
|
| 44 | -* Functional dependencies for dictionaries
|
|
| 45 | -* *
|
|
| 46 | -************************************************************************
|
|
| 41 | +{- Note [Overview of fundeps]
|
|
| 42 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 43 | +Here is our plan for dealing with functional dependencies
|
|
| 47 | 44 | |
| 48 | -When we spot an equality arising from a functional dependency,
|
|
| 49 | -we now use that equality (a "wanted") to rewrite the work-item
|
|
| 50 | -constraint right away. This avoids two dangers
|
|
| 45 | +* When we have failed to solve a Wanted constraint, do this
|
|
| 46 | + 1. Generate any fundep-equalities [FunDepEqn] from that constraint.
|
|
| 47 | + 2. Try to solve that [FunDepEqn]
|
|
| 48 | + 3. If any unifications happened, send the constraint back to the
|
|
| 49 | + start of the pipeline
|
|
| 51 | 50 | |
| 52 | - Danger 1: If we send the original constraint on down the pipeline
|
|
| 53 | - it may react with an instance declaration, and in delicate
|
|
| 54 | - situations (when a Given overlaps with an instance) that
|
|
| 55 | - may produce new insoluble goals: see #4952
|
|
| 51 | +* Step (1) How we generate those [FunDepEqn] varies:
|
|
| 52 | + - tryDictFunDeps: for class constraints (C t1 .. tn)
|
|
| 53 | + we look at top-level instances and inert Givens
|
|
| 54 | + - tryEqFunDeps: for type-family equalities (F t1 .. tn ~ ty)
|
|
| 55 | + we look at top-level family instances
|
|
| 56 | + and inert Given family equalities
|
|
| 56 | 57 | |
| 57 | - Danger 2: If we don't rewrite the constraint, it may re-react
|
|
| 58 | - with the same thing later, and produce the same equality
|
|
| 59 | - again --> termination worries.
|
|
| 58 | +* Step (2). We use `solveFunDeps` to solve the [FunDepEqn] in a nested
|
|
| 59 | + solver. Key property:
|
|
| 60 | + |
|
| 61 | + The ONLY effect of `solveFunDeps` is possibly to perform unifications:
|
|
| 60 | 62 | |
| 61 | -To achieve this required some refactoring of GHC.Tc.Instance.FunDeps (nicer
|
|
| 62 | -now!).
|
|
| 63 | + - It entirely discards any unsolved fundep equalities.
|
|
| 64 | + |
|
| 65 | + - Ite entirely discards any evidence arising from solving fundep equalities
|
|
| 66 | + |
|
| 67 | +* Step (3) if we did any unifications in Step (2), we start again with the
|
|
| 68 | + current unsolved Wanted. It might now be soluble!
|
|
| 69 | + |
|
| 70 | +* For Given constraints, things are different:
|
|
| 71 | + - tryDictFunDeps: we do nothing
|
|
| 72 | + - tryEqFunDeps: for type-family equalities, we can produce new
|
|
| 73 | + actual evidence for built-in type families. E.g.
|
|
| 74 | + [G] co : 3 ~ x + 1
|
|
| 75 | + We can produce new evidence
|
|
| 76 | + [G] co' : x ~ 2
|
|
| 77 | + So we generate and emit fresh Givens. See
|
|
| 78 | + `improveGivenTopFunEqs` and `improveGivenLocalFunEqs`
|
|
| 79 | + No unification is involved here, just emitting new Givens.
|
|
| 80 | + |
|
| 81 | +(FD1) Consequences for error messages.
|
|
| 82 | + Because we discard any unsolved FunDepEqns, we get better error messages.
|
|
| 83 | + Consider class C a b | a -> b
|
|
| 84 | + instance C Int Bool
|
|
| 85 | + and [W] C Int Char
|
|
| 86 | + We'll get an insoluble fundep-equality (Char ~ Bool), but it's very
|
|
| 87 | + unhelpful to report it. Much better just to say
|
|
| 88 | + No instance for C Int Bool
|
|
| 89 | + |
|
| 90 | + Similarly if had [W] C Int S, [W] C Int T, it is not helpful to
|
|
| 91 | + complain about insoluble (S ~ T).
|
|
| 63 | 92 | |
| 64 | 93 | Note [FunDep and implicit parameter reactions]
|
| 65 | 94 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -107,141 +136,65 @@ Then it is solvable, but its very hard to detect this on the spot. |
| 107 | 136 | It's exactly the same with implicit parameters, except that the
|
| 108 | 137 | "aggressive" approach would be much easier to implement.
|
| 109 | 138 | |
| 110 | -Note [Fundeps with instances, and equality orientation]
|
|
| 111 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 112 | -This Note describes a delicate interaction that constrains the orientation of
|
|
| 113 | -equalities. This one is about fundeps, but the /exact/ same thing arises for
|
|
| 114 | -type-family injectivity constraints: see Note [Improvement orientation].
|
|
| 115 | - |
|
| 116 | -doTopFunDepImprovement compares the constraint with all the instance
|
|
| 117 | -declarations, to see if we can produce any equalities. E.g
|
|
| 118 | - class C2 a b | a -> b
|
|
| 119 | - instance C Int Bool
|
|
| 120 | -Then the constraint (C Int ty) generates the equality [W] ty ~ Bool.
|
|
| 121 | - |
|
| 122 | -There is a nasty corner in #19415 which led to the typechecker looping:
|
|
| 123 | - class C s t b | s -> t
|
|
| 124 | - instance ... => C (T kx x) (T ky y) Int
|
|
| 125 | - T :: forall k. k -> Type
|
|
| 126 | - |
|
| 127 | - work_item: dwrk :: C (T @ka (a::ka)) (T @kb0 (b0::kb0)) Char
|
|
| 128 | - where kb0, b0 are unification vars
|
|
| 129 | - |
|
| 130 | - ==> {doTopFunDepImprovement: compare work_item with instance,
|
|
| 131 | - generate /fresh/ unification variables kfresh0, yfresh0,
|
|
| 132 | - emit a new Wanted, and add dwrk to inert set}
|
|
| 133 | - |
|
| 134 | - Suppose we emit this new Wanted from the fundep:
|
|
| 135 | - [W] T kb0 (b0::kb0) ~ T kfresh0 (yfresh0::kfresh0)
|
|
| 136 | - |
|
| 137 | - ==> {solve that equality kb0 := kfresh0, b0 := yfresh0}
|
|
| 138 | - Now kick out dwrk, since it mentions kb0
|
|
| 139 | - But now we are back to the start! Loop!
|
|
| 140 | - |
|
| 141 | -NB1: This example relies on an instance that does not satisfy the
|
|
| 142 | - coverage condition (although it may satisfy the weak coverage
|
|
| 143 | - condition), and hence whose fundeps generate fresh unification
|
|
| 144 | - variables. Not satisfying the coverage condition is known to
|
|
| 145 | - lead to termination trouble, but in this case it's plain silly.
|
|
| 146 | - |
|
| 147 | -NB2: In this example, the third parameter to C ensures that the
|
|
| 148 | - instance doesn't actually match the Wanted, so we can't use it to
|
|
| 149 | - solve the Wanted
|
|
| 150 | - |
|
| 151 | -We solve the problem by (#21703):
|
|
| 139 | +Note [Partial functional dependencies]
|
|
| 140 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 141 | +Consider this (#12522):
|
|
| 142 | + type family F x = t | t -> x
|
|
| 143 | + type instance F (a, Int) = (Int, G a)
|
|
| 144 | +where G is injective; and wanted constraints
|
|
| 145 | + [W] F (alpha, beta) ~ (Int, <some type>)
|
|
| 152 | 146 | |
| 153 | - carefully orienting the new Wanted so that all the
|
|
| 154 | - freshly-generated unification variables are on the LHS.
|
|
| 147 | +The injectivity will give rise to fundep equalities
|
|
| 148 | + [W] gamma1 ~ alpha
|
|
| 149 | + [W] Int ~ beta
|
|
| 155 | 150 | |
| 156 | - Thus we call unifyWanteds on
|
|
| 157 | - T kfresh0 (yfresh0::kfresh0) ~ T kb0 (b0::kb0)
|
|
| 158 | - and /NOT/
|
|
| 159 | - T kb0 (b0::kb0) ~ T kfresh0 (yfresh0::kfresh0)
|
|
| 151 | +The fresh unification variable `gamma1` comes from the fact that we can only do
|
|
| 152 | +"partial improvement" here; see Section 5.2 of "Injective type families for
|
|
| 153 | +Haskell" (HS'15).
|
|
| 160 | 154 | |
| 161 | -Now we'll unify kfresh0:=kb0, yfresh0:=b0, and all is well. The general idea
|
|
| 162 | -is that we want to preferentially eliminate those freshly-generated
|
|
| 163 | -unification variables, rather than unifying older variables, which causes
|
|
| 164 | -kick-out etc.
|
|
| 155 | +Now it is crucial that, when solving,
|
|
| 156 | + we unify gamma1 := alpha (YES)
|
|
| 157 | + and not alpha := gamma1 (NO)
|
|
| 165 | 158 | |
| 166 | -Keeping younger variables on the left also gives very minor improvement in
|
|
| 167 | -the compiler performance by having less kick-outs and allocations (-0.1% on
|
|
| 168 | -average). Indeed Historical Note [Eliminate younger unification variables]
|
|
| 169 | -in GHC.Tc.Utils.Unify describes an earlier attempt to do so systematically,
|
|
| 170 | -apparently now in abeyance.
|
|
| 159 | +Why? Because if we do (YES) we'll think we have made some progress
|
|
| 160 | +(some unification has happened), and hence go round again; but actually all we
|
|
| 161 | +have done is to replace `alpha` with `gamma1`.
|
|
| 171 | 162 | |
| 172 | -But this is is a delicate solution. We must take care to /preserve/
|
|
| 173 | -orientation during solving. Wrinkles:
|
|
| 163 | +These "fresh unification variables" in fundep-equalities are ubituitous.
|
|
| 164 | +For example
|
|
| 165 | + class C a b | a -> b
|
|
| 166 | + instance .. => C Int [x]
|
|
| 167 | +If we see
|
|
| 168 | + [W] C Int alpha
|
|
| 169 | +we'll generate a fundep-equality [W] alpha ~ [beta1]
|
|
| 170 | +where `beta1` is one of those "fresh unification variables
|
|
| 174 | 171 | |
| 175 | -(W1) We start with
|
|
| 176 | - [W] T kfresh0 (yfresh0::kfresh0) ~ T kb0 (b0::kb0)
|
|
| 177 | - Decompose to
|
|
| 178 | - [W] kfresh0 ~ kb0
|
|
| 179 | - [W] (yfresh0::kfresh0) ~ (b0::kb0)
|
|
| 180 | - Preserve orientation when decomposing!!
|
|
| 172 | +This problem shows up in several guises; see (at the bottom)
|
|
| 173 | + * Historical Note [Improvement orientation]
|
|
| 174 | + * Historical Note [Fundeps with instances, and equality orientation]
|
|
| 181 | 175 | |
| 182 | -(W2) Suppose we happen to tackle the second Wanted from (W1)
|
|
| 183 | - first. Then in canEqCanLHSHetero we emit a /kind/ equality, as
|
|
| 184 | - well as a now-homogeneous type equality
|
|
| 185 | - [W] kco : kfresh0 ~ kb0
|
|
| 186 | - [W] (yfresh0::kfresh0) ~ (b0::kb0) |> (sym kco)
|
|
| 187 | - Preserve orientation in canEqCanLHSHetero!! (Failing to
|
|
| 188 | - preserve orientation here was the immediate cause of #21703.)
|
|
| 176 | +The solution is super-simple:
|
|
| 189 | 177 | |
| 190 | -(W3) There is a potential interaction with the swapping done by
|
|
| 191 | - GHC.Tc.Utils.Unify.swapOverTyVars. We think it's fine, but it's
|
|
| 192 | - a slight worry. See especially Note [TyVar/TyVar orientation] in
|
|
| 193 | - that module.
|
|
| 178 | + * A fundep-equality is described by `FunDepEqn`, whose `fd_qtvs` field explicitly
|
|
| 179 | + lists the "fresh variables"
|
|
| 194 | 180 | |
| 195 | -The trouble is that "preserving orientation" is a rather global invariant,
|
|
| 196 | -and sometimes we definitely do want to swap (e.g. Int ~ alpha), so we don't
|
|
| 197 | -even have a precise statement of what the invariant is. The advantage
|
|
| 198 | -of the preserve-orientation plan is that it is extremely cheap to implement,
|
|
| 199 | -and apparently works beautifully.
|
|
| 181 | + * Function `instantiateFunDepEqn` instantiates a `FunDepEqn`, and CRUCIALLY
|
|
| 182 | + gives the new unification variables a level one deeper than the current
|
|
| 183 | + level.
|
|
| 200 | 184 | |
| 201 | ---- Alternative plan (1) ---
|
|
| 202 | -Rather than have an ill-defined invariant, another possiblity is to
|
|
| 203 | -elminate those fresh unification variables at birth, when generating
|
|
| 204 | -the new fundep-inspired equalities.
|
|
| 185 | + * Now, given `alpha ~ beta`, all the unification machinery guarantees, to
|
|
| 186 | + unify the variable with the deeper level. See GHC.Tc.Utils.Unify
|
|
| 187 | + Note [Deeper level on the left]. That ensures that the fresh `gamma1`
|
|
| 188 | + will be eliminated in favour of `alpha`. Hooray.
|
|
| 205 | 189 | |
| 206 | -The key idea is to call `instFlexiX` in `emitFunDepWanteds` on only those
|
|
| 207 | -type variables that are guaranteed to give us some progress. This means we
|
|
| 208 | -have to locally (without calling emitWanteds) identify the type variables
|
|
| 209 | -that do not give us any progress. In the above example, we _know_ that
|
|
| 210 | -emitting the two wanteds `kco` and `co` is fruitless.
|
|
| 190 | + * Better still, we solve the [FunDepEqn] with
|
|
| 191 | + solveFunDeps :: CtEvidence -> [FunDepEqn] -> TcS Bool
|
|
| 192 | + It uses `reportUnifications` to see if any unification happened at this
|
|
| 193 | + level or outside -- that is, it does NOT report unifications to the fresh
|
|
| 194 | + unification variables. So `solveFunDeps` returns True only if it
|
|
| 195 | + unifies a variable /other than/ the fresh ones. Bingo.
|
|
| 211 | 196 | |
| 212 | - Q: How do we identify such no-ops?
|
|
| 213 | - |
|
| 214 | - 1. Generate a matching substitution from LHS to RHS
|
|
| 215 | - ɸ = [kb0 :-> k0, b0 :-> y0]
|
|
| 216 | - 2. Call `instFlexiX` on only those type variables that do not appear in the domain of ɸ
|
|
| 217 | - ɸ' = instFlexiX ɸ (tvs - domain ɸ)
|
|
| 218 | - 3. Apply ɸ' on LHS and then call emitWanteds
|
|
| 219 | - unifyWanteds ... (subst ɸ' LHS) RHS
|
|
| 220 | - |
|
| 221 | -Why will this work? The matching substitution ɸ will be a best effort
|
|
| 222 | -substitution that gives us all the easy solutions. It can be generated with
|
|
| 223 | -modified version of `Core/Unify.unify_tys` where we run it in a matching mode
|
|
| 224 | -and never generate `SurelyApart` and always return a `MaybeApart Subst`
|
|
| 225 | -instead.
|
|
| 226 | - |
|
| 227 | -The same alternative plan would work for type-family injectivity constraints:
|
|
| 228 | -see Note [Improvement orientation] in GHC.Tc.Solver.Equality.
|
|
| 229 | ---- End of Alternative plan (1) ---
|
|
| 230 | - |
|
| 231 | ---- Alternative plan (2) ---
|
|
| 232 | -We could have a new flavour of TcTyVar (like `TauTv`, `TyVarTv` etc; see GHC.Tc.Utils.TcType.MetaInfo)
|
|
| 233 | -for the fresh unification variables introduced by functional dependencies. Say `FunDepTv`. Then in
|
|
| 234 | -GHC.Tc.Utils.Unify.swapOverTyVars we could arrange to keep a `FunDepTv` on the left if possible.
|
|
| 235 | -Looks possible, but it's one more complication.
|
|
| 236 | ---- End of Alternative plan (2) ---
|
|
| 237 | - |
|
| 238 | - |
|
| 239 | ---- Historical note: Failed Alternative Plan (3) ---
|
|
| 240 | -Previously we used a flag `cc_fundeps` in `CDictCan`. It would flip to False
|
|
| 241 | -once we used a fun dep to hint the solver to break and to stop emitting more
|
|
| 242 | -wanteds. This solution was not complete, and caused a failures while trying
|
|
| 243 | -to solve for transitive functional dependencies (test case: T21703)
|
|
| 244 | --- End of Historical note: Failed Alternative Plan (3) --
|
|
| 197 | +Another victory for levels numbers!
|
|
| 245 | 198 | |
| 246 | 199 | Note [Do fundeps last]
|
| 247 | 200 | ~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -260,7 +213,7 @@ Consider T4254b: |
| 260 | 213 | If we interact that Wanted with /both/ the top-level instance, /and/ the
|
| 261 | 214 | local Given, we'll get
|
| 262 | 215 | beta ~ Int and beta ~ b
|
| 263 | - respectively. That would generate (b~Bool), which would fai. I think
|
|
| 216 | + respectively. That would generate (b~Bool), which would fail. I think
|
|
| 264 | 217 | it doesn't matter which of the two we pick, but historically we have
|
| 265 | 218 | picked the local-fundeps first.
|
| 266 | 219 | |
| ... | ... | @@ -273,7 +226,6 @@ Consider T4254b: |
| 273 | 226 | |
| 274 | 227 | (DFL2) is achieved by trying fundeps only on /unsolved/ Wanteds.
|
| 275 | 228 | |
| 276 | - |
|
| 277 | 229 | Note [Weird fundeps]
|
| 278 | 230 | ~~~~~~~~~~~~~~~~~~~~
|
| 279 | 231 | Consider class Het a b | a -> b where
|
| ... | ... | @@ -296,6 +248,13 @@ as the fundeps. |
| 296 | 248 | #7875 is a case in point.
|
| 297 | 249 | -}
|
| 298 | 250 | |
| 251 | + |
|
| 252 | +{- *********************************************************************
|
|
| 253 | +* *
|
|
| 254 | +* Functional dependencies for dictionaries
|
|
| 255 | +* *
|
|
| 256 | +********************************************************************* -}
|
|
| 257 | + |
|
| 299 | 258 | tryDictFunDeps :: DictCt -> SolverStage ()
|
| 300 | 259 | -- (tryDictFunDeps inst_envs cts)
|
| 301 | 260 | -- * Generate the fundeps from interacting the
|
| ... | ... | @@ -334,6 +293,7 @@ tryDictFunDepsLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev }) |
| 334 | 293 | text "imp =" <+> ppr imp $$ text "eqns = " <+> ppr eqns
|
| 335 | 294 | |
| 336 | 295 | ; if imp then startAgainWith (CDictCan dict_ct)
|
| 296 | + -- See (DFL1) of Note [Do fundeps last]
|
|
| 337 | 297 | else continueWith () }
|
| 338 | 298 | where
|
| 339 | 299 | work_pred = ctEvPred work_ev
|
| ... | ... | @@ -436,88 +396,6 @@ and Given/instance fundeps entirely. |
| 436 | 396 | Functional dependencies for type families
|
| 437 | 397 | * *
|
| 438 | 398 | **********************************************************************
|
| 439 | - |
|
| 440 | -Note [Reverse order of fundep equations]
|
|
| 441 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 442 | -Consider this scenario (from dependent/should_fail/T13135_simple):
|
|
| 443 | - |
|
| 444 | - type Sig :: Type -> Type
|
|
| 445 | - data Sig a = SigFun a (Sig a)
|
|
| 446 | - |
|
| 447 | - type SmartFun :: forall (t :: Type). Sig t -> Type
|
|
| 448 | - type family SmartFun sig = r | r -> sig where
|
|
| 449 | - SmartFun @Type (SigFun @Type a sig) = a -> SmartFun @Type sig
|
|
| 450 | - |
|
| 451 | - [W] SmartFun @kappa sigma ~ (Int -> Bool)
|
|
| 452 | - |
|
| 453 | -The injectivity of SmartFun allows us to produce two new equalities:
|
|
| 454 | - |
|
| 455 | - [W] w1 :: Type ~ kappa
|
|
| 456 | - [W] w2 :: SigFun @Type Int beta ~ sigma
|
|
| 457 | - |
|
| 458 | -for some fresh (beta :: SigType). The second Wanted here is actually
|
|
| 459 | -heterogeneous: the LHS has type Sig Type while the RHS has type Sig kappa.
|
|
| 460 | -Of course, if we solve the first wanted first, the second becomes homogeneous.
|
|
| 461 | - |
|
| 462 | -When looking for injectivity-inspired equalities, we work left-to-right,
|
|
| 463 | -producing the two equalities in the order written above. However, these
|
|
| 464 | -equalities are then passed into wrapUnifierTcS, which will fail, adding these
|
|
| 465 | -to the work list. However, crucially, the work list operates like a *stack*.
|
|
| 466 | -So, because we add w1 and then w2, we process w2 first. This is silly: solving
|
|
| 467 | -w1 would unlock w2. So we make sure to add equalities to the work
|
|
| 468 | -list in left-to-right order, which requires a few key calls to 'reverse'.
|
|
| 469 | - |
|
| 470 | -This treatment is also used for class-based functional dependencies, although
|
|
| 471 | -we do not have a program yet known to exhibit a loop there. It just seems
|
|
| 472 | -like the right thing to do.
|
|
| 473 | - |
|
| 474 | -When this was originally conceived, it was necessary to avoid a loop in T13135.
|
|
| 475 | -That loop is now avoided by continuing with the kind equality (not the type
|
|
| 476 | -equality) in canEqCanLHSHetero (see Note [Equalities with heterogeneous kinds]).
|
|
| 477 | -However, the idea of working left-to-right still seems worthwhile, and so the calls
|
|
| 478 | -to 'reverse' remain.
|
|
| 479 | - |
|
| 480 | -Note [Improvement orientation]
|
|
| 481 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 482 | -See also Note [Fundeps with instances, and equality orientation], which describes
|
|
| 483 | -the Exact Same Problem, with the same solution, but for functional dependencies.
|
|
| 484 | - |
|
| 485 | -A very delicate point is the orientation of equalities
|
|
| 486 | -arising from injectivity improvement (#12522). Suppose we have
|
|
| 487 | - type family F x = t | t -> x
|
|
| 488 | - type instance F (a, Int) = (Int, G a)
|
|
| 489 | -where G is injective; and wanted constraints
|
|
| 490 | - |
|
| 491 | - [W] F (alpha, beta) ~ (Int, <some type>)
|
|
| 492 | - |
|
| 493 | -The injectivity will give rise to constraints
|
|
| 494 | - |
|
| 495 | - [W] gamma1 ~ alpha
|
|
| 496 | - [W] Int ~ beta
|
|
| 497 | - |
|
| 498 | -The fresh unification variable gamma1 comes from the fact that we
|
|
| 499 | -can only do "partial improvement" here; see Section 5.2 of
|
|
| 500 | -"Injective type families for Haskell" (HS'15).
|
|
| 501 | - |
|
| 502 | -Now, it's very important to orient the equations this way round,
|
|
| 503 | -so that the fresh unification variable will be eliminated in
|
|
| 504 | -favour of alpha. If we instead had
|
|
| 505 | - [W] alpha ~ gamma1
|
|
| 506 | -then we would unify alpha := gamma1; and kick out the wanted
|
|
| 507 | -constraint. But when we substitute it back in, it'd look like
|
|
| 508 | - [W] F (gamma1, beta) ~ fuv
|
|
| 509 | -and exactly the same thing would happen again! Infinite loop.
|
|
| 510 | - |
|
| 511 | ----> ToDo: all this fragility has gone away! Fix the Note! <---
|
|
| 512 | - |
|
| 513 | -This all seems fragile, and it might seem more robust to avoid
|
|
| 514 | -introducing gamma1 in the first place, in the case where the
|
|
| 515 | -actual argument (alpha, beta) partly matches the improvement
|
|
| 516 | -template. But that's a bit tricky, esp when we remember that the
|
|
| 517 | -kinds much match too; so it's easier to let the normal machinery
|
|
| 518 | -handle it. Instead we are careful to orient the new
|
|
| 519 | -equality with the template on the left. Delicate, but it works.
|
|
| 520 | - |
|
| 521 | 399 | -}
|
| 522 | 400 | |
| 523 | 401 | --------------------
|
| ... | ... | @@ -562,27 +440,18 @@ improveWantedTopFunEqs :: TyCon -> [TcType] -> CtEvidence -> Xi -> TcS Bool |
| 562 | 440 | -- TyCon is definitely a type family
|
| 563 | 441 | -- Work-item is a Wanted
|
| 564 | 442 | improveWantedTopFunEqs fam_tc args ev rhs_ty
|
| 565 | - = do { eqns <- improve_wanted_top_fun_eqs fam_tc args rhs_ty
|
|
| 443 | + = do { fd_eqns <- improve_wanted_top_fun_eqs fam_tc args rhs_ty
|
|
| 566 | 444 | ; traceTcS "improveTopFunEqs" (vcat [ text "lhs:" <+> ppr fam_tc <+> ppr args
|
| 567 | 445 | , text "rhs:" <+> ppr rhs_ty
|
| 568 | - , text "eqns:" <+> ppr eqns ])
|
|
| 569 | - ; unifyFunDeps ev Nominal $ \uenv ->
|
|
| 570 | - uPairsTcM (bump_depth uenv) (reverse eqns) }
|
|
| 571 | - -- Missing that `reverse` causes T13135 and T13135_simple to loop.
|
|
| 572 | - -- See Note [Reverse order of fundep equations]
|
|
| 573 | - -- ToDo: is this still a problem?
|
|
| 446 | + , text "eqns:" <+> ppr fd_eqns ])
|
|
| 447 | + ; solveFunDeps ev fd_eqns }
|
|
| 574 | 448 | |
| 575 | - where
|
|
| 576 | - bump_depth env = env { u_loc = bumpCtLocDepth (u_loc env) }
|
|
| 577 | - -- ToDo: this location is wrong; it should be FunDepOrigin2
|
|
| 578 | - -- See #14778
|
|
| 579 | - |
|
| 580 | -improve_wanted_top_fun_eqs :: TyCon -> [TcType] -> Xi
|
|
| 581 | - -> TcS [TypeEqn]
|
|
| 449 | +improve_wanted_top_fun_eqs :: TyCon -> [TcType] -> Xi -> TcS [FunDepEqn]
|
|
| 582 | 450 | -- TyCon is definitely a type family
|
| 583 | 451 | improve_wanted_top_fun_eqs fam_tc lhs_tys rhs_ty
|
| 584 | 452 | | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
|
| 585 | - = return (map snd $ tryInteractTopFam ops fam_tc lhs_tys rhs_ty)
|
|
| 453 | + = return [FDEqn { fd_qtvs = []
|
|
| 454 | + , fd_eqs = map snd $ tryInteractTopFam ops fam_tc lhs_tys rhs_ty }]
|
|
| 586 | 455 | |
| 587 | 456 | -- ToDo: use ideas in #23162 for closed type families; injectivity only for open
|
| 588 | 457 | |
| ... | ... | @@ -593,16 +462,20 @@ improve_wanted_top_fun_eqs fam_tc lhs_tys rhs_ty |
| 593 | 462 | ; top_eqns <- improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
|
| 594 | 463 | ; let local_eqns = improve_injective_wanted_famfam inj_args fam_tc lhs_tys rhs_ty
|
| 595 | 464 | ; traceTcS "improve_wanted_top_fun_eqs" $
|
| 596 | - vcat [ ppr fam_tc, text "local_eqns" <+> ppr local_eqns, text "top_eqns" <+> ppr top_eqns ]
|
|
| 597 | - -- xxx ToDo: this does both local and top => bug?
|
|
| 465 | + vcat [ ppr fam_tc
|
|
| 466 | + , text "local_eqns" <+> ppr local_eqns
|
|
| 467 | + , text "top_eqns" <+> ppr top_eqns ]
|
|
| 468 | + -- xxx ToDo: this does both local and top => bug?
|
|
| 598 | 469 | ; return (local_eqns ++ top_eqns) }
|
| 599 | 470 | |
| 600 | 471 | | otherwise -- No injectivity
|
| 601 | 472 | = return []
|
| 602 | 473 | |
| 603 | -improve_injective_wanted_top :: FamInstEnvs -> [Bool] -> TyCon -> [TcType] -> Xi -> TcS [TypeEqn]
|
|
| 474 | +improve_injective_wanted_top :: FamInstEnvs -> [Bool] -> TyCon
|
|
| 475 | + -> [TcType] -> Xi -> TcS [FunDepEqn]
|
|
| 604 | 476 | -- Interact with top-level instance declarations
|
| 605 | 477 | -- See Section 5.2 in the Injective Type Families paper
|
| 478 | +-- The injectivity flags [Bool] will not all be False, but nothing goes wrong if they are
|
|
| 606 | 479 | improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty
|
| 607 | 480 | = concatMapM do_one branches
|
| 608 | 481 | where
|
| ... | ... | @@ -617,7 +490,7 @@ improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty |
| 617 | 490 | | otherwise
|
| 618 | 491 | = []
|
| 619 | 492 | |
| 620 | - do_one :: CoAxBranch -> TcS [TypeEqn]
|
|
| 493 | + do_one :: CoAxBranch -> TcS [FunDepEqn]
|
|
| 621 | 494 | do_one branch@(CoAxBranch { cab_tvs = branch_tvs, cab_lhs = branch_lhs_tys, cab_rhs = branch_rhs })
|
| 622 | 495 | | let in_scope1 = in_scope `extendInScopeSetList` branch_tvs
|
| 623 | 496 | , Just subst <- tcUnifyTyForInjectivity False in_scope1 branch_rhs rhs_ty
|
| ... | ... | @@ -638,9 +511,10 @@ improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty |
| 638 | 511 | , text "rhs_ty" <+> ppr rhs_ty
|
| 639 | 512 | , text "subst" <+> ppr subst
|
| 640 | 513 | , text "subst1" <+> ppr subst1 ]
|
| 641 | - ; if apartnessCheck (substTys subst1 branch_lhs_tys) branch
|
|
| 642 | - then do { traceTcS "improv_inj_top1" (ppr branch_lhs_tys)
|
|
| 643 | - ; return (mkInjectivityEqns inj_args (map (substTy subst1) branch_lhs_tys) lhs_tys) }
|
|
| 514 | + ; let branch_lhs_tys' = substTys subst1 branch_lhs_tys
|
|
| 515 | + ; if apartnessCheck branch_lhs_tys' branch
|
|
| 516 | + then do { traceTcS "improv_inj_top1" (ppr branch_lhs_tys')
|
|
| 517 | + ; return [mkInjectivityFDEqn inj_args branch_lhs_tys' lhs_tys] }
|
|
| 644 | 518 | -- NB: The fresh unification variables (from unsubstTvs) are on the left
|
| 645 | 519 | -- See Note [Improvement orientation]
|
| 646 | 520 | else do { traceTcS "improve_inj_top2" empty; return [] } }
|
| ... | ... | @@ -651,20 +525,25 @@ improve_injective_wanted_top fam_envs inj_args fam_tc lhs_tys rhs_ty |
| 651 | 525 | in_scope = mkInScopeSet (tyCoVarsOfType rhs_ty)
|
| 652 | 526 | |
| 653 | 527 | |
| 654 | -improve_injective_wanted_famfam :: [Bool] -> TyCon -> [TcType] -> Xi -> [TypeEqn]
|
|
| 528 | +improve_injective_wanted_famfam :: [Bool] -> TyCon -> [TcType] -> Xi -> [FunDepEqn]
|
|
| 655 | 529 | -- Interact with itself, specifically F s1 s2 ~ F t1 t2
|
| 530 | +-- The injectivity flags [Bool] will not all be False, but nothing goes wrong if they are
|
|
| 656 | 531 | improve_injective_wanted_famfam inj_args fam_tc lhs_tys rhs_ty
|
| 657 | 532 | | Just (tc, rhs_tys) <- tcSplitTyConApp_maybe rhs_ty
|
| 658 | 533 | , tc == fam_tc
|
| 659 | - = mkInjectivityEqns inj_args lhs_tys rhs_tys
|
|
| 534 | + = [mkInjectivityFDEqn inj_args lhs_tys rhs_tys]
|
|
| 660 | 535 | | otherwise
|
| 661 | 536 | = []
|
| 662 | 537 | |
| 663 | -mkInjectivityEqns :: [Bool] -> [TcType] -> [TcType] -> [TypeEqn]
|
|
| 538 | +mkInjectivityFDEqn :: [Bool] -> [TcType] -> [TcType] -> FunDepEqn
|
|
| 664 | 539 | -- When F s1 s2 s3 ~ F t1 t2 t3, and F has injectivity info [True,False,True]
|
| 665 | --- return the equations [Pair s1 t1, Pair s3 t3]
|
|
| 666 | -mkInjectivityEqns inj_args lhs_args rhs_args
|
|
| 667 | - = [ Pair lhs_arg rhs_arg | (True, lhs_arg, rhs_arg) <- zip3 inj_args lhs_args rhs_args ]
|
|
| 540 | +-- return the FDEqn { fd_eqs = [Pair s1 t1, Pair s3 t3] }
|
|
| 541 | +-- The injectivity flags [Bool] will not all be False, but nothing goes wrong if they are
|
|
| 542 | +mkInjectivityFDEqn inj_args lhs_args rhs_args
|
|
| 543 | + = FDEqn { fd_qtvs = [], fd_eqs = eqs }
|
|
| 544 | + where
|
|
| 545 | + eqs = [ Pair lhs_arg rhs_arg
|
|
| 546 | + | (True, lhs_arg, rhs_arg) <- zip3 inj_args lhs_args rhs_args ]
|
|
| 668 | 547 | |
| 669 | 548 | ---------------------------------------------
|
| 670 | 549 | improveLocalFunEqs :: TyCon -> [TcType] -> EqCt -- F args ~ rhs
|
| ... | ... | @@ -765,30 +644,23 @@ improveWantedLocalFunEqs funeqs_for_tc fam_tc args work_ev rhs |
| 765 | 644 | = []
|
| 766 | 645 | |
| 767 | 646 | --------------------
|
| 768 | - do_one_built_in ops rhs (EqCt { eq_lhs = TyFamLHS _ iargs, eq_rhs = irhs, eq_ev = inert_ev })
|
|
| 647 | + do_one_built_in ops rhs (EqCt { eq_lhs = TyFamLHS _ iargs, eq_rhs = irhs })
|
|
| 769 | 648 | | irhs `tcEqType` rhs
|
| 770 | - = mk_fd_eqns inert_ev (map snd $ tryInteractInertFam ops fam_tc args iargs)
|
|
| 649 | + = [FDEqn { fd_qtvs = [], fd_eqs = map snd $ tryInteractInertFam ops fam_tc args iargs }]
|
|
| 771 | 650 | | otherwise
|
| 772 | 651 | = []
|
| 773 | 652 | do_one_built_in _ _ _ = pprPanic "interactFunEq 1" (ppr fam_tc) -- TyVarLHS
|
| 774 | 653 | |
| 775 | 654 | --------------------
|
| 776 | 655 | -- See Note [Type inference for type families with injectivity]
|
| 777 | - do_one_injective inj_args rhs (EqCt { eq_lhs = TyFamLHS _ inert_args
|
|
| 778 | - , eq_rhs = irhs, eq_ev = inert_ev })
|
|
| 656 | + do_one_injective inj_args rhs (EqCt { eq_lhs = TyFamLHS _ inert_args, eq_rhs = irhs })
|
|
| 779 | 657 | | rhs `tcEqType` irhs
|
| 780 | - = mk_fd_eqns inert_ev $ mkInjectivityEqns inj_args args inert_args
|
|
| 658 | + = [mkInjectivityFDEqn inj_args args inert_args]
|
|
| 781 | 659 | | otherwise
|
| 782 | 660 | = []
|
| 783 | 661 | |
| 784 | 662 | do_one_injective _ _ _ = pprPanic "interactFunEq 2" (ppr fam_tc) -- TyVarLHS
|
| 785 | 663 | |
| 786 | - --------------------
|
|
| 787 | - -- ToDO: fix me
|
|
| 788 | - mk_fd_eqns :: CtEvidence -> [TypeEqn] -> [FunDepEqn]
|
|
| 789 | - mk_fd_eqns _inert_ev eqns
|
|
| 790 | - | null eqns = []
|
|
| 791 | - | otherwise = [ FDEqn { fd_qtvs = [], fd_eqs = eqns } ]
|
|
| 792 | 664 | |
| 793 | 665 | {- Note [Type inference for type families with injectivity]
|
| 794 | 666 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -870,13 +742,11 @@ just an optimization so we don't lose anything in terms of completeness of |
| 870 | 742 | solving.
|
| 871 | 743 | -}
|
| 872 | 744 | |
| 873 | -{-
|
|
| 874 | -************************************************************************
|
|
| 745 | +{- *********************************************************************
|
|
| 875 | 746 | * *
|
| 876 | 747 | Emitting equalities arising from fundeps
|
| 877 | 748 | * *
|
| 878 | -************************************************************************
|
|
| 879 | --}
|
|
| 749 | +********************************************************************* -}
|
|
| 880 | 750 | |
| 881 | 751 | solveFunDeps :: CtEvidence -- The work item
|
| 882 | 752 | -> [FunDepEqn]
|
| ... | ... | @@ -885,16 +755,18 @@ solveFunDeps :: CtEvidence -- The work item |
| 885 | 755 | -- By "solve" we mean: (only) do unifications. We do not generate evidence, and
|
| 886 | 756 | -- other than unifications there should be no effects whatsoever
|
| 887 | 757 | --
|
| 888 | --- Return True if some unifications happened
|
|
| 889 | --- See Note [FunDep and implicit parameter reactions]
|
|
| 758 | +-- The returned Bool is True if some unifications happened
|
|
| 759 | +--
|
|
| 760 | +-- See Note [Overview of fundeps]
|
|
| 890 | 761 | solveFunDeps work_ev fd_eqns
|
| 891 | 762 | | null fd_eqns
|
| 892 | - = return False -- common case noop
|
|
| 763 | + = return False -- Common case no-op
|
|
| 893 | 764 | |
| 894 | 765 | | otherwise
|
| 895 | 766 | = do { (unif_happened, _res)
|
| 896 | - <- nestFunDepsTcS $
|
|
| 897 | - do { (_, eqs) <- unifyForAllBody work_ev Nominal do_fundeps
|
|
| 767 | + <- reportUnifications $
|
|
| 768 | + nestFunDepsTcS $
|
|
| 769 | + do { (_, eqs) <- wrapUnifier work_ev Nominal do_fundeps
|
|
| 898 | 770 | ; solveSimpleWanteds eqs }
|
| 899 | 771 | -- ToDo: why solveSimpleWanteds? Answer
|
| 900 | 772 | -- (a) don't rely on eager unifier
|
| ... | ... | @@ -920,6 +792,7 @@ instantiateFunDepEqn (FDEqn { fd_qtvs = tvs, fd_eqs = eqs }) |
| 920 | 792 | where
|
| 921 | 793 | rev_eqs = reverse eqs
|
| 922 | 794 | -- (reverse eqs): See Note [Reverse order of fundep equations]
|
| 795 | + -- ToDo: is this still a problem?
|
|
| 923 | 796 | |
| 924 | 797 | subst_pair subst (Pair ty1 ty2)
|
| 925 | 798 | = Pair (substTyUnchecked subst' ty1) ty2
|
| ... | ... | @@ -934,3 +807,257 @@ instantiateFunDepEqn (FDEqn { fd_qtvs = tvs, fd_eqs = eqs }) |
| 934 | 807 | -- though ty1 will never (currently) be a poytype, so this
|
| 935 | 808 | -- InScopeSet will never be looked at.
|
| 936 | 809 | |
| 810 | + |
|
| 811 | +{- Note [Reverse order of fundep equations]
|
|
| 812 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 813 | +Consider this scenario (from dependent/should_fail/T13135_simple):
|
|
| 814 | + |
|
| 815 | + type Sig :: Type -> Type
|
|
| 816 | + data Sig a = SigFun a (Sig a)
|
|
| 817 | + |
|
| 818 | + type SmartFun :: forall (t :: Type). Sig t -> Type
|
|
| 819 | + type family SmartFun sig = r | r -> sig where
|
|
| 820 | + SmartFun @Type (SigFun @Type a sig) = a -> SmartFun @Type sig
|
|
| 821 | + |
|
| 822 | + [W] SmartFun @kappa sigma ~ (Int -> Bool)
|
|
| 823 | + |
|
| 824 | +The injectivity of SmartFun allows us to produce two new equalities:
|
|
| 825 | + |
|
| 826 | + [W] w1 :: Type ~ kappa
|
|
| 827 | + [W] w2 :: SigFun @Type Int beta ~ sigma
|
|
| 828 | + |
|
| 829 | +for some fresh (beta :: SigType). The second Wanted here is actually
|
|
| 830 | +heterogeneous: the LHS has type Sig Type while the RHS has type Sig kappa.
|
|
| 831 | +Of course, if we solve the first wanted first, the second becomes homogeneous.
|
|
| 832 | + |
|
| 833 | +When looking for injectivity-inspired equalities, we work left-to-right,
|
|
| 834 | +producing the two equalities in the order written above. However, these
|
|
| 835 | +equalities are then passed into wrapUnifierAndEmit, which will fail, adding these
|
|
| 836 | +to the work list. However, the work list operates like a *stack*.
|
|
| 837 | +So, because we add w1 and then w2, we process w2 first. This is silly: solving
|
|
| 838 | +w1 would unlock w2. So we make sure to add equalities to the work
|
|
| 839 | +list in left-to-right order, which requires a few key calls to 'reverse'.
|
|
| 840 | + |
|
| 841 | +When this was originally conceived, it was necessary to avoid a loop in T13135.
|
|
| 842 | +That loop is now avoided by continuing with the kind equality (not the type
|
|
| 843 | +equality) in canEqCanLHSHetero (see Note [Equalities with heterogeneous kinds]).
|
|
| 844 | +However, the idea of working left-to-right still seems worthwhile, and so the calls
|
|
| 845 | +to 'reverse' remain.
|
|
| 846 | + |
|
| 847 | +This treatment is also used for class-based functional dependencies, although
|
|
| 848 | +we do not have a program yet known to exhibit a loop there. It just seems
|
|
| 849 | +like the right thing to do.
|
|
| 850 | + |
|
| 851 | +In general, I believe this is (now, anyway) just an optimisation, not required
|
|
| 852 | +to avoid loops.
|
|
| 853 | +-}
|
|
| 854 | + |
|
| 855 | +{- *********************************************************************
|
|
| 856 | +* *
|
|
| 857 | + Historical notes
|
|
| 858 | + |
|
| 859 | + Here are a bunch of Notes that are rendered obselete by
|
|
| 860 | + Note [Partial functional dependencies]
|
|
| 861 | + |
|
| 862 | +* *
|
|
| 863 | +********************************************************************* -}
|
|
| 864 | + |
|
| 865 | +{-
|
|
| 866 | +Historical Note [Improvement orientation]
|
|
| 867 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 868 | +See also Note [Fundeps with instances, and equality orientation], which describes
|
|
| 869 | +the Exact Same Problem, with the same solution, but for functional dependencies.
|
|
| 870 | + |
|
| 871 | +A very delicate point is the orientation of equalities
|
|
| 872 | +arising from injectivity improvement (#12522). Suppose we have
|
|
| 873 | + type family F x = t | t -> x
|
|
| 874 | + type instance F (a, Int) = (Int, G a)
|
|
| 875 | +where G is injective; and wanted constraints
|
|
| 876 | + |
|
| 877 | + [W] F (alpha, beta) ~ (Int, <some type>)
|
|
| 878 | + |
|
| 879 | +The injectivity will give rise to constraints
|
|
| 880 | + |
|
| 881 | + [W] gamma1 ~ alpha
|
|
| 882 | + [W] Int ~ beta
|
|
| 883 | + |
|
| 884 | +The fresh unification variable gamma1 comes from the fact that we
|
|
| 885 | +can only do "partial improvement" here; see Section 5.2 of
|
|
| 886 | +"Injective type families for Haskell" (HS'15).
|
|
| 887 | + |
|
| 888 | +Now, it's very important to orient the equations this way round,
|
|
| 889 | +so that the fresh unification variable will be eliminated in
|
|
| 890 | +favour of alpha. If we instead had
|
|
| 891 | + [W] alpha ~ gamma1
|
|
| 892 | +then we would unify alpha := gamma1; and kick out the wanted
|
|
| 893 | +constraint. But when we substitute it back in, it'd look like
|
|
| 894 | + [W] F (gamma1, beta) ~ fuv
|
|
| 895 | +and exactly the same thing would happen again! Infinite loop.
|
|
| 896 | + |
|
| 897 | +---> ToDo: all this fragility has gone away! Fix the Note! <---
|
|
| 898 | + |
|
| 899 | +This all seems fragile, and it might seem more robust to avoid
|
|
| 900 | +introducing gamma1 in the first place, in the case where the
|
|
| 901 | +actual argument (alpha, beta) partly matches the improvement
|
|
| 902 | +template. But that's a bit tricky, esp when we remember that the
|
|
| 903 | +kinds much match too; so it's easier to let the normal machinery
|
|
| 904 | +handle it. Instead we are careful to orient the new
|
|
| 905 | +equality with the template on the left. Delicate, but it works.
|
|
| 906 | + |
|
| 907 | +Historical Note [Fundeps with instances, and equality orientation]
|
|
| 908 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 909 | +This Note describes a delicate interaction that constrains the orientation of
|
|
| 910 | +equalities. This one is about fundeps, but the /exact/ same thing arises for
|
|
| 911 | +type-family injectivity constraints: see Note [Improvement orientation].
|
|
| 912 | + |
|
| 913 | +doTopFunDepImprovement compares the constraint with all the instance
|
|
| 914 | +declarations, to see if we can produce any equalities. E.g
|
|
| 915 | + class C2 a b | a -> b
|
|
| 916 | + instance C Int Bool
|
|
| 917 | +Then the constraint (C Int ty) generates the equality [W] ty ~ Bool.
|
|
| 918 | + |
|
| 919 | +There is a nasty corner in #19415 which led to the typechecker looping:
|
|
| 920 | + class C s t b | s -> t
|
|
| 921 | + instance ... => C (T kx x) (T ky y) Int
|
|
| 922 | + T :: forall k. k -> Type
|
|
| 923 | + |
|
| 924 | + work_item: dwrk :: C (T @ka (a::ka)) (T @kb0 (b0::kb0)) Char
|
|
| 925 | + where kb0, b0 are unification vars
|
|
| 926 | + |
|
| 927 | + ==> {doTopFunDepImprovement: compare work_item with instance,
|
|
| 928 | + generate /fresh/ unification variables kfresh0, yfresh0,
|
|
| 929 | + emit a new Wanted, and add dwrk to inert set}
|
|
| 930 | + |
|
| 931 | + Suppose we emit this new Wanted from the fundep:
|
|
| 932 | + [W] T kb0 (b0::kb0) ~ T kfresh0 (yfresh0::kfresh0)
|
|
| 933 | + |
|
| 934 | + ==> {solve that equality kb0 := kfresh0, b0 := yfresh0}
|
|
| 935 | + Now kick out dwrk, since it mentions kb0
|
|
| 936 | + But now we are back to the start! Loop!
|
|
| 937 | + |
|
| 938 | +NB1: This example relies on an instance that does not satisfy the
|
|
| 939 | + coverage condition (although it may satisfy the weak coverage
|
|
| 940 | + condition), and hence whose fundeps generate fresh unification
|
|
| 941 | + variables. Not satisfying the coverage condition is known to
|
|
| 942 | + lead to termination trouble, but in this case it's plain silly.
|
|
| 943 | + |
|
| 944 | +NB2: In this example, the third parameter to C ensures that the
|
|
| 945 | + instance doesn't actually match the Wanted, so we can't use it to
|
|
| 946 | + solve the Wanted
|
|
| 947 | + |
|
| 948 | +We solve the problem by (#21703):
|
|
| 949 | + |
|
| 950 | + carefully orienting the new Wanted so that all the
|
|
| 951 | + freshly-generated unification variables are on the LHS.
|
|
| 952 | + |
|
| 953 | + Thus we call unifyWanteds on
|
|
| 954 | + T kfresh0 (yfresh0::kfresh0) ~ T kb0 (b0::kb0)
|
|
| 955 | + and /NOT/
|
|
| 956 | + T kb0 (b0::kb0) ~ T kfresh0 (yfresh0::kfresh0)
|
|
| 957 | + |
|
| 958 | +Now we'll unify kfresh0:=kb0, yfresh0:=b0, and all is well. The general idea
|
|
| 959 | +is that we want to preferentially eliminate those freshly-generated
|
|
| 960 | +unification variables, rather than unifying older variables, which causes
|
|
| 961 | +kick-out etc.
|
|
| 962 | + |
|
| 963 | +Keeping younger variables on the left also gives very minor improvement in
|
|
| 964 | +the compiler performance by having less kick-outs and allocations (-0.1% on
|
|
| 965 | +average). Indeed Historical Note [Eliminate younger unification variables]
|
|
| 966 | +in GHC.Tc.Utils.Unify describes an earlier attempt to do so systematically,
|
|
| 967 | +apparently now in abeyance.
|
|
| 968 | + |
|
| 969 | +But this is is a delicate solution. We must take care to /preserve/
|
|
| 970 | +orientation during solving. Wrinkles:
|
|
| 971 | + |
|
| 972 | +(W1) We start with
|
|
| 973 | + [W] T kfresh0 (yfresh0::kfresh0) ~ T kb0 (b0::kb0)
|
|
| 974 | + Decompose to
|
|
| 975 | + [W] kfresh0 ~ kb0
|
|
| 976 | + [W] (yfresh0::kfresh0) ~ (b0::kb0)
|
|
| 977 | + Preserve orientation when decomposing!!
|
|
| 978 | + |
|
| 979 | +(W2) Suppose we happen to tackle the second Wanted from (W1)
|
|
| 980 | + first. Then in canEqCanLHSHetero we emit a /kind/ equality, as
|
|
| 981 | + well as a now-homogeneous type equality
|
|
| 982 | + [W] kco : kfresh0 ~ kb0
|
|
| 983 | + [W] (yfresh0::kfresh0) ~ (b0::kb0) |> (sym kco)
|
|
| 984 | + Preserve orientation in canEqCanLHSHetero!! (Failing to
|
|
| 985 | + preserve orientation here was the immediate cause of #21703.)
|
|
| 986 | + |
|
| 987 | +(W3) There is a potential interaction with the swapping done by
|
|
| 988 | + GHC.Tc.Utils.Unify.swapOverTyVars. We think it's fine, but it's
|
|
| 989 | + a slight worry. See especially Note [TyVar/TyVar orientation] in
|
|
| 990 | + that module.
|
|
| 991 | + |
|
| 992 | +The trouble is that "preserving orientation" is a rather global invariant,
|
|
| 993 | +and sometimes we definitely do want to swap (e.g. Int ~ alpha), so we don't
|
|
| 994 | +even have a precise statement of what the invariant is. The advantage
|
|
| 995 | +of the preserve-orientation plan is that it is extremely cheap to implement,
|
|
| 996 | +and apparently works beautifully.
|
|
| 997 | + |
|
| 998 | +--- Alternative plan (1) ---
|
|
| 999 | +Rather than have an ill-defined invariant, another possiblity is to
|
|
| 1000 | +elminate those fresh unification variables at birth, when generating
|
|
| 1001 | +the new fundep-inspired equalities.
|
|
| 1002 | + |
|
| 1003 | +The key idea is to call `instFlexiX` in `emitFunDepWanteds` on only those
|
|
| 1004 | +type variables that are guaranteed to give us some progress. This means we
|
|
| 1005 | +have to locally (without calling emitWanteds) identify the type variables
|
|
| 1006 | +that do not give us any progress. In the above example, we _know_ that
|
|
| 1007 | +emitting the two wanteds `kco` and `co` is fruitless.
|
|
| 1008 | + |
|
| 1009 | + Q: How do we identify such no-ops?
|
|
| 1010 | + |
|
| 1011 | + 1. Generate a matching substitution from LHS to RHS
|
|
| 1012 | + ɸ = [kb0 :-> k0, b0 :-> y0]
|
|
| 1013 | + 2. Call `instFlexiX` on only those type variables that do not appear in the domain of ɸ
|
|
| 1014 | + ɸ' = instFlexiX ɸ (tvs - domain ɸ)
|
|
| 1015 | + 3. Apply ɸ' on LHS and then call emitWanteds
|
|
| 1016 | + unifyWanteds ... (subst ɸ' LHS) RHS
|
|
| 1017 | + |
|
| 1018 | +Why will this work? The matching substitution ɸ will be a best effort
|
|
| 1019 | +substitution that gives us all the easy solutions. It can be generated with
|
|
| 1020 | +modified version of `Core/Unify.unify_tys` where we run it in a matching mode
|
|
| 1021 | +and never generate `SurelyApart` and always return a `MaybeApart Subst`
|
|
| 1022 | +instead.
|
|
| 1023 | + |
|
| 1024 | +The same alternative plan would work for type-family injectivity constraints:
|
|
| 1025 | +see Note [Improvement orientation] in GHC.Tc.Solver.Equality.
|
|
| 1026 | +--- End of Alternative plan (1) ---
|
|
| 1027 | + |
|
| 1028 | +--- Alternative plan (2) ---
|
|
| 1029 | +We could have a new flavour of TcTyVar (like `TauTv`, `TyVarTv` etc; see GHC.Tc.Utils.TcType.MetaInfo)
|
|
| 1030 | +for the fresh unification variables introduced by functional dependencies. Say `FunDepTv`. Then in
|
|
| 1031 | +GHC.Tc.Utils.Unify.swapOverTyVars we could arrange to keep a `FunDepTv` on the left if possible.
|
|
| 1032 | +Looks possible, but it's one more complication.
|
|
| 1033 | +--- End of Alternative plan (2) ---
|
|
| 1034 | + |
|
| 1035 | + |
|
| 1036 | +--- Historical note: Failed Alternative Plan (3) ---
|
|
| 1037 | +Previously we used a flag `cc_fundeps` in `CDictCan`. It would flip to False
|
|
| 1038 | +once we used a fun dep to hint the solver to break and to stop emitting more
|
|
| 1039 | +wanteds. This solution was not complete, and caused a failures while trying
|
|
| 1040 | +to solve for transitive functional dependencies (test case: T21703)
|
|
| 1041 | +-- End of Historical note: Failed Alternative Plan (3) --
|
|
| 1042 | + |
|
| 1043 | + |
|
| 1044 | +Historical Note
|
|
| 1045 | +~~~~~~~~~~~~~~~
|
|
| 1046 | +This Note (anonymous, but related to dict-solving) is rendered obselete by
|
|
| 1047 | + - Danger 1: solved by Note [Instance and Given overlap]
|
|
| 1048 | + - Danger 2: solved by fundeps being idempotent
|
|
| 1049 | + |
|
| 1050 | +When we spot an equality arising from a functional dependency,
|
|
| 1051 | +we now use that equality (a "wanted") to rewrite the work-item
|
|
| 1052 | +constraint right away. This avoids two dangers
|
|
| 1053 | + |
|
| 1054 | + Danger 1: If we send the original constraint on down the pipeline
|
|
| 1055 | + it may react with an instance declaration, and in delicate
|
|
| 1056 | + situations (when a Given overlaps with an instance) that
|
|
| 1057 | + may produce new insoluble goals: see #4952
|
|
| 1058 | + |
|
| 1059 | + Danger 2: If we don't rewrite the constraint, it may re-react
|
|
| 1060 | + with the same thing later, and produce the same equality
|
|
| 1061 | + again --> termination worries.
|
|
| 1062 | + |
|
| 1063 | +-} |
| ... | ... | @@ -81,7 +81,7 @@ module GHC.Tc.Solver.Monad ( |
| 81 | 81 | lookupInertDict,
|
| 82 | 82 | |
| 83 | 83 | -- The Model
|
| 84 | - recordUnification, recordUnifications, kickOutRewritable,
|
|
| 84 | + recordUnification, kickOutRewritable,
|
|
| 85 | 85 | |
| 86 | 86 | -- Inert Safe Haskell safe-overlap failures
|
| 87 | 87 | insertSafeOverlapFailureTcS,
|
| ... | ... | @@ -102,7 +102,7 @@ module GHC.Tc.Solver.Monad ( |
| 102 | 102 | instDFunType,
|
| 103 | 103 | |
| 104 | 104 | -- Unification
|
| 105 | - wrapUnifierX, wrapUnifierTcS, unifyFunDeps, uPairsTcM, unifyForAllBody,
|
|
| 105 | + wrapUnifier, wrapUnifierAndEmit, uPairsTcM,
|
|
| 106 | 106 | |
| 107 | 107 | -- MetaTyVars
|
| 108 | 108 | newFlexiTcSTy, instFlexiX, instFlexiXTcM,
|
| ... | ... | @@ -908,21 +908,19 @@ data TcSEnv |
| 908 | 908 | = TcSEnv {
|
| 909 | 909 | tcs_ev_binds :: EvBindsVar,
|
| 910 | 910 | |
| 911 | - tcs_unif_lvl :: IORef (Maybe TcLevel),
|
|
| 912 | - -- The Unification Level Flag
|
|
| 913 | - -- Outermost level at which we have unified a meta tyvar
|
|
| 914 | - -- Starts at Nothing, then (Just i), then (Just j) where j<i
|
|
| 915 | - -- See Note [The Unification Level Flag]
|
|
| 911 | + tcs_unif_lvl :: TcRef WhatUnifications,
|
|
| 912 | + -- Level of the outermost meta-tyvar that we have unified
|
|
| 913 | + -- See Note [WhatUnifications] in GHC.Tc.Utils.Unify
|
|
| 916 | 914 | |
| 917 | - tcs_count :: IORef Int, -- Global step count
|
|
| 915 | + tcs_count :: TcRef Int, -- Global step count
|
|
| 918 | 916 | |
| 919 | - tcs_inerts :: IORef InertSet, -- Current inert set
|
|
| 917 | + tcs_inerts :: TcRef InertSet, -- Current inert set
|
|
| 920 | 918 | |
| 921 | 919 | -- | The mode of operation for the constraint solver.
|
| 922 | 920 | -- See Note [TcSMode]
|
| 923 | 921 | tcs_mode :: TcSMode,
|
| 924 | 922 | |
| 925 | - tcs_worklist :: IORef WorkList
|
|
| 923 | + tcs_worklist :: TcRef WorkList
|
|
| 926 | 924 | }
|
| 927 | 925 | |
| 928 | 926 | ---------------
|
| ... | ... | @@ -1103,7 +1101,7 @@ runTcSWithEvBinds' mode ev_binds_var thing_inside |
| 1103 | 1101 | ; inert_var <- TcM.newTcRef (emptyInertSet tc_lvl)
|
| 1104 | 1102 | |
| 1105 | 1103 | ; wl_var <- TcM.newTcRef emptyWorkList
|
| 1106 | - ; unif_lvl_var <- TcM.newTcRef Nothing
|
|
| 1104 | + ; unif_lvl_var <- TcM.newTcRef NoUnificationsYet
|
|
| 1107 | 1105 | ; let env = TcSEnv { tcs_ev_binds = ev_binds_var
|
| 1108 | 1106 | , tcs_unif_lvl = unif_lvl_var
|
| 1109 | 1107 | , tcs_count = step_count
|
| ... | ... | @@ -1202,10 +1200,9 @@ nestImplicTcS ev_binds_var inner_tclvl (TcS thing_inside) |
| 1202 | 1200 | #endif
|
| 1203 | 1201 | ; return res }
|
| 1204 | 1202 | |
| 1205 | -nestFunDepsTcS :: TcS a -> TcS (Bool, a)
|
|
| 1203 | +nestFunDepsTcS :: TcS a -> TcS a
|
|
| 1206 | 1204 | nestFunDepsTcS (TcS thing_inside)
|
| 1207 | - = reportUnifications $
|
|
| 1208 | - TcS $ \ env@(TcSEnv { tcs_inerts = inerts_var }) ->
|
|
| 1205 | + = TcS $ \ env@(TcSEnv { tcs_inerts = inerts_var }) ->
|
|
| 1209 | 1206 | TcM.pushTcLevelM_ $
|
| 1210 | 1207 | -- pushTcLevelTcM: increase the level so that unification variables
|
| 1211 | 1208 | -- allocated by the fundep-creation itself don't count as useful unifications
|
| ... | ... | @@ -1220,6 +1217,10 @@ nestFunDepsTcS (TcS thing_inside) |
| 1220 | 1217 | ; TcM.traceTc "nestFunDepsTcS {" empty
|
| 1221 | 1218 | ; res <- thing_inside nest_env
|
| 1222 | 1219 | ; TcM.traceTc "nestFunDepsTcS }" empty
|
| 1220 | + |
|
| 1221 | + -- Unlike nestTcS, do /not/ do `updateInertsWith`; we are going to
|
|
| 1222 | + -- abandon everything about this sub-computation except its unifications
|
|
| 1223 | + |
|
| 1223 | 1224 | ; return res }
|
| 1224 | 1225 | |
| 1225 | 1226 | nestTcS :: TcS a -> TcS a
|
| ... | ... | @@ -1733,72 +1734,22 @@ pushLevelNoWorkList _ (TcS thing_inside) |
| 1733 | 1734 | * *
|
| 1734 | 1735 | ********************************************************************* -}
|
| 1735 | 1736 | |
| 1736 | -{- Note [The Unification Level Flag]
|
|
| 1737 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1738 | -Consider a deep tree of implication constraints
|
|
| 1739 | - forall[1] a. -- Outer-implic
|
|
| 1740 | - C alpha[1] -- Simple
|
|
| 1741 | - forall[2] c. ....(C alpha[1]).... -- Implic-1
|
|
| 1742 | - forall[2] b. ....(alpha[1] ~ Int).... -- Implic-2
|
|
| 1743 | - |
|
| 1744 | -The (C alpha) is insoluble until we know alpha. We solve alpha
|
|
| 1745 | -by unifying alpha:=Int somewhere deep inside Implic-2. But then we
|
|
| 1746 | -must try to solve the Outer-implic all over again. This time we can
|
|
| 1747 | -solve (C alpha) both in Outer-implic, and nested inside Implic-1.
|
|
| 1748 | - |
|
| 1749 | -When should we iterate solving a level-n implication?
|
|
| 1750 | -Answer: if any unification of a tyvar at level n takes place
|
|
| 1751 | - in the ic_implics of that implication.
|
|
| 1752 | - |
|
| 1753 | -* What if a unification takes place at level n-1? Then don't iterate
|
|
| 1754 | - level n, because we'll iterate level n-1, and that will in turn iterate
|
|
| 1755 | - level n.
|
|
| 1756 | - |
|
| 1757 | -* What if a unification takes place at level n, in the ic_simples of
|
|
| 1758 | - level n? No need to track this, because the kick-out mechanism deals
|
|
| 1759 | - with it. (We can't drop kick-out in favour of iteration, because kick-out
|
|
| 1760 | - works for skolem-equalities, not just unifications.)
|
|
| 1761 | - |
|
| 1762 | -So the monad-global Unification Level Flag, kept in tcs_unif_lvl keeps
|
|
| 1763 | -track of
|
|
| 1764 | - - Whether any unifications at all have taken place (Nothing => no unifications)
|
|
| 1765 | - - If so, what is the outermost level that has seen a unification (Just lvl)
|
|
| 1766 | - |
|
| 1767 | -The iteration is done in the simplify_loop/maybe_simplify_again loop in GHC.Tc.Solver.
|
|
| 1768 | - |
|
| 1769 | -It is helpful not to iterate unless there is a chance of progress. #8474 is
|
|
| 1770 | -an example:
|
|
| 1771 | - |
|
| 1772 | - * There's a deeply-nested chain of implication constraints.
|
|
| 1773 | - ?x:alpha => ?y1:beta1 => ... ?yn:betan => [W] ?x:Int
|
|
| 1774 | - |
|
| 1775 | - * From the innermost one we get a [W] alpha[1] ~ Int,
|
|
| 1776 | - so we can unify.
|
|
| 1777 | - |
|
| 1778 | - * It's better not to iterate the inner implications, but go all the
|
|
| 1779 | - way out to level 1 before iterating -- because iterating level 1
|
|
| 1780 | - will iterate the inner levels anyway.
|
|
| 1781 | - |
|
| 1782 | -(In the olden days when we "floated" thse Derived constraints, this was
|
|
| 1783 | -much, much more important -- we got exponential behaviour, as each iteration
|
|
| 1784 | -produced the same Derived constraint.)
|
|
| 1785 | --}
|
|
| 1786 | - |
|
| 1787 | - |
|
| 1788 | 1737 | unifyTyVar :: TcTyVar -> TcType -> TcS ()
|
| 1789 | 1738 | -- Unify a meta-tyvar with a type
|
| 1790 | 1739 | -- We should never unify the same variable twice!
|
| 1740 | +-- C.f. GHC.Tc.Utils.Unify.unifyTyVar
|
|
| 1791 | 1741 | unifyTyVar tv ty
|
| 1792 | 1742 | = assertPpr (isMetaTyVar tv) (ppr tv) $
|
| 1793 | 1743 | do { liftZonkTcS (TcM.writeMetaTyVar tv ty) -- Produces a trace message
|
| 1794 | - ; recordUnification tv }
|
|
| 1744 | + ; uni_ref <- getWhatUnifications
|
|
| 1745 | + ; wrapTcS $ recordUnification uni_ref tv }
|
|
| 1795 | 1746 | |
| 1796 | 1747 | reportUnifications :: TcS a -> TcS (Bool, a)
|
| 1797 | --- Record whether any unifications are done by thing_inside
|
|
| 1748 | +-- Record whether any useful unifications are done by thing_inside
|
|
| 1798 | 1749 | -- Remember to propagate the information to the enclosing context
|
| 1799 | 1750 | reportUnifications (TcS thing_inside)
|
| 1800 | 1751 | = TcS $ \ env@(TcSEnv { tcs_unif_lvl = outer_ul_var }) ->
|
| 1801 | - do { inner_ul_var <- TcM.newTcRef Nothing
|
|
| 1752 | + do { inner_ul_var <- TcM.newTcRef NoUnificationsYet
|
|
| 1802 | 1753 | |
| 1803 | 1754 | ; res <- thing_inside (env { tcs_unif_lvl = inner_ul_var })
|
| 1804 | 1755 | |
| ... | ... | @@ -1806,25 +1757,19 @@ reportUnifications (TcS thing_inside) |
| 1806 | 1757 | ; mb_inner_lvl <- TcM.readTcRef inner_ul_var
|
| 1807 | 1758 | |
| 1808 | 1759 | ; case mb_inner_lvl of
|
| 1809 | - Just unif_lvl
|
|
| 1760 | + UnificationsDone unif_lvl
|
|
| 1810 | 1761 | | ambient_lvl `deeperThanOrSame` unif_lvl
|
| 1811 | 1762 | -> -- Some useful unifications took place
|
| 1812 | - do { mb_outer_lvl <- TcM.readTcRef outer_ul_var
|
|
| 1813 | - ; TcM.traceTc "reportUnifications" $
|
|
| 1814 | - vcat [ text "ambient =" <+> ppr ambient_lvl
|
|
| 1815 | - , text "unif_lvl =" <+> ppr unif_lvl
|
|
| 1816 | - , text "mb_outer =" <+> ppr mb_outer_lvl ]
|
|
| 1817 | - ; case mb_outer_lvl of
|
|
| 1818 | - Just outer_unif_lvl | unif_lvl `deeperThanOrSame` outer_unif_lvl
|
|
| 1819 | - -> -- No need to update: outer_unif_lvl is already shallower
|
|
| 1820 | - return ()
|
|
| 1821 | - _ -> -- Update the outer level
|
|
| 1822 | - TcM.writeTcRef outer_ul_var (Just unif_lvl)
|
|
| 1763 | + do { recordUnificationLevel outer_ul_var unif_lvl
|
|
| 1823 | 1764 | ; return (True, res) }
|
| 1824 | 1765 | |
| 1825 | 1766 | _ -> -- No useful unifications
|
| 1826 | 1767 | return (False, res) }
|
| 1827 | 1768 | |
| 1769 | +getWhatUnifications :: TcS (TcRef WhatUnifications)
|
|
| 1770 | +getWhatUnifications
|
|
| 1771 | + = TcS $ \env -> return (tcs_unif_lvl env)
|
|
| 1772 | + |
|
| 1828 | 1773 | traceUnificationFlag :: String -> TcS ()
|
| 1829 | 1774 | traceUnificationFlag str
|
| 1830 | 1775 | = TcS $ \env ->
|
| ... | ... | @@ -1837,7 +1782,8 @@ traceUnificationFlag str |
| 1837 | 1782 | |
| 1838 | 1783 | getUnificationFlag :: TcS Bool
|
| 1839 | 1784 | -- We are at ambient level i
|
| 1840 | --- If the unification flag = Just i, reset it to Nothing and return True
|
|
| 1785 | +-- If the unification flag = UnificationsDone i,
|
|
| 1786 | +-- reset it to NoUnificationsYet, and return True
|
|
| 1841 | 1787 | -- Otherwise leave it unchanged and return False
|
| 1842 | 1788 | getUnificationFlag
|
| 1843 | 1789 | = TcS $ \env ->
|
| ... | ... | @@ -1848,39 +1794,13 @@ getUnificationFlag |
| 1848 | 1794 | vcat [ text "ambient:" <+> ppr ambient_lvl
|
| 1849 | 1795 | , text "unif_lvl:" <+> ppr mb_lvl ]
|
| 1850 | 1796 | ; case mb_lvl of
|
| 1851 | - Nothing -> return False
|
|
| 1852 | - Just unif_lvl | ambient_lvl `strictlyDeeperThan` unif_lvl
|
|
| 1853 | - -> return False
|
|
| 1854 | - | otherwise
|
|
| 1855 | - -> do { TcM.writeTcRef ref Nothing
|
|
| 1856 | - ; return True } }
|
|
| 1857 | - |
|
| 1858 | -recordUnification :: TcTyVar -> TcS ()
|
|
| 1859 | -recordUnification tv = setUnificationFlagTo (tcTyVarLevel tv)
|
|
| 1860 | - |
|
| 1861 | -recordUnifications :: [TcTyVar] -> TcS ()
|
|
| 1862 | -recordUnifications tvs
|
|
| 1863 | - = case tvs of
|
|
| 1864 | - [] -> return ()
|
|
| 1865 | - (tv:tvs) -> do { traceTcS "recordUnifications" (ppr min_tv_lvl $$ ppr tvs)
|
|
| 1866 | - ; setUnificationFlagTo min_tv_lvl }
|
|
| 1867 | - where
|
|
| 1868 | - min_tv_lvl = foldr (minTcLevel . tcTyVarLevel) (tcTyVarLevel tv) tvs
|
|
| 1869 | - |
|
| 1870 | -setUnificationFlagTo :: TcLevel -> TcS ()
|
|
| 1871 | --- (setUnificationFlag i) sets the unification level to (Just i)
|
|
| 1872 | --- unless it already is (Just j) where j <= i
|
|
| 1873 | -setUnificationFlagTo lvl
|
|
| 1874 | - = TcS $ \env ->
|
|
| 1875 | - do { let ref = tcs_unif_lvl env
|
|
| 1876 | - ; mb_lvl <- TcM.readTcRef ref
|
|
| 1877 | - ; case mb_lvl of
|
|
| 1878 | - Just unif_lvl | lvl `deeperThanOrSame` unif_lvl
|
|
| 1879 | - -> do { TcM.traceTc "set-uni-flag skip" $
|
|
| 1880 | - vcat [ text "lvl" <+> ppr lvl, text "unif_lvl" <+> ppr unif_lvl ]
|
|
| 1881 | - ; return () }
|
|
| 1882 | - _ -> do { TcM.traceTc "set-uni-flag" (ppr lvl)
|
|
| 1883 | - ; TcM.writeTcRef ref (Just lvl) } }
|
|
| 1797 | + NoUnificationsYet -> return False
|
|
| 1798 | + UnificationsDone unif_lvl
|
|
| 1799 | + | ambient_lvl `strictlyDeeperThan` unif_lvl
|
|
| 1800 | + -> return False
|
|
| 1801 | + | otherwise
|
|
| 1802 | + -> do { TcM.writeTcRef ref NoUnificationsYet
|
|
| 1803 | + ; return True } }
|
|
| 1884 | 1804 | |
| 1885 | 1805 | |
| 1886 | 1806 | {- *********************************************************************
|
| ... | ... | @@ -2182,77 +2102,30 @@ solverDepthError loc ty |
| 2182 | 2102 | * *
|
| 2183 | 2103 | ************************************************************************
|
| 2184 | 2104 | |
| 2185 | -Note [wrapUnifierTcS]
|
|
| 2186 | -~~~~~~~~~~~~~~~~~~~
|
|
| 2105 | +Note [wrapUnifier]
|
|
| 2106 | +~~~~~~~~~~~~~~~~~~
|
|
| 2187 | 2107 | When decomposing equalities we often create new wanted constraints for
|
| 2188 | 2108 | (s ~ t). But what if s=t? Then it'd be faster to return Refl right away.
|
| 2189 | 2109 | |
| 2190 | 2110 | Rather than making an equality test (which traverses the structure of the type,
|
| 2191 | -perhaps fruitlessly), we call uType (via wrapUnifierTcS) to traverse the common
|
|
| 2111 | +perhaps fruitlessly), we call uType (via wrapUnifier) to traverse the common
|
|
| 2192 | 2112 | structure, and bales out when it finds a difference by creating a new deferred
|
| 2193 | 2113 | Wanted constraint. But where it succeeds in finding common structure, it just
|
| 2194 | 2114 | builds a coercion to reflect it.
|
| 2195 | 2115 | |
| 2196 | 2116 | This is all much faster than creating a new constraint, putting it in the
|
| 2197 | 2117 | work list, picking it out, canonicalising it, etc etc.
|
| 2198 | - |
|
| 2199 | -Note [unifyFunDeps]
|
|
| 2200 | -~~~~~~~~~~~~~~~~~~~
|
|
| 2201 | -The Bool returned by `unifyFunDeps` is True if we have unified a variable
|
|
| 2202 | -that occurs in the constraint we are trying to solve; it is not in the
|
|
| 2203 | -inert set so `wrapUnifierTcS` won't kick it out. Instead we want to send it
|
|
| 2204 | -back to the start of the pipeline. Hence the Bool.
|
|
| 2205 | - |
|
| 2206 | -It's vital that we don't return (not (null unified)) because the fundeps
|
|
| 2207 | -may create fresh variables; unifying them (alone) should not make us send
|
|
| 2208 | -the constraint back to the start, or we'll get an infinite loop. See
|
|
| 2209 | -Note [Fundeps with instances, and equality orientation] in GHC.Tc.Solver.Dict
|
|
| 2210 | -and Note [Improvement orientation] in GHC.Tc.Solver.Equality.
|
|
| 2211 | 2118 | -}
|
| 2212 | 2119 | |
| 2213 | 2120 | uPairsTcM :: UnifyEnv -> [TypeEqn] -> TcM ()
|
| 2214 | 2121 | uPairsTcM uenv eqns = mapM_ (\(Pair ty1 ty2) -> uType uenv ty1 ty2) eqns
|
| 2215 | 2122 | |
| 2216 | -unifyFunDeps :: CtEvidence -> Role
|
|
| 2217 | - -> (UnifyEnv -> TcM ())
|
|
| 2218 | - -> TcS Bool
|
|
| 2219 | -unifyFunDeps ev role do_unifications
|
|
| 2220 | - = do { (_, _, unified) <- wrapUnifierTcS ev role do_unifications
|
|
| 2221 | - ; return (any (`elemVarSet` fvs) unified) }
|
|
| 2222 | - -- See Note [unifyFunDeps]
|
|
| 2223 | - where
|
|
| 2224 | - fvs = tyCoVarsOfType (ctEvPred ev)
|
|
| 2225 | - |
|
| 2226 | -unifyForAllBody :: CtEvidence -> Role -> (UnifyEnv -> TcM a)
|
|
| 2227 | - -> TcS (a, Cts)
|
|
| 2228 | --- We /return/ the equality constraints we generate,
|
|
| 2229 | --- rather than emitting them into the monad.
|
|
| 2230 | --- See See (SF5) in Note [Solving forall equalities] in GHC.Tc.Solver.Equality
|
|
| 2231 | -unifyForAllBody ev role unify_body
|
|
| 2232 | - = do { (res, cts, unified) <- wrapUnifierX ev role unify_body
|
|
| 2233 | - |
|
| 2234 | - -- Record the unificaions we have done
|
|
| 2235 | - ; recordUnifications unified
|
|
| 2236 | - |
|
| 2237 | - ; return (res, cts) }
|
|
| 2238 | - |
|
| 2239 | -wrapUnifierTcS :: CtEvidence -> Role
|
|
| 2240 | - -> (UnifyEnv -> TcM a) -- Some calls to uType
|
|
| 2241 | - -> TcS (a, Bag Ct, [TcTyVar])
|
|
| 2242 | --- Invokes the do_unifications argument, with a suitable UnifyEnv.
|
|
| 2243 | --- Emit deferred equalities and kick-out from the inert set as a
|
|
| 2244 | --- result of any unifications.
|
|
| 2245 | --- Very good short-cut when the two types are equal, or nearly so
|
|
| 2246 | --- See Note [wrapUnifierTcS]
|
|
| 2247 | ---
|
|
| 2248 | --- The [TcTyVar] is the list of unification variables that were
|
|
| 2249 | --- unified the process; the (Bag Ct) are the deferred constraints.
|
|
| 2250 | - |
|
| 2251 | -wrapUnifierTcS ev role do_unifications
|
|
| 2252 | - = do { (res, cts, unified) <- wrapUnifierX ev role do_unifications
|
|
| 2253 | - |
|
| 2254 | - -- Record the unificaions we have done
|
|
| 2255 | - ; recordUnifications unified
|
|
| 2123 | +wrapUnifierAndEmit :: CtEvidence -> Role
|
|
| 2124 | + -> (UnifyEnv -> TcM a) -- Some calls to uType
|
|
| 2125 | + -> TcS a
|
|
| 2126 | +-- Like wrapUnifier, but emits any unsolved equalities into the work-list
|
|
| 2127 | +wrapUnifierAndEmit ev role do_unifications
|
|
| 2128 | + = do { (res, cts) <- wrapUnifier ev role do_unifications
|
|
| 2256 | 2129 | |
| 2257 | 2130 | -- Emit the deferred constraints
|
| 2258 | 2131 | -- See Note [Work-list ordering] in GHC.Tc.Solved.Equality
|
| ... | ... | @@ -2263,31 +2136,40 @@ wrapUnifierTcS ev role do_unifications |
| 2263 | 2136 | ; unless (isEmptyBag cts) $
|
| 2264 | 2137 | updWorkListTcS (extendWorkListChildEqs ev cts)
|
| 2265 | 2138 | |
| 2266 | - ; return (res, cts, unified) }
|
|
| 2139 | + ; return res }
|
|
| 2267 | 2140 | |
| 2268 | -wrapUnifierX :: CtEvidence -> Role
|
|
| 2141 | +wrapUnifier :: CtEvidence -> Role
|
|
| 2269 | 2142 | -> (UnifyEnv -> TcM a) -- Some calls to uType
|
| 2270 | - -> TcS (a, Bag Ct, [TcTyVar])
|
|
| 2271 | -wrapUnifierX ev role do_unifications
|
|
| 2143 | + -> TcS (a, Bag Ct)
|
|
| 2144 | +-- Invokes the do_unifications argument, with a suitable UnifyEnv.
|
|
| 2145 | +-- Very good short-cut when the two types are equal, or nearly so
|
|
| 2146 | +-- See Note [wrapUnifier]
|
|
| 2147 | +-- The (Bag Ct) are the deferred constraints; we emit them but
|
|
| 2148 | +-- also return them
|
|
| 2149 | +wrapUnifier ev role do_unifications
|
|
| 2272 | 2150 | = do { given_eq_lvl <- getInnermostGivenEqLevel
|
| 2151 | + ; what_uni_ref <- getWhatUnifications
|
|
| 2152 | + |
|
| 2273 | 2153 | ; wrapTcS $
|
| 2274 | - do { defer_ref <- TcM.newTcRef emptyBag
|
|
| 2275 | - ; unified_ref <- TcM.newTcRef []
|
|
| 2154 | + do { defer_ref <- TcM.newTcRef emptyBag
|
|
| 2276 | 2155 | ; let env = UE { u_role = role
|
| 2277 | 2156 | , u_given_eq_lvl = given_eq_lvl
|
| 2278 | 2157 | , u_rewriters = ctEvRewriters ev
|
| 2279 | 2158 | , u_loc = ctEvLoc ev
|
| 2280 | 2159 | , u_defer = defer_ref
|
| 2281 | - , u_unified = Just unified_ref}
|
|
| 2160 | + , u_what = Just what_uni_ref }
|
|
| 2282 | 2161 | -- u_rewriters: the rewriter set and location from
|
| 2283 | 2162 | -- the parent constraint `ev` are inherited in any
|
| 2284 | 2163 | -- new constraints spat out by the unifier
|
| 2164 | + --
|
|
| 2165 | + -- u_what: likewise inherit the WhatUnifications flag,
|
|
| 2166 | + -- so that unifications done here are visible
|
|
| 2167 | + -- to the caller
|
|
| 2285 | 2168 | |
| 2286 | 2169 | ; res <- do_unifications env
|
| 2287 | 2170 | |
| 2288 | 2171 | ; cts <- TcM.readTcRef defer_ref
|
| 2289 | - ; unified <- TcM.readTcRef unified_ref
|
|
| 2290 | - ; return (res, cts, unified) } }
|
|
| 2172 | + ; return (res, cts) } }
|
|
| 2291 | 2173 | |
| 2292 | 2174 | |
| 2293 | 2175 | {-
|
| ... | ... | @@ -132,9 +132,10 @@ simplify_loop n limit definitely_redo_implications |
| 132 | 132 | ; return (wc { wc_simple = simples1
|
| 133 | 133 | , wc_impl = implics1 }) }
|
| 134 | 134 | |
| 135 | + -- See Note [When to iterate: unifications]
|
|
| 135 | 136 | ; unif_happened <- getUnificationFlag
|
| 136 | 137 | ; csTraceTcS $ text "unif_happened" <+> ppr unif_happened
|
| 137 | - -- Note [The Unification Level Flag] in GHC.Tc.Solver.Monad
|
|
| 138 | + |
|
| 138 | 139 | ; maybe_simplify_again (n+1) limit unif_happened wc2 }
|
| 139 | 140 | |
| 140 | 141 | data NextAction
|
| ... | ... | @@ -225,10 +226,59 @@ any new unifications, and iterate the implications only if so. |
| 225 | 226 | |
| 226 | 227 | "RAE": Add comment here about fundeps also using this mechanism. And probably
|
| 227 | 228 | update name of Note.
|
| 228 | --}
|
|
| 229 | 229 | |
| 230 | -{- Note [Expanding Recursive Superclasses and ExpansionFuel]
|
|
| 231 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 230 | +Note [When to iterate the solver: unifications]
|
|
| 231 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 232 | +Consider a deep tree of implication constraints
|
|
| 233 | + forall[1] a. -- Outer-implic
|
|
| 234 | + C alpha[1] -- Simple
|
|
| 235 | + forall[2] c. ....(C alpha[1]).... -- Implic-1
|
|
| 236 | + forall[2] b. ....(alpha[1] ~ Int).... -- Implic-2
|
|
| 237 | + |
|
| 238 | +The (C alpha) is insoluble until we know alpha. We solve alpha
|
|
| 239 | +by unifying alpha:=Int somewhere deep inside Implic-2. But then we
|
|
| 240 | +must try to solve the Outer-implic all over again. This time we can
|
|
| 241 | +solve (C alpha) both in Outer-implic, and nested inside Implic-1.
|
|
| 242 | + |
|
| 243 | +When should we iterate solving a level-n implication?
|
|
| 244 | +Answer: if any unification of a tyvar at level n takes place
|
|
| 245 | + in the ic_implics of that implication.
|
|
| 246 | + |
|
| 247 | +* What if a unification takes place at level n-1? Then don't iterate
|
|
| 248 | + level n, because we'll iterate level n-1, and that will in turn iterate
|
|
| 249 | + level n.
|
|
| 250 | + |
|
| 251 | +* What if a unification takes place at level n, in the ic_simples of
|
|
| 252 | + level n? No need to track this, because the kick-out mechanism deals
|
|
| 253 | + with it. (We can't drop kick-out in favour of iteration, because kick-out
|
|
| 254 | + works for skolem-equalities, not just unifications.)
|
|
| 255 | + |
|
| 256 | +So the monad-global `WhatUnifications` flag, kept in `tcs_unif_lvl` keeps
|
|
| 257 | +track of whether any unifications at all have taken place, and if so, what
|
|
| 258 | +is the outermost level that has seen a unification. Seee GHC.Tc.Utils.Unify
|
|
| 259 | +Note [WhatUnifications].
|
|
| 260 | + |
|
| 261 | +The iteration is done in the simplify_loop/maybe_simplify_again loop.
|
|
| 262 | + |
|
| 263 | +It is helpful not to iterate unless there is a chance of progress. #8474 is
|
|
| 264 | +an example:
|
|
| 265 | + |
|
| 266 | + * There's a deeply-nested chain of implication constraints.
|
|
| 267 | + ?x:alpha => ?y1:beta1 => ... ?yn:betan => [W] ?x:Int
|
|
| 268 | + |
|
| 269 | + * From the innermost one we get a [W] alpha[1] ~ Int,
|
|
| 270 | + so we can unify.
|
|
| 271 | + |
|
| 272 | + * It's better not to iterate the inner implications, but go all the
|
|
| 273 | + way out to level 1 before iterating -- because iterating level 1
|
|
| 274 | + will iterate the inner levels anyway.
|
|
| 275 | + |
|
| 276 | +(In the olden days when we "floated" these Derived constraints, this was
|
|
| 277 | +much, much more important -- we got exponential behaviour, as each iteration
|
|
| 278 | +produced the same Derived constraint.)
|
|
| 279 | + |
|
| 280 | +Note [Expanding Recursive Superclasses and ExpansionFuel]
|
|
| 281 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 232 | 282 | Consider the class declaration (T21909)
|
| 233 | 283 | |
| 234 | 284 | class C [a] => C a where
|
| ... | ... | @@ -1907,6 +1907,9 @@ emitSimple ct |
| 1907 | 1907 | |
| 1908 | 1908 | emitSimples :: Cts -> TcM ()
|
| 1909 | 1909 | emitSimples cts
|
| 1910 | + | null cts
|
|
| 1911 | + = return ()
|
|
| 1912 | + | otherwise
|
|
| 1910 | 1913 | = do { lie_var <- getConstraintVar ;
|
| 1911 | 1914 | updTcRef lie_var (`addSimples` cts) }
|
| 1912 | 1915 |
| ... | ... | @@ -30,14 +30,15 @@ module GHC.Tc.Utils.Unify ( |
| 30 | 30 | dsInstantiate,
|
| 31 | 31 | |
| 32 | 32 | -- Various unifications
|
| 33 | - unifyType, unifyKind, unifyInvisibleType,
|
|
| 33 | + uType, unifyType, unifyKind, unifyInvisibleType,
|
|
| 34 | 34 | unifyExprType, unifyTypeAndEmit, promoteTcType,
|
| 35 | 35 | swapOverTyVars, touchabilityTest, checkTopShape, lhsPriority,
|
| 36 | - UnifyEnv(..), updUEnvLoc, setUEnvRole,
|
|
| 37 | - uType,
|
|
| 38 | 36 | mightEqualLater,
|
| 39 | 37 | makeTypeConcrete,
|
| 40 | 38 | |
| 39 | + UnifyEnv(..), updUEnvLoc, setUEnvRole,
|
|
| 40 | + WhatUnifications(..), recordUnification, recordUnificationLevel,
|
|
| 41 | + |
|
| 41 | 42 | --------------------------------
|
| 42 | 43 | -- Holes
|
| 43 | 44 | matchExpectedListTy,
|
| ... | ... | @@ -2296,15 +2297,75 @@ unifyTypeAndEmit t_or_k orig ty1 ty2 |
| 2296 | 2297 | ; let env = UE { u_loc = loc, u_role = Nominal
|
| 2297 | 2298 | , u_given_eq_lvl = cur_lvl
|
| 2298 | 2299 | , u_rewriters = emptyRewriterSet -- ToDo: check this
|
| 2299 | - , u_defer = ref, u_unified = Nothing }
|
|
| 2300 | + , u_defer = ref, u_what = Nothing }
|
|
| 2300 | 2301 | |
| 2301 | 2302 | -- The hard work happens here
|
| 2302 | 2303 | ; co <- uType env ty1 ty2
|
| 2303 | 2304 | |
| 2305 | + -- Emit any deferred constraints
|
|
| 2304 | 2306 | ; cts <- readTcRef ref
|
| 2305 | - ; unless (null cts) (emitSimples cts)
|
|
| 2307 | + ; emitSimples cts
|
|
| 2308 | + |
|
| 2306 | 2309 | ; return co }
|
| 2307 | 2310 | |
| 2311 | + |
|
| 2312 | +{- *********************************************************************
|
|
| 2313 | +* *
|
|
| 2314 | + WhatUnifications
|
|
| 2315 | +* *
|
|
| 2316 | +**********************************************************************-}
|
|
| 2317 | + |
|
| 2318 | +data WhatUnifications
|
|
| 2319 | + = NoUnificationsYet
|
|
| 2320 | + | UnificationsDone TcLevel
|
|
| 2321 | + |
|
| 2322 | +{- Note [WhatUnifications]
|
|
| 2323 | +~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 2324 | +We record, in mutable variable carried by the monad, the `WhatUnifications` flag.
|
|
| 2325 | + |
|
| 2326 | +* In the eager unifier (this module) it is held the
|
|
| 2327 | + u_what :: Maybe (TcRef WhatUnificatons)
|
|
| 2328 | + field of `UnifyEnv`
|
|
| 2329 | + |
|
| 2330 | +* In TcS monad, it is held in the
|
|
| 2331 | + tcs_unif_lvl :: IORef WhatUnifications
|
|
| 2332 | + field of `TcSEnv`.
|
|
| 2333 | + |
|
| 2334 | +In all cases the idea is this:
|
|
| 2335 | + |
|
| 2336 | + ---------------------------------------
|
|
| 2337 | + `WhatUnifications` records the level of the
|
|
| 2338 | + outermost meta-tyvar that we have unified
|
|
| 2339 | + ----------------------------------------
|
|
| 2340 | + |
|
| 2341 | +It starts life as `NoUnificationsYet`. Then when we unify a tyvar at level j,
|
|
| 2342 | +we set the flag to `UnificationsDone j`, unless the flag is /already/ set to
|
|
| 2343 | +`UnificationsDone i` where i<=j.
|
|
| 2344 | + |
|
| 2345 | +Why do all this?
|
|
| 2346 | + * See Note [When to iterate the solver: unifications] in GHC.Tc.Solver.Solve
|
|
| 2347 | +-}
|
|
| 2348 | + |
|
| 2349 | +recordUnification :: TcRef WhatUnifications -> TcTyVar -> TcM ()
|
|
| 2350 | +recordUnification what_ref tv = recordUnificationLevel what_ref (tcTyVarLevel tv)
|
|
| 2351 | + |
|
| 2352 | +recordUnificationLevel :: TcRef WhatUnifications -> TcLevel -> TcM ()
|
|
| 2353 | +recordUnificationLevel what_ref tv_lvl
|
|
| 2354 | + = do { what <- readTcRef what_ref
|
|
| 2355 | + ; case what of
|
|
| 2356 | + UnificationsDone unif_lvl
|
|
| 2357 | + | tv_lvl `deeperThanOrSame` unif_lvl
|
|
| 2358 | + -> do { traceTc "set-uni-flag: no-op" $
|
|
| 2359 | + vcat [ text "lvl" <+> ppr tv_lvl, text "unif_lvl" <+> ppr unif_lvl ]
|
|
| 2360 | + ; return () }
|
|
| 2361 | + _ -> do { traceTc "set-uni-flag" (ppr tv_lvl)
|
|
| 2362 | + ; writeTcRef what_ref (UnificationsDone tv_lvl) } }
|
|
| 2363 | + |
|
| 2364 | + |
|
| 2365 | +instance Outputable WhatUnifications where
|
|
| 2366 | + ppr NoUnificationsYet = text "NoUniYet"
|
|
| 2367 | + ppr (UnificationsDone lvl) = text "UniDone" <> braces (ppr lvl)
|
|
| 2368 | + |
|
| 2308 | 2369 | {-
|
| 2309 | 2370 | %************************************************************************
|
| 2310 | 2371 | %* *
|
| ... | ... | @@ -2320,7 +2381,7 @@ The eager unifier, `uType`, is called by |
| 2320 | 2381 | via the wrappers `unifyType`, `unifyKind` etc
|
| 2321 | 2382 | |
| 2322 | 2383 | * The constraint solver (e.g. in GHC.Tc.Solver.Equality),
|
| 2323 | - via `GHC.Tc.Solver.Monad.wrapUnifierTcS`.
|
|
| 2384 | + via `GHC.Tc.Solver.Monad.wrapUnifie`.
|
|
| 2324 | 2385 | |
| 2325 | 2386 | `uType` runs in the TcM monad, but it carries a UnifyEnv that tells it
|
| 2326 | 2387 | what to do when unifying a variable or deferring a constraint. Specifically,
|
| ... | ... | @@ -2355,7 +2416,7 @@ data UnifyEnv |
| 2355 | 2416 | |
| 2356 | 2417 | -- Which variables are unified;
|
| 2357 | 2418 | -- if Nothing, we don't care
|
| 2358 | - , u_unified :: Maybe (TcRef [TcTyVar])
|
|
| 2419 | + , u_what :: Maybe (TcRef WhatUnifications)
|
|
| 2359 | 2420 | }
|
| 2360 | 2421 | |
| 2361 | 2422 | setUEnvRole :: UnifyEnv -> Role -> UnifyEnv
|
| ... | ... | @@ -2752,10 +2813,7 @@ uUnfilledVar2 env@(UE { u_defer = def_eq_ref, u_given_eq_lvl = given_eq_lvl }) |
| 2752 | 2813 | -- Only proceed if the kinds match
|
| 2753 | 2814 | -- NB: tv1 should still be unfilled, despite the kind unification
|
| 2754 | 2815 | -- because tv1 is not free in ty2' (or, hence, in its kind)
|
| 2755 | - then do { liftZonkM $ writeMetaTyVar tv1 ty2
|
|
| 2756 | - ; case u_unified env of
|
|
| 2757 | - Nothing -> return ()
|
|
| 2758 | - Just uref -> updTcRef uref (tv1 :)
|
|
| 2816 | + then do { unifyTyVar env tv1 ty2
|
|
| 2759 | 2817 | ; return (mkNomReflCo ty2) } -- Unification is always Nominal
|
| 2760 | 2818 | |
| 2761 | 2819 | else -- The kinds don't match yet, so defer instead.
|
| ... | ... | @@ -2770,6 +2828,14 @@ uUnfilledVar2 env@(UE { u_defer = def_eq_ref, u_given_eq_lvl = given_eq_lvl }) |
| 2770 | 2828 | ty1 = mkTyVarTy tv1
|
| 2771 | 2829 | defer = unSwap swapped (uType_defer env) ty1 ty2
|
| 2772 | 2830 | |
| 2831 | +unifyTyVar :: UnifyEnv -> TcTyVar -> TcType -> TcM ()
|
|
| 2832 | +-- Actually do the unification, and record it in WhatUnifications
|
|
| 2833 | +unifyTyVar (UE { u_what = mb_what_unifications }) tv ty
|
|
| 2834 | + = do { liftZonkM $ writeMetaTyVar tv ty
|
|
| 2835 | + ; case mb_what_unifications of
|
|
| 2836 | + Nothing -> return ()
|
|
| 2837 | + Just wu -> recordUnification wu tv }
|
|
| 2838 | + |
|
| 2773 | 2839 | swapOverTyVars :: Bool -> TcTyVar -> TcTyVar -> Bool
|
| 2774 | 2840 | swapOverTyVars is_given tv1 tv2
|
| 2775 | 2841 | -- See Note [Unification variables on the left]
|
| ... | ... | @@ -3011,8 +3077,14 @@ The most important thing is that we want to put tyvars with |
| 3011 | 3077 | the deepest level on the left. The reason to do so differs for
|
| 3012 | 3078 | Wanteds and Givens, but either way, deepest wins! Simple.
|
| 3013 | 3079 | |
| 3014 | -* Wanteds. Putting the deepest variable on the left maximise the
|
|
| 3080 | +* Wanteds. Putting the deepest variable on the left maximises the
|
|
| 3015 | 3081 | chances that it's a touchable meta-tyvar which can be solved.
|
| 3082 | + It also /crucial/ for skolem escape. Consider
|
|
| 3083 | + [W] alpha[7] ~ beta[8]
|
|
| 3084 | + [W] beta[8] ~ a[8] -- `a` is a skolem
|
|
| 3085 | + If we unify alpha[7]:=beta[8], we will then happily unify
|
|
| 3086 | + beta[8]:=a[8]. But that's wrong because now alpha[7]
|
|
| 3087 | + is unified with an inner skolem a[8]. Disaster.
|
|
| 3016 | 3088 | |
| 3017 | 3089 | * Givens. Suppose we have something like
|
| 3018 | 3090 | forall a[2]. b[1] ~ a[2] => beta[1] ~ a[2]
|