Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
22d11fa8
by Simon Peyton Jones at 2025-04-28T18:05:19-04:00
16 changed files:
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- testsuite/tests/indexed-types/should_fail/T3330c.stderr
- testsuite/tests/indexed-types/should_fail/T4174.stderr
- testsuite/tests/indexed-types/should_fail/T8227.stderr
- testsuite/tests/typecheck/should_compile/T25266a.stderr
- testsuite/tests/typecheck/should_fail/T18851.stderr
Changes:
... | ... | @@ -120,7 +120,8 @@ module GHC.Core.Coercion ( |
120 | 120 | |
121 | 121 | multToCo, mkRuntimeRepCo,
|
122 | 122 | |
123 | - hasCoercionHoleTy, hasCoercionHoleCo, hasThisCoercionHoleTy,
|
|
123 | + hasHeteroKindCoercionHoleTy, hasHeteroKindCoercionHoleCo,
|
|
124 | + hasThisCoercionHoleTy,
|
|
124 | 125 | |
125 | 126 | setCoHoleType
|
126 | 127 | ) where
|
... | ... | @@ -2795,12 +2796,12 @@ has_co_hole_co :: Coercion -> Monoid.Any |
2795 | 2796 | -- | Is there a hetero-kind coercion hole in this type?
|
2796 | 2797 | -- (That is, a coercion hole with ch_hetero_kind=True.)
|
2797 | 2798 | -- See wrinkle (EIK2) of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality
|
2798 | -hasCoercionHoleTy :: Type -> Bool
|
|
2799 | -hasCoercionHoleTy = Monoid.getAny . has_co_hole_ty
|
|
2799 | +hasHeteroKindCoercionHoleTy :: Type -> Bool
|
|
2800 | +hasHeteroKindCoercionHoleTy = Monoid.getAny . has_co_hole_ty
|
|
2800 | 2801 | |
2801 | 2802 | -- | Is there a hetero-kind coercion hole in this coercion?
|
2802 | -hasCoercionHoleCo :: Coercion -> Bool
|
|
2803 | -hasCoercionHoleCo = Monoid.getAny . has_co_hole_co
|
|
2803 | +hasHeteroKindCoercionHoleCo :: Coercion -> Bool
|
|
2804 | +hasHeteroKindCoercionHoleCo = Monoid.getAny . has_co_hole_co
|
|
2804 | 2805 | |
2805 | 2806 | hasThisCoercionHoleTy :: Type -> CoercionHole -> Bool
|
2806 | 2807 | hasThisCoercionHoleTy ty hole = Monoid.getAny (f ty)
|
... | ... | @@ -466,13 +466,12 @@ mkErrorItem ct |
466 | 466 | = do { let loc = ctLoc ct
|
467 | 467 | flav = ctFlavour ct
|
468 | 468 | |
469 | - ; (suppress, m_evdest) <- case ctEvidence ct of
|
|
470 | - -- For this `suppress` stuff
|
|
471 | - -- see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
|
|
472 | - CtGiven {} -> return (False, Nothing)
|
|
473 | - CtWanted (WantedCt { ctev_rewriters = rewriters, ctev_dest = dest })
|
|
474 | - -> do { rewriters' <- zonkRewriterSet rewriters
|
|
475 | - ; return (not (isEmptyRewriterSet rewriters'), Just dest) }
|
|
469 | + (suppress, m_evdest) = case ctEvidence ct of
|
|
470 | + -- For this `suppress` stuff
|
|
471 | + -- see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
|
|
472 | + CtGiven {} -> (False, Nothing)
|
|
473 | + CtWanted (WantedCt { ctev_rewriters = rws, ctev_dest = dest })
|
|
474 | + -> (not (isEmptyRewriterSet rws), Just dest)
|
|
476 | 475 | |
477 | 476 | ; let m_reason = case ct of
|
478 | 477 | CIrredCan (IrredCt { ir_reason = reason }) -> Just reason
|
... | ... | @@ -503,7 +502,7 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
503 | 502 | , text "tidy_errs =" <+> ppr tidy_errs ])
|
504 | 503 | |
505 | 504 | -- Catch an awkward (and probably rare) case in which /all/ errors are
|
506 | - -- suppressed: see Wrinkle (WRW2) in Note [Prioritise Wanteds with empty
|
|
505 | + -- suppressed: see Wrinkle (PER2) in Note [Prioritise Wanteds with empty
|
|
507 | 506 | -- RewriterSet] in GHC.Tc.Types.Constraint.
|
508 | 507 | --
|
509 | 508 | -- Unless we are sure that an error will be reported some other way
|
... | ... | @@ -1821,7 +1820,7 @@ mkTyVarEqErr' ctxt item (tv1, co1) ty2 |
1821 | 1820 | -- Incompatible kinds
|
1822 | 1821 | -- This is wrinkle (EIK2) in Note [Equalities with incompatible kinds]
|
1823 | 1822 | -- in GHC.Tc.Solver.Equality
|
1824 | - | hasCoercionHoleCo co1 || hasCoercionHoleTy ty2
|
|
1823 | + | hasHeteroKindCoercionHoleCo co1 || hasHeteroKindCoercionHoleTy ty2
|
|
1825 | 1824 | = return $ mkBlockedEqErr item
|
1826 | 1825 | |
1827 | 1826 | | isSkolemTyVar tv1 -- ty2 won't be a meta-tyvar; we would have
|
... | ... | @@ -1081,9 +1081,9 @@ disambigProposalSequences orig_wanteds wanteds proposalSequences allConsistent |
1081 | 1081 | ; successes <- fmap catMaybes $
|
1082 | 1082 | nestImplicTcS fake_ev_binds_var (pushTcLevel tclvl) $
|
1083 | 1083 | mapM firstSuccess proposalSequences
|
1084 | - ; traceTcS "disambigProposalSequences" (vcat [ ppr wanteds
|
|
1085 | - , ppr proposalSequences
|
|
1086 | - , ppr successes ])
|
|
1084 | + ; traceTcS "disambigProposalSequences {" (vcat [ ppr wanteds
|
|
1085 | + , ppr proposalSequences
|
|
1086 | + , ppr successes ])
|
|
1087 | 1087 | -- Step (4) in Note [How type-class constraints are defaulted]
|
1088 | 1088 | ; case successes of
|
1089 | 1089 | success@(tvs, subst) : rest
|
... | ... | @@ -1613,54 +1613,63 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 |
1613 | 1613 | -- NotSwapped:
|
1614 | 1614 | -- ev :: (lhs1:ki1) ~r# (xi2:ki2)
|
1615 | 1615 | -- kind_co :: k11 ~# ki2 -- Same orientation as ev
|
1616 | --- type_ev :: lhs1 ~r# (xi2 |> sym kind_co)
|
|
1616 | +-- new_ev :: lhs1 ~r# (xi2 |> sym kind_co)
|
|
1617 | 1617 | -- Swapped
|
1618 | 1618 | -- ev :: (xi2:ki2) ~r# (lhs1:ki1)
|
1619 | 1619 | -- kind_co :: ki2 ~# ki1 -- Same orientation as ev
|
1620 | --- type_ev :: (xi2 |> kind_co) ~r# lhs1
|
|
1620 | +-- new_ev :: (xi2 |> kind_co) ~r# lhs1
|
|
1621 | +-- Note that we need the `sym` when we are /not/ swapped; hence `mk_sym_co`
|
|
1621 | 1622 | |
1622 | - = do { (kind_co, rewriters, unifs_happened) <- mk_kind_eq -- :: ki1 ~N ki2
|
|
1623 | - ; if unifs_happened
|
|
1624 | - -- Unifications happened, so start again to do the zonking
|
|
1625 | - -- Otherwise we might put something in the inert set that isn't inert
|
|
1626 | - then startAgainWith (mkNonCanonical ev)
|
|
1627 | - else
|
|
1628 | - do { let lhs_redn = mkReflRedn role ps_xi1
|
|
1629 | - rhs_redn = mkGReflRightRedn role xi2 mb_sym_kind_co
|
|
1630 | - mb_sym_kind_co = case swapped of
|
|
1631 | - NotSwapped -> mkSymCo kind_co
|
|
1632 | - IsSwapped -> kind_co
|
|
1633 | - |
|
1634 | - ; traceTcS "Hetero equality gives rise to kind equality"
|
|
1635 | - (ppr swapped $$
|
|
1636 | - ppr kind_co <+> dcolon <+> sep [ ppr ki1, text "~#", ppr ki2 ])
|
|
1637 | - ; type_ev <- rewriteEqEvidence rewriters ev swapped lhs_redn rhs_redn
|
|
1638 | - |
|
1639 | - ; let new_xi2 = mkCastTy ps_xi2 mb_sym_kind_co
|
|
1640 | - ; canEqCanLHSHomo type_ev eq_rel NotSwapped lhs1 ps_xi1 new_xi2 new_xi2 }}
|
|
1641 | - |
|
1642 | - where
|
|
1643 | - mk_kind_eq :: TcS (CoercionN, RewriterSet, Bool)
|
|
1644 | - -- Returned kind_co has kind (k1 ~ k2) if NotSwapped, (k2 ~ k1) if Swapped
|
|
1645 | - -- Returned Bool = True if unifications happened, so we should retry
|
|
1646 | - mk_kind_eq = case ev of
|
|
1623 | + = case ev of
|
|
1647 | 1624 | CtGiven (GivenCt { ctev_evar = evar, ctev_loc = loc })
|
1648 | 1625 | -> do { let kind_co = mkKindCo (mkCoVarCo evar)
|
1649 | 1626 | pred_ty = unSwap swapped mkNomEqPred ki1 ki2
|
1650 | 1627 | kind_loc = mkKindEqLoc xi1 xi2 loc
|
1651 | 1628 | ; kind_ev <- newGivenEvVar kind_loc (pred_ty, evCoercion kind_co)
|
1652 | 1629 | ; emitWorkNC [CtGiven kind_ev]
|
1653 | - ; return (givenCtEvCoercion kind_ev, emptyRewriterSet, False) }
|
|
1630 | + ; let kind_co = givenCtEvCoercion kind_ev
|
|
1631 | + new_xi2 = mkCastTy ps_xi2 (mk_sym_co kind_co)
|
|
1632 | + ; new_ev <- do_rewrite emptyRewriterSet kind_co
|
|
1633 | + -- In the Given case, `new_ev` is canonical, so carry on
|
|
1634 | + ; canEqCanLHSHomo new_ev eq_rel NotSwapped lhs1 ps_xi1 new_xi2 new_xi2 }
|
|
1654 | 1635 | |
1655 | 1636 | CtWanted {}
|
1656 | - -> do { (kind_co, cts, unifs) <- wrapUnifierTcS ev Nominal $ \uenv ->
|
|
1657 | - let uenv' = updUEnvLoc uenv (mkKindEqLoc xi1 xi2)
|
|
1658 | - in unSwap swapped (uType uenv') ki1 ki2
|
|
1659 | - ; return (kind_co, rewriterSetFromCts cts, not (null unifs)) }
|
|
1660 | - |
|
1637 | + -> do { (kind_co, cts, unifs) <- wrapUnifierTcS ev Nominal $ \uenv ->
|
|
1638 | + let uenv' = updUEnvLoc uenv (mkKindEqLoc xi1 xi2)
|
|
1639 | + in unSwap swapped (uType uenv') ki1 ki2
|
|
1640 | + ; if not (null unifs)
|
|
1641 | + then -- Unifications happened, so start again to do the zonking
|
|
1642 | + -- Otherwise we might put something in the inert set that isn't inert
|
|
1643 | + startAgainWith (mkNonCanonical ev)
|
|
1644 | + else
|
|
1645 | + |
|
1646 | + assertPpr (not (isEmptyCts cts)) (ppr ev $$ ppr ki1 $$ ppr ki2) $
|
|
1647 | + -- The constraints won't be empty because the two kinds differ, and there
|
|
1648 | + -- are no unifications, so we must have emitted one or more constraints
|
|
1649 | + do { new_ev <- do_rewrite (rewriterSetFromCts cts) kind_co
|
|
1650 | + -- The rewritten equality `new_ev` is non-canonical,
|
|
1651 | + -- so put it straight in the Irreds
|
|
1652 | + ; finishCanWithIrred (NonCanonicalReason (cteProblem cteCoercionHole)) new_ev } }
|
|
1653 | + where
|
|
1661 | 1654 | xi1 = canEqLHSType lhs1
|
1662 | 1655 | role = eqRelRole eq_rel
|
1663 | 1656 | |
1657 | + -- Apply mkSymCo when /not/ swapped
|
|
1658 | + mk_sym_co co = case swapped of
|
|
1659 | + NotSwapped -> mkSymCo co
|
|
1660 | + IsSwapped -> co
|
|
1661 | + |
|
1662 | + do_rewrite rewriters kind_co
|
|
1663 | + = do { traceTcS "Hetero equality gives rise to kind equality"
|
|
1664 | + (ppr swapped $$
|
|
1665 | + ppr kind_co <+> dcolon <+> sep [ ppr ki1, text "~#", ppr ki2 ])
|
|
1666 | + ; rewriteEqEvidence rewriters ev swapped lhs_redn rhs_redn }
|
|
1667 | + where
|
|
1668 | + -- kind_co :: ki1 ~N ki2
|
|
1669 | + lhs_redn = mkReflRedn role ps_xi1
|
|
1670 | + rhs_redn = mkGReflRightRedn role xi2 (mk_sym_co kind_co)
|
|
1671 | + |
|
1672 | + |
|
1664 | 1673 | canEqCanLHSHomo :: CtEvidence -- lhs ~ rhs
|
1665 | 1674 | -- or, if swapped: rhs ~ lhs
|
1666 | 1675 | -> EqRel -> SwapFlag
|
... | ... | @@ -2044,19 +2053,20 @@ What do we do when we have an equality |
2044 | 2053 | where k1 and k2 differ? Easy: we create a coercion that relates k1 and
|
2045 | 2054 | k2 and use this to cast. To wit, from
|
2046 | 2055 | |
2047 | - [X] (tv :: k1) ~ (rhs :: k2)
|
|
2056 | + [X] co1 :: (tv :: k1) ~ (rhs :: k2)
|
|
2048 | 2057 | |
2049 | 2058 | (where [X] is [G] or [W]), we go to
|
2050 | 2059 | |
2051 | - [X] co :: k1 ~ k2
|
|
2052 | - [X] (tv :: k1) ~ ((rhs |> sym co) :: k1)
|
|
2060 | + co1 = co2 ; sym (GRefl kco)
|
|
2061 | + [X] co2 :: (tv :: k1) ~ ((rhs |> sym kco) :: k1)
|
|
2062 | + [X] kco :: k1 ~ k2
|
|
2053 | 2063 | |
2054 | 2064 | Wrinkles:
|
2055 | 2065 | |
2056 | -(EIK1) When X is W, the new type-level wanted is effectively rewritten by the
|
|
2057 | - kind-level one. We thus include the kind-level wanted in the RewriterSet
|
|
2058 | - for the type-level one. See Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint.
|
|
2059 | - This is done in canEqCanLHSHetero.
|
|
2066 | +(EIK1) When X=Wanted, the new type-level wanted for `co` is effectively rewritten by
|
|
2067 | + the kind-level one. We thus include the kind-level wanted in the RewriterSet
|
|
2068 | + for the type-level one. See Note [Wanteds rewrite Wanteds] in
|
|
2069 | + GHC.Tc.Types.Constraint. This is done in canEqCanLHSHetero.
|
|
2060 | 2070 | |
2061 | 2071 | (EIK2) Suppose we have [W] (a::Type) ~ (b::Type->Type). The above rewrite will produce
|
2062 | 2072 | [W] w : a ~ (b |> kw)
|
... | ... | @@ -2076,13 +2086,17 @@ Wrinkles: |
2076 | 2086 | Instead, it lands in the inert_irreds in the inert set, awaiting solution of
|
2077 | 2087 | that `kw`.
|
2078 | 2088 | |
2079 | - (EIK2a) We must later indeed unify if/when the kind-level wanted, `kw` gets
|
|
2080 | - solved. This is done in kickOutAfterFillingCoercionHole, which kicks out
|
|
2089 | + (EIK2a) We must later indeed unify if/when the kind-level wanted, `kw` gets
|
|
2090 | + solved. This is done in `kickOutAfterFillingCoercionHole`, which kicks out
|
|
2081 | 2091 | all equalities whose RHS mentions the filled-in coercion hole. Note that
|
2082 | 2092 | it looks for type family equalities, too, because of the use of unifyTest
|
2083 | 2093 | in canEqTyVarFunEq.
|
2084 | 2094 | |
2085 | - (EIK2b) What if the RHS mentions /other/ coercion holes? How can that happen? The
|
|
2095 | + To do this, we slightly-hackily use the `ctev_rewriters` field of the inert,
|
|
2096 | + which records that `w` has been rewritten by `kw`.
|
|
2097 | + See (WRW3) in Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint.
|
|
2098 | + |
|
2099 | + (EIK2b) What if the RHS mentions /other/ coercion holes? How can that happen? The
|
|
2086 | 2100 | main way is like this. Assume F :: forall k. k -> Type
|
2087 | 2101 | [W] kw : k ~ Type
|
2088 | 2102 | [W] w : a ~ F k t
|
... | ... | @@ -2093,15 +2107,32 @@ Wrinkles: |
2093 | 2107 | rewriting. Indeed tests JuanLopez only typechecks if we do. So we'd like to treat
|
2094 | 2108 | this kind of equality as canonical.
|
2095 | 2109 | |
2096 | - Hence the ch_hetero_kind field in CoercionHole: it is True of constraints
|
|
2097 | - created by `canEqCanLHSHetero` to fix up hetero-kinded equalities; and False otherwise:
|
|
2110 | + So here is our implementation:
|
|
2111 | + * The `ch_hetero_kind` field in CoercionHole identifies a coercion hole created
|
|
2112 | + by `canEqCanLHSHetero` to fix up hetero-kinded equalities.
|
|
2113 | + |
|
2114 | + * An equality constraint is non-canonical if it mentions a /hetero-kind/
|
|
2115 | + CoercionHole on the RHS. This (and only this) is the (TyEq:CH) invariant
|
|
2116 | + for canonical equalities (see Note [Canonical equalities])
|
|
2117 | + |
|
2118 | + * The invariant is checked by the `hasHeterKindCoercionHoleCo` test in
|
|
2119 | + GHC.Tc.Utils.Unify.checkCo; and not satisfying this invariant is what
|
|
2120 | + `cteCoercionHole` in `CheckTyEqResult` means.
|
|
2098 | 2121 | |
2099 | - * An equality constraint is non-canonical if it mentions a hetero-kind
|
|
2100 | - CoercionHole on the RHS. See the `hasCoercionHoleCo` test in GHC.Tc.Utils.checkCo.
|
|
2122 | + * These special hetero-kind CoercionHoles are created by the `uType` unifier when
|
|
2123 | + the parent's CtOrigin is KindEqOrigin: see GHC.Tc.Utils.TcMType.newCoercionHole
|
|
2124 | + and friends.
|
|
2101 | 2125 | |
2102 | - * Hetero-kind CoercionHoles are created when the parent's CtOrigin is
|
|
2103 | - KindEqOrigin: see GHC.Tc.Utils.TcMType.newCoercionHole and friends. We
|
|
2104 | - set this origin, via `mkKindLoc`, in `mk_kind_eq` in `canEqCanLHSHetero`.
|
|
2126 | + We set this origin, via `updUEnvLoc`, in `mk_kind_eq` in `canEqCanLHSHetero`.
|
|
2127 | + |
|
2128 | + * We /also/ add the coercion hole to the `RewriterSet` of the constraint,
|
|
2129 | + in `canEqCanLHSHetero`
|
|
2130 | + |
|
2131 | + * When filling one of these special hetero-kind coercion holes, we kick out
|
|
2132 | + any IrredCt's that mention this hole; maybe it is now canonical.
|
|
2133 | + See `kickOutAfterFillingCoercionHole`.
|
|
2134 | + |
|
2135 | + Gah! This is bizarrely complicated.
|
|
2105 | 2136 | |
2106 | 2137 | (EIK3) Suppose we have [W] (a :: k1) ~ (rhs :: k2). We duly follow the
|
2107 | 2138 | algorithm detailed here, producing [W] co :: k1 ~ k2, and adding
|
... | ... | @@ -2576,17 +2607,17 @@ Suppose we have |
2576 | 2607 | Then we can simply solve g2 from g1, thus g2 := g1. Easy!
|
2577 | 2608 | But it's not so simple:
|
2578 | 2609 | |
2579 | -* If t is a type variable, the equalties might be oriented differently:
|
|
2610 | +(CE1) If t is a type variable, the equalties might be oriented differently:
|
|
2580 | 2611 | e.g. (g1 :: a~b) and (g2 :: b~a)
|
2581 | 2612 | So we look both ways round. Hence the SwapFlag result to
|
2582 | 2613 | inertsCanDischarge.
|
2583 | 2614 | |
2584 | -* We can only do g2 := g1 if g1 can discharge g2; that depends on
|
|
2615 | +(CE2) We can only do g2 := g1 if g1 can discharge g2; that depends on
|
|
2585 | 2616 | (a) the role and (b) the flavour. E.g. a representational equality
|
2586 | 2617 | cannot discharge a nominal one; a Wanted cannot discharge a Given.
|
2587 | 2618 | The predicate is eqCanRewriteFR.
|
2588 | 2619 | |
2589 | -* Visibility. Suppose S :: forall k. k -> Type, and consider unifying
|
|
2620 | +(CE3) Visibility. Suppose S :: forall k. k -> Type, and consider unifying
|
|
2590 | 2621 | S @Type (a::Type) ~ S @(Type->Type) (b::Type->Type)
|
2591 | 2622 | From the first argument we get (Type ~ Type->Type); from the second
|
2592 | 2623 | argument we get (a ~ b) which in turn gives (Type ~ Type->Type).
|
... | ... | @@ -2601,6 +2632,24 @@ But it's not so simple: |
2601 | 2632 | So when combining two otherwise-identical equalites, we want to
|
2602 | 2633 | keep the visible one, and discharge the invisible one. Hence the
|
2603 | 2634 | call to strictly_more_visible.
|
2635 | + |
|
2636 | +(CE4) Suppose we have this set up (#25440):
|
|
2637 | + Inert: [W] g1: F a ~ a Int (arising from (F a ~ a Int)
|
|
2638 | + Work item: [W] g2: F alpha ~ F a (arising from (F alpha ~ F a)
|
|
2639 | + We rewrite g2 with g1, to give
|
|
2640 | + [W] g2{rw:g1} : F alpha ~ a Int
|
|
2641 | + Now if F is injective we can get [W] alpha~a, and hence alpha:=a, and
|
|
2642 | + we kick out g1. Now we have two constraints
|
|
2643 | + [W] g1 : F a ~ a Int (arising from (F a ~ a Int)
|
|
2644 | + [W] g2{rw:g1} : F a ~ a Int (arising from (F alpha ~ F a)
|
|
2645 | + If we end up with g2 in the inert set (not g1) we'll get a very confusing
|
|
2646 | + error message that we can solve (F a ~ a Int)
|
|
2647 | + arising from F a ~ F a
|
|
2648 | + |
|
2649 | + TL;DR: Better to hang on to `g1` (with no rewriters), in preference
|
|
2650 | + to `g2` (which has a rewriter).
|
|
2651 | + |
|
2652 | + See (WRW1) in Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint.
|
|
2604 | 2653 | -}
|
2605 | 2654 | |
2606 | 2655 | tryInertEqs :: EqCt -> SolverStage ()
|
... | ... | @@ -2646,21 +2695,27 @@ inertsCanDischarge inerts (EqCt { eq_lhs = lhs_w, eq_rhs = rhs_w |
2646 | 2695 | loc_w = ctEvLoc ev_w
|
2647 | 2696 | flav_w = ctEvFlavour ev_w
|
2648 | 2697 | fr_w = (flav_w, eq_rel)
|
2698 | + empty_rw_w = isEmptyRewriterSet (ctEvRewriters ev_w)
|
|
2649 | 2699 | |
2650 | 2700 | inert_beats_wanted ev_i eq_rel
|
2651 | 2701 | = -- eqCanRewriteFR: see second bullet of Note [Combining equalities]
|
2652 | - -- strictly_more_visible: see last bullet of Note [Combining equalities]
|
|
2653 | 2702 | fr_i `eqCanRewriteFR` fr_w
|
2654 | - && not ((loc_w `strictly_more_visible` ctEvLoc ev_i)
|
|
2655 | - && (fr_w `eqCanRewriteFR` fr_i))
|
|
2703 | + && not (prefer_wanted ev_i && (fr_w `eqCanRewriteFR` fr_i))
|
|
2656 | 2704 | where
|
2657 | 2705 | fr_i = (ctEvFlavour ev_i, eq_rel)
|
2658 | 2706 | |
2659 | - -- See Note [Combining equalities], final bullet
|
|
2707 | + -- See (CE3) in Note [Combining equalities]
|
|
2660 | 2708 | strictly_more_visible loc1 loc2
|
2661 | 2709 | = not (isVisibleOrigin (ctLocOrigin loc2)) &&
|
2662 | 2710 | isVisibleOrigin (ctLocOrigin loc1)
|
2663 | 2711 | |
2712 | + prefer_wanted ev_i
|
|
2713 | + = (loc_w `strictly_more_visible` ctEvLoc ev_i)
|
|
2714 | + -- strictly_more_visible: see (CE3) in Note [Combining equalities]
|
|
2715 | + || (empty_rw_w && not (isEmptyRewriterSet (ctEvRewriters ev_i)))
|
|
2716 | + -- Prefer the one that has no rewriters
|
|
2717 | + -- See (CE4) in Note [Combining equalities]
|
|
2718 | + |
|
2664 | 2719 | inertsCanDischarge _ _ = Nothing
|
2665 | 2720 | |
2666 | 2721 |
... | ... | @@ -150,7 +150,6 @@ import qualified GHC.Tc.Utils.Env as TcM |
150 | 150 | )
|
151 | 151 | import GHC.Tc.Zonk.Monad ( ZonkM )
|
152 | 152 | import qualified GHC.Tc.Zonk.TcType as TcM
|
153 | -import qualified GHC.Tc.Zonk.Type as TcM
|
|
154 | 153 | |
155 | 154 | import GHC.Driver.DynFlags
|
156 | 155 | |
... | ... | @@ -475,10 +474,14 @@ kickOutAfterUnification tv_list = case nonEmpty tv_list of |
475 | 474 | ; return n_kicked }
|
476 | 475 | |
477 | 476 | kickOutAfterFillingCoercionHole :: CoercionHole -> TcS ()
|
478 | --- See Wrinkle (EIK2a) in Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality
|
|
477 | +-- See Wrinkle (EIK2) in Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality
|
|
479 | 478 | -- It's possible that this could just go ahead and unify, but could there be occurs-check
|
480 | 479 | -- problems? Seems simpler just to kick out.
|
481 | 480 | kickOutAfterFillingCoercionHole hole
|
481 | + | not (isHeteroKindCoHole hole)
|
|
482 | + = return () -- Only hetero-kind coercion holes provoke kick-out;
|
|
483 | + -- see (EIK2b) in Note [Equalities with incompatible kinds]
|
|
484 | + | otherwise
|
|
482 | 485 | = do { ics <- getInertCans
|
483 | 486 | ; let (kicked_out, ics') = kick_out ics
|
484 | 487 | n_kicked = lengthBag kicked_out
|
... | ... | @@ -497,14 +500,14 @@ kickOutAfterFillingCoercionHole hole |
497 | 500 | kick_out ics@(IC { inert_irreds = irreds })
|
498 | 501 | = -- We only care about irreds here, because any constraint blocked
|
499 | 502 | -- by a coercion hole is an irred. See wrinkle (EIK2a) in
|
500 | - -- Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical
|
|
503 | + -- Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality
|
|
501 | 504 | (irreds_to_kick, ics { inert_irreds = irreds_to_keep })
|
502 | 505 | where
|
503 | 506 | (irreds_to_kick, irreds_to_keep) = partitionBag kick_ct irreds
|
504 | 507 | |
505 | - kick_ct :: IrredCt -> Bool
|
|
506 | - -- True: kick out; False: keep.
|
|
507 | - kick_ct ct
|
|
508 | + kick_ct :: IrredCt -> Bool -- True: kick out; False: keep.
|
|
509 | + kick_ct ct -- See (EIK2) in Note [Equalities with incompatible kinds]
|
|
510 | + -- for this very specific kick-ot stuff
|
|
508 | 511 | | IrredCt { ir_ev = ev, ir_reason = reason } <- ct
|
509 | 512 | , CtWanted (WantedCt { ctev_rewriters = RewriterSet rewriters }) <- ev
|
510 | 513 | , NonCanonicalReason ctyeq <- reason
|
... | ... | @@ -847,17 +850,15 @@ removeInertCt is ct |
847 | 850 | |
848 | 851 | -- | Looks up a family application in the inerts.
|
849 | 852 | lookupFamAppInert :: (CtFlavourRole -> Bool) -- can it rewrite the target?
|
850 | - -> TyCon -> [Type] -> TcS (Maybe (Reduction, CtFlavourRole))
|
|
853 | + -> TyCon -> [Type] -> TcS (Maybe EqCt)
|
|
851 | 854 | lookupFamAppInert rewrite_pred fam_tc tys
|
852 | 855 | = do { IS { inert_cans = IC { inert_funeqs = inert_funeqs } } <- getInertSet
|
853 | 856 | ; return (lookup_inerts inert_funeqs) }
|
854 | 857 | where
|
855 | 858 | lookup_inerts inert_funeqs
|
856 | - | Just ecl <- findFunEq inert_funeqs fam_tc tys
|
|
857 | - , Just (EqCt { eq_ev = ctev, eq_rhs = rhs })
|
|
858 | - <- find (rewrite_pred . eqCtFlavourRole) ecl
|
|
859 | - = Just (mkReduction (ctEvCoercion ctev) rhs, ctEvFlavourRole ctev)
|
|
860 | - | otherwise = Nothing
|
|
859 | + = case findFunEq inert_funeqs fam_tc tys of
|
|
860 | + Nothing -> Nothing
|
|
861 | + Just (ecl :: [EqCt]) -> find (rewrite_pred . eqCtFlavourRole) ecl
|
|
861 | 862 | |
862 | 863 | lookupInInerts :: CtLoc -> TcPredType -> TcS (Maybe CtEvidence)
|
863 | 864 | -- Is this exact predicate type cached in the solved or canonicals of the InertSet?
|
... | ... | @@ -1467,8 +1468,8 @@ emitWork cts |
1467 | 1468 | -- c1 is rewritten by another, c2. When c2 gets solved,
|
1468 | 1469 | -- c1 has no rewriters, and can be prioritised; see
|
1469 | 1470 | -- Note [Prioritise Wanteds with empty RewriterSet]
|
1470 | - -- in GHC.Tc.Types.Constraint wrinkle (WRW1)
|
|
1471 | - ; cts <- wrapTcS $ mapBagM TcM.zonkCtRewriterSet cts
|
|
1471 | + -- in GHC.Tc.Types.Constraint wrinkle (PER1)
|
|
1472 | + ; cts <- liftZonkTcS $ mapBagM TcM.zonkCtRewriterSet cts
|
|
1472 | 1473 | ; updWorkListTcS (extendWorkListCts cts) }
|
1473 | 1474 | |
1474 | 1475 | emitImplication :: Implication -> TcS ()
|
... | ... | @@ -2340,7 +2341,7 @@ wrapUnifierX ev role do_unifications |
2340 | 2341 | ; wrapTcS $
|
2341 | 2342 | do { defer_ref <- TcM.newTcRef emptyBag
|
2342 | 2343 | ; unified_ref <- TcM.newTcRef []
|
2343 | - ; rewriters <- TcM.zonkRewriterSet (ctEvRewriters ev)
|
|
2344 | + ; rewriters <- TcM.liftZonkM (TcM.zonkRewriterSet (ctEvRewriters ev))
|
|
2344 | 2345 | ; let env = UE { u_role = role
|
2345 | 2346 | , u_rewriters = rewriters
|
2346 | 2347 | , u_loc = ctEvLoc ev
|
... | ... | @@ -150,13 +150,16 @@ bumpDepth (RewriteM thing_inside) |
150 | 150 | { let !env' = env { re_loc = bumpCtLocDepth (re_loc env) }
|
151 | 151 | ; thing_inside env' }
|
152 | 152 | |
153 | +recordRewriter :: CtEvidence -> RewriteM ()
|
|
154 | +-- Record that we have rewritten the target with this (equality) evidence
|
|
153 | 155 | -- See Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
|
154 | --- Precondition: the WantedCtEvidence is for an equality constraint
|
|
155 | -recordRewriter :: WantedCtEvidence -> RewriteM ()
|
|
156 | -recordRewriter (WantedCt { ctev_dest = HoleDest hole })
|
|
157 | - = RewriteM $ \env -> updTcRef (re_rewriters env) (`addRewriter` hole)
|
|
158 | -recordRewriter other =
|
|
159 | - pprPanic "recordRewriter: non-equality constraint" (ppr other)
|
|
156 | +-- Precondition: the CtEvidence is for an equality constraint
|
|
157 | +recordRewriter (CtGiven {})
|
|
158 | + = return ()
|
|
159 | +recordRewriter (CtWanted (WantedCt { ctev_dest = dest }))
|
|
160 | + = case dest of
|
|
161 | + HoleDest hole -> RewriteM $ \env -> updTcRef (re_rewriters env) (`addRewriter` hole)
|
|
162 | + other -> pprPanic "recordRewriter: non-equality constraint" (ppr other)
|
|
160 | 163 | |
161 | 164 | {- Note [Rewriter EqRels]
|
162 | 165 | ~~~~~~~~~~~~~~~~~~~~~~~~~
|
... | ... | @@ -848,16 +851,18 @@ rewrite_exact_fam_app tc tys |
848 | 851 | |
849 | 852 | -- STEP 3: try the inerts
|
850 | 853 | ; flavour <- getFlavour
|
851 | - ; result2 <- liftTcS $ lookupFamAppInert (`eqCanRewriteFR` (flavour, eq_rel)) tc xis
|
|
852 | - ; case result2 of
|
|
853 | - { Just (redn, (inert_flavour, inert_eq_rel))
|
|
854 | + ; mb_eq <- liftTcS $ lookupFamAppInert (`eqCanRewriteFR` (flavour, eq_rel)) tc xis
|
|
855 | + ; case mb_eq of
|
|
856 | + { Just (EqCt { eq_ev = inert_ev, eq_rhs = inert_rhs, eq_eq_rel = inert_eq_rel })
|
|
854 | 857 | -> do { traceRewriteM "rewrite family application with inert"
|
855 | 858 | (ppr tc <+> ppr xis $$ ppr redn)
|
856 | - ; finish (inert_flavour == Given) (homogenise downgraded_redn) }
|
|
857 | - -- this will sometimes duplicate an inert in the cache,
|
|
859 | + ; recordRewriter inert_ev
|
|
860 | + ; finish (isGiven inert_ev) (homogenise downgraded_redn) }
|
|
861 | + -- This will sometimes duplicate an inert in the cache,
|
|
858 | 862 | -- but avoiding doing so had no impact on performance, and
|
859 | 863 | -- it seems easier not to weed out that special case
|
860 | 864 | where
|
865 | + redn = mkReduction (ctEvCoercion inert_ev) inert_rhs
|
|
861 | 866 | inert_role = eqRelRole inert_eq_rel
|
862 | 867 | role = eqRelRole eq_rel
|
863 | 868 | downgraded_redn = downgradeRedn role inert_role redn
|
... | ... | @@ -1024,11 +1029,8 @@ rewrite_tyvar2 tv fr@(_, eq_rel) |
1024 | 1029 | -> do { traceRewriteM "Following inert tyvar" $
|
1025 | 1030 | vcat [ ppr tv <+> equals <+> ppr rhs_ty
|
1026 | 1031 | , ppr ctev ]
|
1027 | - ; case ctev of
|
|
1028 | - CtGiven {} -> return ()
|
|
1029 | - CtWanted wtd ->
|
|
1032 | + ; recordRewriter ctev
|
|
1030 | 1033 | -- See Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint
|
1031 | - recordRewriter wtd
|
|
1032 | 1034 | |
1033 | 1035 | ; let rewriting_co1 = ctEvCoercion ctev
|
1034 | 1036 | rewriting_co = case (ct_eq_rel, eq_rel) of
|
... | ... | @@ -240,18 +240,24 @@ instance Outputable DictCt where |
240 | 240 | {- Note [Canonical equalities]
|
241 | 241 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
242 | 242 | An EqCt is a canonical equality constraint, one that can live in the inert set,
|
243 | -and that can be used to rewrite other constrtaints. It satisfies these invariants:
|
|
243 | +and that can be used to rewrite other constraints. It satisfies these invariants:
|
|
244 | + |
|
244 | 245 | * (TyEq:OC) lhs does not occur in rhs (occurs check)
|
245 | 246 | Note [EqCt occurs check]
|
247 | + |
|
246 | 248 | * (TyEq:F) rhs has no foralls
|
247 | 249 | (this avoids substituting a forall for the tyvar in other types)
|
250 | + |
|
248 | 251 | * (TyEq:K) typeKind lhs `tcEqKind` typeKind rhs; Note [Ct kind invariant]
|
252 | + |
|
249 | 253 | * (TyEq:N) If the equality is representational, rhs is not headed by a saturated
|
250 | 254 | application of a newtype TyCon. See GHC.Tc.Solver.Equality
|
251 | 255 | Note [No top-level newtypes on RHS of representational equalities].
|
252 | 256 | (Applies only when constructor of newtype is in scope.)
|
257 | + |
|
253 | 258 | * (TyEq:U) An EqCt is not immediately unifiable. If we can unify a:=ty, we
|
254 | 259 | will not form an EqCt (a ~ ty).
|
260 | + |
|
255 | 261 | * (TyEq:CH) rhs does not mention any coercion holes that resulted from fixing up
|
256 | 262 | a hetero-kinded equality. See Note [Equalities with incompatible kinds] in
|
257 | 263 | GHC.Tc.Solver.Equality, wrinkle (EIK2)
|
... | ... | @@ -534,9 +540,12 @@ cteSolubleOccurs = CTEP (bit 3) -- Occurs-check under a type function, or in |
534 | 540 | -- cteSolubleOccurs must be one bit to the left of cteInsolubleOccurs
|
535 | 541 | -- See also Note [Insoluble mis-match] in GHC.Tc.Errors
|
536 | 542 | |
537 | -cteCoercionHole = CTEP (bit 4) -- Coercion hole encountered
|
|
543 | +cteCoercionHole = CTEP (bit 4) -- Kind-equality coercion hole encountered
|
|
544 | + -- See (EIK2) in Note [Equalities with incompatible kinds]
|
|
545 | + |
|
538 | 546 | cteConcrete = CTEP (bit 5) -- Type variable that can't be made concrete
|
539 | 547 | -- e.g. alpha[conc] ~ Maybe beta[tv]
|
548 | + |
|
540 | 549 | cteSkolemEscape = CTEP (bit 6) -- Skolem escape e.g. alpha[2] ~ b[sk,4]
|
541 | 550 | |
542 | 551 | cteProblem :: CheckTyEqProblem -> CheckTyEqResult
|
... | ... | @@ -2444,19 +2453,29 @@ We thus want Wanteds to rewrite Wanteds in order to accept more programs, |
2444 | 2453 | but we don't want Wanteds to rewrite Wanteds because doing so can create
|
2445 | 2454 | inscrutable error messages. To solve this dilemma:
|
2446 | 2455 | |
2447 | -* We allow Wanteds to rewrite Wanteds, but...
|
|
2456 | +* We allow Wanteds to rewrite Wanteds, but each Wanted tracks the set of Wanteds
|
|
2457 | + it has been rewritten by, in its RewriterSet, stored in the ctev_rewriters
|
|
2458 | + field of the CtWanted constructor of CtEvidence. (Only Wanteds have
|
|
2459 | + RewriterSets.)
|
|
2460 | + |
|
2461 | +* A RewriterSet is just a set of unfilled CoercionHoles. This is sufficient
|
|
2462 | + because only equalities (evidenced by coercion holes) are used for rewriting;
|
|
2463 | + other (dictionary) constraints cannot ever rewrite.
|
|
2448 | 2464 | |
2449 | -* Each Wanted tracks the set of Wanteds it has been rewritten by, in its
|
|
2450 | - RewriterSet, stored in the ctev_rewriters field of the CtWanted
|
|
2451 | - constructor of CtEvidence. (Only Wanteds have RewriterSets.)
|
|
2465 | +* The rewriter (in e.g. GHC.Tc.Solver.Rewrite.rewrite) tracks and returns a RewriterSet,
|
|
2466 | + consisting of the evidence (a CoercionHole) for any Wanted equalities used in
|
|
2467 | + rewriting.
|
|
2468 | + |
|
2469 | +* Then GHC.Tc.Solver.Solve.rewriteEvidence and GHC.Tc.Solver.Equality.rewriteEqEvidence
|
|
2470 | + add this RewriterSet to the rewritten constraint's rewriter set.
|
|
2452 | 2471 | |
2453 | 2472 | * In error reporting, we simply suppress any errors that have been rewritten
|
2454 | 2473 | by /unsolved/ wanteds. This suppression happens in GHC.Tc.Errors.mkErrorItem,
|
2455 | - which uses GHC.Tc.Zonk.Type.zonkRewriterSet to look through any filled
|
|
2474 | + which uses `GHC.Tc.Zonk.Type.zonkRewriterSet` to look through any filled
|
|
2456 | 2475 | coercion holes. The idea is that we wish to report the "root cause" -- the
|
2457 | 2476 | error that rewrote all the others.
|
2458 | 2477 | |
2459 | -* We prioritise Wanteds that have an empty RewriterSet:
|
|
2478 | +* In error reporting, we prioritise Wanteds that have an empty RewriterSet:
|
|
2460 | 2479 | see Note [Prioritise Wanteds with empty RewriterSet].
|
2461 | 2480 | |
2462 | 2481 | Let's continue our first example above:
|
... | ... | @@ -2471,19 +2490,30 @@ Because Wanteds can rewrite Wanteds, w1 will rewrite w2, yielding |
2471 | 2490 | |
2472 | 2491 | The {w1} in the second line of output is the RewriterSet of w1.
|
2473 | 2492 | |
2474 | -A RewriterSet is just a set of unfilled CoercionHoles. This is sufficient
|
|
2475 | -because only equalities (evidenced by coercion holes) are used for rewriting;
|
|
2476 | -other (dictionary) constraints cannot ever rewrite. The rewriter (in
|
|
2477 | -e.g. GHC.Tc.Solver.Rewrite.rewrite) tracks and returns a RewriterSet,
|
|
2478 | -consisting of the evidence (a CoercionHole) for any Wanted equalities used in
|
|
2479 | -rewriting. Then GHC.Tc.Solver.Solve.rewriteEvidence and
|
|
2480 | -GHC.Tc.Solver.Equality.rewriteEqEvidence add this RewriterSet to the rewritten
|
|
2481 | -constraint's rewriter set.
|
|
2493 | +Wrinkles:
|
|
2494 | + |
|
2495 | +(WRW1) When we find a constraint identical to one already in the inert set,
|
|
2496 | + we solve one from the other. Other things being equal, keep the one
|
|
2497 | + that has fewer (better still no) rewriters.
|
|
2498 | + See (CE4) in Note [Combining equalities] in GHC.Tc.Solver.Equality.
|
|
2499 | + |
|
2500 | + To this accurately we should use `zonkRewriterSet` during canonicalisation,
|
|
2501 | + to eliminate rewriters that have now been solved. Currently we only do so
|
|
2502 | + during error reporting; but perhaps we should change that.
|
|
2503 | + |
|
2504 | +(WRW2) When zonking a constraint (with `zonkCt` and `zonkCtEvidence`) we take
|
|
2505 | + the opportunity to zonk its `RewriterSet`, which eliminates solved ones.
|
|
2506 | + This doesn't guarantee that rewriter sets are always up to date -- see
|
|
2507 | + (WRW1) -- but it helps, and it de-clutters debug output.
|
|
2508 | + |
|
2509 | +(WRW3) We use the rewriter set for a slightly different purpose, in (EIK2)
|
|
2510 | + of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality.
|
|
2511 | + This is a bit of a hack.
|
|
2482 | 2512 | |
2483 | 2513 | Note [Prioritise Wanteds with empty RewriterSet]
|
2484 | 2514 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2485 | 2515 | When extending the WorkList, in GHC.Tc.Solver.InertSet.extendWorkListEq,
|
2486 | -we priorities constraints that have no rewriters. Here's why.
|
|
2516 | +we prioritise constraints that have no rewriters. Here's why.
|
|
2487 | 2517 | |
2488 | 2518 | Consider this, which came up in T22793:
|
2489 | 2519 | inert: {}
|
... | ... | @@ -2527,11 +2557,11 @@ GHC.Tc.Solver.InertSet.extendWorkListEq, and extendWorkListEqs. |
2527 | 2557 | |
2528 | 2558 | Wrinkles
|
2529 | 2559 | |
2530 | -(WRW1) Before checking for an empty RewriterSet, we zonk the RewriterSet,
|
|
2560 | +(PER1) Before checking for an empty RewriterSet, we zonk the RewriterSet,
|
|
2531 | 2561 | because some of those CoercionHoles may have been filled in since we last
|
2532 | 2562 | looked: see GHC.Tc.Solver.Monad.emitWork.
|
2533 | 2563 | |
2534 | -(WRW2) Despite the prioritisation, it is hard to be /certain/ that we can't end up
|
|
2564 | +(PER2) Despite the prioritisation, it is hard to be /certain/ that we can't end up
|
|
2535 | 2565 | in a situation where all of the Wanteds have rewritten each other. In
|
2536 | 2566 | order to report /some/ error in this case, we simply report all the
|
2537 | 2567 | Wanteds. The user will get a perhaps-confusing error message, but they've
|
... | ... | @@ -49,7 +49,6 @@ module GHC.Tc.Utils.TcMType ( |
49 | 49 | |
50 | 50 | newCoercionHole, newCoercionHoleO, newVanillaCoercionHole,
|
51 | 51 | fillCoercionHole, isFilledCoercionHole,
|
52 | - unpackCoercionHole, unpackCoercionHole_maybe,
|
|
53 | 52 | checkCoercionHole,
|
54 | 53 | |
55 | 54 | newImplication,
|
... | ... | @@ -115,7 +114,6 @@ import GHC.Tc.Types.CtLoc( CtLoc, ctLocOrigin ) |
115 | 114 | import GHC.Tc.Utils.Monad -- TcType, amongst others
|
116 | 115 | import GHC.Tc.Utils.TcType
|
117 | 116 | import GHC.Tc.Errors.Types
|
118 | -import GHC.Tc.Zonk.Type
|
|
119 | 117 | import GHC.Tc.Zonk.TcType
|
120 | 118 | |
121 | 119 | import GHC.Builtin.Names
|
... | ... | @@ -371,6 +369,7 @@ newCoercionHoleO (KindEqOrigin {}) pty = new_coercion_hole True pty |
371 | 369 | newCoercionHoleO _ pty = new_coercion_hole False pty
|
372 | 370 | |
373 | 371 | new_coercion_hole :: Bool -> TcPredType -> TcM CoercionHole
|
372 | +-- For the Bool, see (EIK2) in Note [Equalities with incompatible kinds]
|
|
374 | 373 | new_coercion_hole hetero_kind pred_ty
|
375 | 374 | = do { co_var <- newEvVar pred_ty
|
376 | 375 | ; traceTc "New coercion hole:" (ppr co_var <+> dcolon <+> ppr pred_ty)
|
... | ... | @@ -1583,7 +1582,7 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co |
1583 | 1582 | go_co dv (SubCo co) = go_co dv co
|
1584 | 1583 | |
1585 | 1584 | go_co dv (HoleCo hole)
|
1586 | - = do m_co <- unpackCoercionHole_maybe hole
|
|
1585 | + = do m_co <- liftZonkM (unpackCoercionHole_maybe hole)
|
|
1587 | 1586 | case m_co of
|
1588 | 1587 | Just co -> go_co dv co
|
1589 | 1588 | Nothing -> go_cv dv (coHoleCoVar hole)
|
... | ... | @@ -2649,8 +2649,9 @@ There are five reasons not to unify: |
2649 | 2649 | we can fill beta[tau] := beta[conc]. This is why we call
|
2650 | 2650 | 'makeTypeConcrete' in startSolvingByUnification.
|
2651 | 2651 | |
2652 | -5. (COERCION-HOLE) Confusing coercion holes
|
|
2653 | - Suppose our equality is
|
|
2652 | +5. (COERCION-HOLE) rhs does not mention any coercion holes that resulted from
|
|
2653 | + fixing up a hetero-kinded equality. This is the same as (TyEq:CH) in
|
|
2654 | + Note [Canonical equalities]. Suppose our equality is
|
|
2654 | 2655 | (alpha :: k) ~ (Int |> {co})
|
2655 | 2656 | where co :: Type ~ k is an unsolved wanted. Note that this equality
|
2656 | 2657 | is homogeneous; both sides have kind k. We refrain from unifying here, because
|
... | ... | @@ -3549,7 +3550,7 @@ checkCo flags co = |
3549 | 3550 | -- Check for coercion holes, if unifying.
|
3550 | 3551 | -- See (COERCION-HOLE) in Note [Unification preconditions]
|
3551 | 3552 | | case lc of { LC_None {} -> False; _ -> True } -- equivalent to "we are unifying"; see Note [TyEqFlags]
|
3552 | - , hasCoercionHoleCo co
|
|
3553 | + , hasHeteroKindCoercionHoleCo co
|
|
3553 | 3554 | -> return $ PuFail (cteProblem cteCoercionHole)
|
3554 | 3555 | |
3555 | 3556 | -- Occurs check (can promote)
|
1 | +{-# LANGUAGE DuplicateRecordFields #-}
|
|
2 | + |
|
1 | 3 | {-
|
2 | 4 | (c) The University of Glasgow 2006
|
3 | 5 | (c) The AQUA Project, Glasgow University, 1996-1998
|
... | ... | @@ -36,6 +38,13 @@ module GHC.Tc.Zonk.TcType |
36 | 38 | -- ** Zonking constraints
|
37 | 39 | , zonkCt, zonkWC, zonkSimples, zonkImplication
|
38 | 40 | |
41 | + -- * Rewriter sets
|
|
42 | + , zonkRewriterSet, zonkCtRewriterSet, zonkCtEvRewriterSet
|
|
43 | + |
|
44 | + -- * Coercion holes
|
|
45 | + , isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe
|
|
46 | + |
|
47 | + |
|
39 | 48 | -- * Tidying
|
40 | 49 | , tcInitTidyEnv, tcInitOpenTidyEnv
|
41 | 50 | , tidyCt, tidyEvVar, tidyDelayedError
|
... | ... | @@ -81,7 +90,7 @@ import GHC.Core.Coercion |
81 | 90 | import GHC.Core.Predicate
|
82 | 91 | |
83 | 92 | import GHC.Utils.Constants
|
84 | -import GHC.Utils.Outputable
|
|
93 | +import GHC.Utils.Outputable as Outputable
|
|
85 | 94 | import GHC.Utils.Misc
|
86 | 95 | import GHC.Utils.Monad ( mapAccumLM )
|
87 | 96 | import GHC.Utils.Panic
|
... | ... | @@ -89,6 +98,9 @@ import GHC.Utils.Panic |
89 | 98 | import GHC.Data.Bag
|
90 | 99 | import GHC.Data.Pair
|
91 | 100 | |
101 | +import Data.Semigroup
|
|
102 | +import Data.Maybe
|
|
103 | + |
|
92 | 104 | {- *********************************************************************
|
93 | 105 | * *
|
94 | 106 | Writing to metavariables
|
... | ... | @@ -366,8 +378,8 @@ checkCoercionHole cv co |
366 | 378 | ; return $
|
367 | 379 | assertPpr (ok cv_ty)
|
368 | 380 | (text "Bad coercion hole" <+>
|
369 | - ppr cv <> colon <+> vcat [ ppr t1, ppr t2, ppr role
|
|
370 | - , ppr cv_ty ])
|
|
381 | + ppr cv Outputable.<> colon
|
|
382 | + <+> vcat [ ppr t1, ppr t2, ppr role, ppr cv_ty ])
|
|
371 | 383 | co }
|
372 | 384 | | otherwise
|
373 | 385 | = return co
|
... | ... | @@ -494,9 +506,15 @@ zonkCt ct |
494 | 506 | ; return (mkNonCanonical fl') }
|
495 | 507 | |
496 | 508 | zonkCtEvidence :: CtEvidence -> ZonkM CtEvidence
|
497 | -zonkCtEvidence ctev
|
|
498 | - = do { pred' <- zonkTcType (ctEvPred ctev)
|
|
499 | - ; return (setCtEvPredType ctev pred') }
|
|
509 | +-- Zonks the ctev_pred and the ctev_rewriters; but not ctev_evar
|
|
510 | +-- For ctev_rewriters, see (WRW2) in Note [Wanteds rewrite Wanteds]
|
|
511 | +zonkCtEvidence (CtGiven (GivenCt { ctev_pred = pred, ctev_evar = var, ctev_loc = loc }))
|
|
512 | + = do { pred' <- zonkTcType pred
|
|
513 | + ; return (CtGiven (GivenCt { ctev_pred = pred', ctev_evar = var, ctev_loc = loc })) }
|
|
514 | +zonkCtEvidence (CtWanted wanted@(WantedCt { ctev_pred = pred, ctev_rewriters = rws }))
|
|
515 | + = do { pred' <- zonkTcType pred
|
|
516 | + ; rws' <- zonkRewriterSet rws
|
|
517 | + ; return (CtWanted (wanted { ctev_pred = pred', ctev_rewriters = rws' })) }
|
|
500 | 518 | |
501 | 519 | zonkSkolemInfo :: SkolemInfo -> ZonkM SkolemInfo
|
502 | 520 | zonkSkolemInfo (SkolemInfo u sk) = SkolemInfo u <$> zonkSkolemInfoAnon sk
|
... | ... | @@ -530,6 +548,103 @@ win. |
530 | 548 | |
531 | 549 | But c.f Note [Sharing when zonking to Type] in GHC.Tc.Zonk.Type.
|
532 | 550 | |
551 | +%************************************************************************
|
|
552 | +%* *
|
|
553 | + Zonking rewriter sets
|
|
554 | +* *
|
|
555 | +************************************************************************
|
|
556 | +-}
|
|
557 | + |
|
558 | +zonkCtRewriterSet :: Ct -> ZonkM Ct
|
|
559 | +zonkCtRewriterSet ct
|
|
560 | + | isGivenCt ct
|
|
561 | + = return ct
|
|
562 | + | otherwise
|
|
563 | + = case ct of
|
|
564 | + CEqCan eq@(EqCt { eq_ev = ev }) -> do { ev' <- zonkCtEvRewriterSet ev
|
|
565 | + ; return (CEqCan (eq { eq_ev = ev' })) }
|
|
566 | + CIrredCan ir@(IrredCt { ir_ev = ev }) -> do { ev' <- zonkCtEvRewriterSet ev
|
|
567 | + ; return (CIrredCan (ir { ir_ev = ev' })) }
|
|
568 | + CDictCan di@(DictCt { di_ev = ev }) -> do { ev' <- zonkCtEvRewriterSet ev
|
|
569 | + ; return (CDictCan (di { di_ev = ev' })) }
|
|
570 | + CQuantCan {} -> return ct
|
|
571 | + CNonCanonical ev -> do { ev' <- zonkCtEvRewriterSet ev
|
|
572 | + ; return (CNonCanonical ev') }
|
|
573 | + |
|
574 | +zonkCtEvRewriterSet :: CtEvidence -> ZonkM CtEvidence
|
|
575 | +zonkCtEvRewriterSet ev@(CtGiven {})
|
|
576 | + = return ev
|
|
577 | +zonkCtEvRewriterSet ev@(CtWanted wtd)
|
|
578 | + = do { rewriters' <- zonkRewriterSet (ctEvRewriters ev)
|
|
579 | + ; return (CtWanted $ setWantedCtEvRewriters wtd rewriters') }
|
|
580 | + |
|
581 | +-- | Zonk a rewriter set; if a coercion hole in the set has been filled,
|
|
582 | +-- find all the free un-filled coercion holes in the coercion that fills it
|
|
583 | +zonkRewriterSet :: RewriterSet -> ZonkM RewriterSet
|
|
584 | +zonkRewriterSet (RewriterSet set)
|
|
585 | + = nonDetStrictFoldUniqSet go (return emptyRewriterSet) set
|
|
586 | + -- This does not introduce non-determinism, because the only
|
|
587 | + -- monadic action is to read, and the combining function is
|
|
588 | + -- commutative
|
|
589 | + where
|
|
590 | + go :: CoercionHole -> ZonkM RewriterSet -> ZonkM RewriterSet
|
|
591 | + go hole m_acc = unionRewriterSet <$> check_hole hole <*> m_acc
|
|
592 | + |
|
593 | + check_hole :: CoercionHole -> ZonkM RewriterSet
|
|
594 | + check_hole hole
|
|
595 | + = do { m_co <- unpackCoercionHole_maybe hole
|
|
596 | + ; case m_co of
|
|
597 | + Nothing -> return (unitRewriterSet hole) -- Not filled
|
|
598 | + Just co -> unUCHM (check_co co) } -- Filled: look inside
|
|
599 | + |
|
600 | + check_ty :: Type -> UnfilledCoercionHoleMonoid
|
|
601 | + check_co :: Coercion -> UnfilledCoercionHoleMonoid
|
|
602 | + (check_ty, _, check_co, _) = foldTyCo folder ()
|
|
603 | + |
|
604 | + folder :: TyCoFolder () UnfilledCoercionHoleMonoid
|
|
605 | + folder = TyCoFolder { tcf_view = noView
|
|
606 | + , tcf_tyvar = \ _ tv -> check_ty (tyVarKind tv)
|
|
607 | + , tcf_covar = \ _ cv -> check_ty (varType cv)
|
|
608 | + , tcf_hole = \ _ -> UCHM . check_hole
|
|
609 | + , tcf_tycobinder = \ _ _ _ -> () }
|
|
610 | + |
|
611 | +newtype UnfilledCoercionHoleMonoid = UCHM { unUCHM :: ZonkM RewriterSet }
|
|
612 | + |
|
613 | +instance Semigroup UnfilledCoercionHoleMonoid where
|
|
614 | + UCHM l <> UCHM r = UCHM (unionRewriterSet <$> l <*> r)
|
|
615 | + |
|
616 | +instance Monoid UnfilledCoercionHoleMonoid where
|
|
617 | + mempty = UCHM (return emptyRewriterSet)
|
|
618 | + |
|
619 | + |
|
620 | +{-
|
|
621 | +************************************************************************
|
|
622 | +* *
|
|
623 | + Checking for coercion holes
|
|
624 | +* *
|
|
625 | +************************************************************************
|
|
626 | +-}
|
|
627 | + |
|
628 | +-- | Is a coercion hole filled in?
|
|
629 | +isFilledCoercionHole :: CoercionHole -> ZonkM Bool
|
|
630 | +isFilledCoercionHole (CoercionHole { ch_ref = ref })
|
|
631 | + = isJust <$> readTcRef ref
|
|
632 | + |
|
633 | +-- | Retrieve the contents of a coercion hole. Panics if the hole
|
|
634 | +-- is unfilled
|
|
635 | +unpackCoercionHole :: CoercionHole -> ZonkM Coercion
|
|
636 | +unpackCoercionHole hole
|
|
637 | + = do { contents <- unpackCoercionHole_maybe hole
|
|
638 | + ; case contents of
|
|
639 | + Just co -> return co
|
|
640 | + Nothing -> pprPanic "Unfilled coercion hole" (ppr hole) }
|
|
641 | + |
|
642 | +-- | Retrieve the contents of a coercion hole, if it is filled
|
|
643 | +unpackCoercionHole_maybe :: CoercionHole -> ZonkM (Maybe Coercion)
|
|
644 | +unpackCoercionHole_maybe (CoercionHole { ch_ref = ref }) = readTcRef ref
|
|
645 | + |
|
646 | + |
|
647 | +{-
|
|
533 | 648 | %************************************************************************
|
534 | 649 | %* *
|
535 | 650 | Tidying
|
... | ... | @@ -28,12 +28,6 @@ module GHC.Tc.Zonk.Type ( |
28 | 28 | -- ** 'ZonkEnv', and the 'ZonkT' and 'ZonkBndrT' monad transformers
|
29 | 29 | module GHC.Tc.Zonk.Env,
|
30 | 30 | |
31 | - -- * Coercion holes
|
|
32 | - isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe,
|
|
33 | - |
|
34 | - -- * Rewriter sets
|
|
35 | - zonkRewriterSet, zonkCtRewriterSet, zonkCtEvRewriterSet,
|
|
36 | - |
|
37 | 31 | -- * Tidying
|
38 | 32 | tcInitTidyEnv, tcInitOpenTidyEnv,
|
39 | 33 | |
... | ... | @@ -55,7 +49,6 @@ import GHC.Tc.TyCl.Build ( TcMethInfo, MethInfo ) |
55 | 49 | import GHC.Tc.Utils.Env ( tcLookupGlobalOnly )
|
56 | 50 | import GHC.Tc.Utils.TcType
|
57 | 51 | import GHC.Tc.Utils.Monad ( newZonkAnyType, setSrcSpanA, liftZonkM, traceTc, addErr )
|
58 | -import GHC.Tc.Types.Constraint
|
|
59 | 52 | import GHC.Tc.Types.Evidence
|
60 | 53 | import GHC.Tc.Errors.Types
|
61 | 54 | import GHC.Tc.Zonk.Env
|
... | ... | @@ -88,7 +81,6 @@ import GHC.Types.Id |
88 | 81 | import GHC.Types.TypeEnv
|
89 | 82 | import GHC.Types.Basic
|
90 | 83 | import GHC.Types.SrcLoc
|
91 | -import GHC.Types.Unique.Set
|
|
92 | 84 | import GHC.Types.Unique.FM
|
93 | 85 | import GHC.Types.TyThing
|
94 | 86 | |
... | ... | @@ -99,7 +91,6 @@ import GHC.Data.Bag |
99 | 91 | |
100 | 92 | import Control.Monad
|
101 | 93 | import Control.Monad.Trans.Class ( lift )
|
102 | -import Data.Semigroup
|
|
103 | 94 | import Data.List.NonEmpty ( NonEmpty )
|
104 | 95 | import Data.Foldable ( toList )
|
105 | 96 | |
... | ... | @@ -1956,89 +1947,3 @@ finding the free type vars of an expression is necessarily monadic |
1956 | 1947 | operation. (consider /\a -> f @ b, where b is side-effected to a)
|
1957 | 1948 | -}
|
1958 | 1949 | |
1959 | -{-
|
|
1960 | -************************************************************************
|
|
1961 | -* *
|
|
1962 | - Checking for coercion holes
|
|
1963 | -* *
|
|
1964 | -************************************************************************
|
|
1965 | --}
|
|
1966 | - |
|
1967 | --- | Is a coercion hole filled in?
|
|
1968 | -isFilledCoercionHole :: CoercionHole -> TcM Bool
|
|
1969 | -isFilledCoercionHole (CoercionHole { ch_ref = ref })
|
|
1970 | - = isJust <$> readTcRef ref
|
|
1971 | - |
|
1972 | --- | Retrieve the contents of a coercion hole. Panics if the hole
|
|
1973 | --- is unfilled
|
|
1974 | -unpackCoercionHole :: CoercionHole -> TcM Coercion
|
|
1975 | -unpackCoercionHole hole
|
|
1976 | - = do { contents <- unpackCoercionHole_maybe hole
|
|
1977 | - ; case contents of
|
|
1978 | - Just co -> return co
|
|
1979 | - Nothing -> pprPanic "Unfilled coercion hole" (ppr hole) }
|
|
1980 | - |
|
1981 | --- | Retrieve the contents of a coercion hole, if it is filled
|
|
1982 | -unpackCoercionHole_maybe :: CoercionHole -> TcM (Maybe Coercion)
|
|
1983 | -unpackCoercionHole_maybe (CoercionHole { ch_ref = ref }) = readTcRef ref
|
|
1984 | - |
|
1985 | -zonkCtRewriterSet :: Ct -> TcM Ct
|
|
1986 | -zonkCtRewriterSet ct
|
|
1987 | - | isGivenCt ct
|
|
1988 | - = return ct
|
|
1989 | - | otherwise
|
|
1990 | - = case ct of
|
|
1991 | - CEqCan eq@(EqCt { eq_ev = ev }) -> do { ev' <- zonkCtEvRewriterSet ev
|
|
1992 | - ; return (CEqCan (eq { eq_ev = ev' })) }
|
|
1993 | - CIrredCan ir@(IrredCt { ir_ev = ev }) -> do { ev' <- zonkCtEvRewriterSet ev
|
|
1994 | - ; return (CIrredCan (ir { ir_ev = ev' })) }
|
|
1995 | - CDictCan di@(DictCt { di_ev = ev }) -> do { ev' <- zonkCtEvRewriterSet ev
|
|
1996 | - ; return (CDictCan (di { di_ev = ev' })) }
|
|
1997 | - CQuantCan {} -> return ct
|
|
1998 | - CNonCanonical ev -> do { ev' <- zonkCtEvRewriterSet ev
|
|
1999 | - ; return (CNonCanonical ev') }
|
|
2000 | - |
|
2001 | -zonkCtEvRewriterSet :: CtEvidence -> TcM CtEvidence
|
|
2002 | -zonkCtEvRewriterSet ev@(CtGiven {})
|
|
2003 | - = return ev
|
|
2004 | -zonkCtEvRewriterSet ev@(CtWanted wtd)
|
|
2005 | - = do { rewriters' <- zonkRewriterSet (ctEvRewriters ev)
|
|
2006 | - ; return (CtWanted $ setWantedCtEvRewriters wtd rewriters') }
|
|
2007 | - |
|
2008 | --- | Check whether any coercion hole in a RewriterSet is still unsolved.
|
|
2009 | --- Does this by recursively looking through filled coercion holes until
|
|
2010 | --- one is found that is not yet filled in, at which point this aborts.
|
|
2011 | -zonkRewriterSet :: RewriterSet -> TcM RewriterSet
|
|
2012 | -zonkRewriterSet (RewriterSet set)
|
|
2013 | - = nonDetStrictFoldUniqSet go (return emptyRewriterSet) set
|
|
2014 | - -- this does not introduce non-determinism, because the only
|
|
2015 | - -- monadic action is to read, and the combining function is
|
|
2016 | - -- commutative
|
|
2017 | - where
|
|
2018 | - go :: CoercionHole -> TcM RewriterSet -> TcM RewriterSet
|
|
2019 | - go hole m_acc = unionRewriterSet <$> check_hole hole <*> m_acc
|
|
2020 | - |
|
2021 | - check_hole :: CoercionHole -> TcM RewriterSet
|
|
2022 | - check_hole hole = do { m_co <- unpackCoercionHole_maybe hole
|
|
2023 | - ; case m_co of
|
|
2024 | - Nothing -> return (unitRewriterSet hole)
|
|
2025 | - Just co -> unUCHM (check_co co) }
|
|
2026 | - |
|
2027 | - check_ty :: Type -> UnfilledCoercionHoleMonoid
|
|
2028 | - check_co :: Coercion -> UnfilledCoercionHoleMonoid
|
|
2029 | - (check_ty, _, check_co, _) = foldTyCo folder ()
|
|
2030 | - |
|
2031 | - folder :: TyCoFolder () UnfilledCoercionHoleMonoid
|
|
2032 | - folder = TyCoFolder { tcf_view = noView
|
|
2033 | - , tcf_tyvar = \ _ tv -> check_ty (tyVarKind tv)
|
|
2034 | - , tcf_covar = \ _ cv -> check_ty (varType cv)
|
|
2035 | - , tcf_hole = \ _ -> UCHM . check_hole
|
|
2036 | - , tcf_tycobinder = \ _ _ _ -> () }
|
|
2037 | - |
|
2038 | -newtype UnfilledCoercionHoleMonoid = UCHM { unUCHM :: TcM RewriterSet }
|
|
2039 | - |
|
2040 | -instance Semigroup UnfilledCoercionHoleMonoid where
|
|
2041 | - UCHM l <> UCHM r = UCHM (unionRewriterSet <$> l <*> r)
|
|
2042 | - |
|
2043 | -instance Monoid UnfilledCoercionHoleMonoid where
|
|
2044 | - mempty = UCHM (return emptyRewriterSet) |
1 | - |
|
2 | -T3330c.hs:25:43: error: [GHC-18872]
|
|
3 | - • Couldn't match kind ‘* -> *’ with ‘*’
|
|
4 | - When matching types
|
|
5 | - f1 :: * -> *
|
|
6 | - f1 x :: *
|
|
7 | - Expected: Der ((->) x) (Der f1 x)
|
|
8 | - Actual: R f1
|
|
9 | - • In the first argument of ‘plug’, namely ‘rf’
|
|
1 | +T3330c.hs:25:38: error: [GHC-25897]
|
|
2 | + • Could not deduce ‘Der f1 ~ f1’
|
|
3 | + from the context: f ~ (f1 :+: g)
|
|
4 | + bound by a pattern with constructor:
|
|
5 | + RSum :: forall (f :: * -> *) (g :: * -> *).
|
|
6 | + R f -> R g -> R (f :+: g),
|
|
7 | + in an equation for ‘plug'’
|
|
8 | + at T3330c.hs:25:8-17
|
|
9 | + Expected: x -> f1 x
|
|
10 | + Actual: x -> Der f1 x
|
|
11 | + ‘f1’ is a rigid type variable bound by
|
|
12 | + a pattern with constructor:
|
|
13 | + RSum :: forall (f :: * -> *) (g :: * -> *).
|
|
14 | + R f -> R g -> R (f :+: g),
|
|
15 | + in an equation for ‘plug'’
|
|
16 | + at T3330c.hs:25:8-17
|
|
17 | + • The function ‘plug’ is applied to three visible arguments,
|
|
18 | + but its type ‘Rep f => Der f x -> x -> f x’ has only two
|
|
10 | 19 | In the first argument of ‘Inl’, namely ‘(plug rf df x)’
|
11 | 20 | In the expression: Inl (plug rf df x)
|
12 | 21 | • Relevant bindings include
|
13 | - x :: x (bound at T3330c.hs:25:29)
|
|
14 | 22 | df :: Der f1 x (bound at T3330c.hs:25:25)
|
15 | 23 | rf :: R f1 (bound at T3330c.hs:25:13)
|
16 | - plug' :: R f -> Der f x -> x -> f x (bound at T3330c.hs:25:1) |
|
24 | + |
1 | - |
|
2 | -T4174.hs:45:12: error: [GHC-18872]
|
|
3 | - • Couldn't match type ‘False’ with ‘True’
|
|
4 | - arising from a use of ‘sync_large_objects’
|
|
1 | +T4174.hs:45:12: error: [GHC-25897]
|
|
2 | + • Couldn't match type ‘a’ with ‘SmStep’
|
|
3 | + Expected: m (Field (Way (GHC6'8 minor) n t p) a b)
|
|
4 | + Actual: m (Field (WayOf m) SmStep RtsSpinLock)
|
|
5 | + ‘a’ is a rigid type variable bound by
|
|
6 | + the type signature for:
|
|
7 | + testcase :: forall (m :: * -> *) minor n t p a b.
|
|
8 | + Monad m =>
|
|
9 | + m (Field (Way (GHC6'8 minor) n t p) a b)
|
|
10 | + at T4174.hs:44:1-63
|
|
5 | 11 | • In the expression: sync_large_objects
|
6 | 12 | In an equation for ‘testcase’: testcase = sync_large_objects
|
13 | + • Relevant bindings include
|
|
14 | + testcase :: m (Field (Way (GHC6'8 minor) n t p) a b)
|
|
15 | + (bound at T4174.hs:45:1)
|
|
16 | + |
... | ... | @@ -13,12 +13,3 @@ T8227.hs:24:27: error: [GHC-83865] |
13 | 13 | absoluteToParam :: Scalar (V a) -> a -> Scalar (V a)
|
14 | 14 | (bound at T8227.hs:24:1)
|
15 | 15 | |
16 | -T8227.hs:24:48: error: [GHC-27958]
|
|
17 | - • Couldn't match type ‘p0’ with ‘Scalar (V p0)’
|
|
18 | - arising from a type equality Scalar (V a) ~ Scalar (V p0) -> p0
|
|
19 | - The type variable ‘p0’ is ambiguous
|
|
20 | - • In the second argument of ‘arcLengthToParam’, namely ‘eps’
|
|
21 | - In the expression: arcLengthToParam eps eps
|
|
22 | - In an equation for ‘absoluteToParam’:
|
|
23 | - absoluteToParam eps seg = arcLengthToParam eps eps
|
|
24 | - |
1 | -T25266a.hs:10:41: error: [GHC-25897]
|
|
2 | - • Could not deduce ‘p1 ~ p2’
|
|
1 | +T25266a.hs:10:39: error: [GHC-25897]
|
|
2 | + • Could not deduce ‘p2 ~ p1’
|
|
3 | 3 | from the context: a ~ Int
|
4 | 4 | bound by a pattern with constructor: T1 :: T Int,
|
5 | 5 | in a case alternative
|
6 | 6 | at T25266a.hs:10:23-24
|
7 | - ‘p1’ is a rigid type variable bound by
|
|
7 | + ‘p2’ is a rigid type variable bound by
|
|
8 | 8 | the inferred type of f :: p1 -> p2 -> T a -> Int
|
9 | 9 | at T25266a.hs:(9,1)-(11,40)
|
10 | - ‘p2’ is a rigid type variable bound by
|
|
10 | + ‘p1’ is a rigid type variable bound by
|
|
11 | 11 | the inferred type of f :: p1 -> p2 -> T a -> Int
|
12 | 12 | at T25266a.hs:(9,1)-(11,40)
|
13 | - • In the expression: y
|
|
13 | + • In the expression: x
|
|
14 | 14 | In the first argument of ‘length’, namely ‘[x, y]’
|
15 | 15 | In the expression: length [x, y]
|
16 | 16 | • Relevant bindings include
|
1 | - |
|
2 | 1 | T18851.hs:35:5: error: [GHC-18872]
|
3 | - • Couldn't match type ‘B’ with ‘A’
|
|
4 | - arising from a superclass required to satisfy ‘C int0 A’,
|
|
2 | + • Couldn't match type ‘Bool’ with ‘B’
|
|
3 | + arising from a superclass required to satisfy ‘C Int B’,
|
|
5 | 4 | arising from a use of ‘f’
|
6 | 5 | • In the expression: f @A @B
|
7 | 6 | In an equation for ‘g’: g = f @A @B
|
7 | + |