Simon Peyton Jones pushed to branch wip/T25440 at Glasgow Haskell Compiler / GHC
Commits:
-
be011dac
by Simon Peyton Jones at 2025-04-18T13:12:23+01:00
12 changed files:
- 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/Types/Constraint.hs
- compiler/GHC/Tc/Utils/TcMType.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_fail/T18851.stderr
Changes:
| ... | ... | @@ -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
|
| ... | ... | @@ -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
|
| ... | ... | @@ -2077,11 +2077,15 @@ Wrinkles: |
| 2077 | 2077 | that `kw`.
|
| 2078 | 2078 | |
| 2079 | 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
|
|
| 2080 | + solved. This is done in `kickOutAfterFillingCoercionHole`, which kicks out
|
|
| 2081 | 2081 | all equalities whose RHS mentions the filled-in coercion hole. Note that
|
| 2082 | 2082 | it looks for type family equalities, too, because of the use of unifyTest
|
| 2083 | 2083 | in canEqTyVarFunEq.
|
| 2084 | 2084 | |
| 2085 | + To do this, we slightly-hackily use the `ctev_rewriters` field of the inert,
|
|
| 2086 | + which records that `w` has been rewritten by `kw`.
|
|
| 2087 | + See (WRW3) in Note [Wanteds reewrite Wanteds] in GHC.Tc.Types.Constraint.
|
|
| 2088 | + |
|
| 2085 | 2089 | (EIK2b) What if the RHS mentions /other/ coercion holes? How can that happen? The
|
| 2086 | 2090 | main way is like this. Assume F :: forall k. k -> Type
|
| 2087 | 2091 | [W] kw : k ~ Type
|
| ... | ... | @@ -2615,6 +2619,7 @@ But it's not so simple: |
| 2615 | 2619 | error message that we can solve (F a ~ a Int)
|
| 2616 | 2620 | arising from F a ~ F a
|
| 2617 | 2621 | Better to hang on to `g1`, in preference to `g2`.
|
| 2622 | + See (WRW1) in Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint.
|
|
| 2618 | 2623 | -}
|
| 2619 | 2624 | |
| 2620 | 2625 | tryInertEqs :: EqCt -> SolverStage ()
|
| ... | ... | @@ -150,7 +150,6 @@ import qualified GHC.Tc.Utils.Env as TcM |
| 150 | 150 | , topIdLvl )
|
| 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 | |
| ... | ... | @@ -489,7 +488,7 @@ kickOutAfterFillingCoercionHole hole |
| 489 | 488 | kick_out ics@(IC { inert_irreds = irreds })
|
| 490 | 489 | = -- We only care about irreds here, because any constraint blocked
|
| 491 | 490 | -- by a coercion hole is an irred. See wrinkle (EIK2a) in
|
| 492 | - -- Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical
|
|
| 491 | + -- Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality
|
|
| 493 | 492 | (irreds_to_kick, ics { inert_irreds = irreds_to_keep })
|
| 494 | 493 | where
|
| 495 | 494 | (irreds_to_kick, irreds_to_keep) = partitionBag kick_ct irreds
|
| ... | ... | @@ -1457,8 +1456,8 @@ emitWork cts |
| 1457 | 1456 | -- c1 is rewritten by another, c2. When c2 gets solved,
|
| 1458 | 1457 | -- c1 has no rewriters, and can be prioritised; see
|
| 1459 | 1458 | -- Note [Prioritise Wanteds with empty RewriterSet]
|
| 1460 | - -- in GHC.Tc.Types.Constraint wrinkle (WRW1)
|
|
| 1461 | - ; cts <- wrapTcS $ mapBagM TcM.zonkCtRewriterSet cts
|
|
| 1459 | + -- in GHC.Tc.Types.Constraint wrinkle (PER1)
|
|
| 1460 | + ; cts <- liftZonkTcS $ mapBagM TcM.zonkCtRewriterSet cts
|
|
| 1462 | 1461 | ; updWorkListTcS (extendWorkListCts cts) }
|
| 1463 | 1462 | |
| 1464 | 1463 | emitImplication :: Implication -> TcS ()
|
| ... | ... | @@ -2252,7 +2251,7 @@ wrapUnifierX ev role do_unifications |
| 2252 | 2251 | ; wrapTcS $
|
| 2253 | 2252 | do { defer_ref <- TcM.newTcRef emptyBag
|
| 2254 | 2253 | ; unified_ref <- TcM.newTcRef []
|
| 2255 | - ; rewriters <- TcM.zonkRewriterSet (ctEvRewriters ev)
|
|
| 2254 | + ; rewriters <- TcM.liftZonkM (TcM.zonkRewriterSet (ctEvRewriters ev))
|
|
| 2256 | 2255 | ; let env = UE { u_role = role
|
| 2257 | 2256 | , u_rewriters = rewriters
|
| 2258 | 2257 | , u_loc = ctEvLoc ev
|
| ... | ... | @@ -240,7 +240,7 @@ 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 | * (TyEq:OC) lhs does not occur in rhs (occurs check)
|
| 245 | 245 | Note [EqCt occurs check]
|
| 246 | 246 | * (TyEq:F) rhs has no foralls
|
| ... | ... | @@ -2444,19 +2444,29 @@ We thus want Wanteds to rewrite Wanteds in order to accept more programs, |
| 2444 | 2444 | but we don't want Wanteds to rewrite Wanteds because doing so can create
|
| 2445 | 2445 | inscrutable error messages. To solve this dilemma:
|
| 2446 | 2446 | |
| 2447 | -* We allow Wanteds to rewrite Wanteds, but...
|
|
| 2447 | +* We allow Wanteds to rewrite Wanteds, but each Wanted tracks the set of Wanteds
|
|
| 2448 | + it has been rewritten by, in its RewriterSet, stored in the ctev_rewriters
|
|
| 2449 | + field of the CtWanted constructor of CtEvidence. (Only Wanteds have
|
|
| 2450 | + RewriterSets.)
|
|
| 2448 | 2451 | |
| 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.)
|
|
| 2452 | +* A RewriterSet is just a set of unfilled CoercionHoles. This is sufficient
|
|
| 2453 | + because only equalities (evidenced by coercion holes) are used for rewriting;
|
|
| 2454 | + other (dictionary) constraints cannot ever rewrite.
|
|
| 2455 | + |
|
| 2456 | +* The rewriter (in e.g. GHC.Tc.Solver.Rewrite.rewrite) tracks and returns a RewriterSet,
|
|
| 2457 | + consisting of the evidence (a CoercionHole) for any Wanted equalities used in
|
|
| 2458 | + rewriting.
|
|
| 2459 | + |
|
| 2460 | +* Then GHC.Tc.Solver.Solve.rewriteEvidence and GHC.Tc.Solver.Equality.rewriteEqEvidence
|
|
| 2461 | + add this RewriterSet to the rewritten constraint's rewriter set.
|
|
| 2452 | 2462 | |
| 2453 | 2463 | * In error reporting, we simply suppress any errors that have been rewritten
|
| 2454 | 2464 | by /unsolved/ wanteds. This suppression happens in GHC.Tc.Errors.mkErrorItem,
|
| 2455 | - which uses GHC.Tc.Zonk.Type.zonkRewriterSet to look through any filled
|
|
| 2465 | + which uses `GHC.Tc.Zonk.Type.zonkRewriterSet` to look through any filled
|
|
| 2456 | 2466 | coercion holes. The idea is that we wish to report the "root cause" -- the
|
| 2457 | 2467 | error that rewrote all the others.
|
| 2458 | 2468 | |
| 2459 | -* We prioritise Wanteds that have an empty RewriterSet:
|
|
| 2469 | +* In error reporting, we prioritise Wanteds that have an empty RewriterSet:
|
|
| 2460 | 2470 | see Note [Prioritise Wanteds with empty RewriterSet].
|
| 2461 | 2471 | |
| 2462 | 2472 | Let's continue our first example above:
|
| ... | ... | @@ -2471,19 +2481,30 @@ Because Wanteds can rewrite Wanteds, w1 will rewrite w2, yielding |
| 2471 | 2481 | |
| 2472 | 2482 | The {w1} in the second line of output is the RewriterSet of w1.
|
| 2473 | 2483 | |
| 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.
|
|
| 2484 | +Wrinkles:
|
|
| 2485 | + |
|
| 2486 | +(WRW1) When we find a constraint identical to one already in the inert set,
|
|
| 2487 | + we solve one from the other. Other things being equal, keep the one
|
|
| 2488 | + that has fewer (better still no) rewriters.
|
|
| 2489 | + See (CE4) in Note [Combining equalities] in GHC.Tc.Solver.Equality.
|
|
| 2490 | + |
|
| 2491 | + To this accurately we should use `zonkRewriterSet` during canonicalisation,
|
|
| 2492 | + to eliminate rewriters that have now been solved. Currently we only do so
|
|
| 2493 | + during error reporting; but perhaps we should change that.
|
|
| 2494 | + |
|
| 2495 | +(WRW2) When zonk a constraint (with `zonkCt` and `zonkCtEvidence`) we take
|
|
| 2496 | + the opportunity to zonk its `RewriterSet, which eliminates solved ones`.
|
|
| 2497 | + This doesn't guarantee that rewriter sets are always up to date -- see
|
|
| 2498 | + (WRW1) -- but it helps, and it de-clutters debug output.
|
|
| 2499 | + |
|
| 2500 | +(WRW3) We use the rewriter set for a slightly different purpose, in (EIK2)
|
|
| 2501 | + of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality.
|
|
| 2502 | + This is a bit of a hack.
|
|
| 2482 | 2503 | |
| 2483 | 2504 | Note [Prioritise Wanteds with empty RewriterSet]
|
| 2484 | 2505 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 2485 | 2506 | When extending the WorkList, in GHC.Tc.Solver.InertSet.extendWorkListEq,
|
| 2486 | -we priorities constraints that have no rewriters. Here's why.
|
|
| 2507 | +we prioritise constraints that have no rewriters. Here's why.
|
|
| 2487 | 2508 | |
| 2488 | 2509 | Consider this, which came up in T22793:
|
| 2489 | 2510 | inert: {}
|
| ... | ... | @@ -2527,11 +2548,11 @@ GHC.Tc.Solver.InertSet.extendWorkListEq, and extendWorkListEqs. |
| 2527 | 2548 | |
| 2528 | 2549 | Wrinkles
|
| 2529 | 2550 | |
| 2530 | -(WRW1) Before checking for an empty RewriterSet, we zonk the RewriterSet,
|
|
| 2551 | +(PER1) Before checking for an empty RewriterSet, we zonk the RewriterSet,
|
|
| 2531 | 2552 | because some of those CoercionHoles may have been filled in since we last
|
| 2532 | 2553 | looked: see GHC.Tc.Solver.Monad.emitWork.
|
| 2533 | 2554 | |
| 2534 | -(WRW2) Despite the prioritisation, it is hard to be /certain/ that we can't end up
|
|
| 2555 | +(PER2) Despite the prioritisation, it is hard to be /certain/ that we can't end up
|
|
| 2535 | 2556 | in a situation where all of the Wanteds have rewritten each other. In
|
| 2536 | 2557 | order to report /some/ error in this case, we simply report all the
|
| 2537 | 2558 | 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
|
| ... | ... | @@ -1583,7 +1581,7 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co |
| 1583 | 1581 | go_co dv (SubCo co) = go_co dv co
|
| 1584 | 1582 | |
| 1585 | 1583 | go_co dv (HoleCo hole)
|
| 1586 | - = do m_co <- unpackCoercionHole_maybe hole
|
|
| 1584 | + = do m_co <- liftZonkM (unpackCoercionHole_maybe hole)
|
|
| 1587 | 1585 | case m_co of
|
| 1588 | 1586 | Just co -> go_co dv co
|
| 1589 | 1587 | Nothing -> go_cv dv (coHoleCoVar hole)
|
| 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 | +-- | Check whether any coercion hole in a RewriterSet is still unsolved.
|
|
| 582 | +-- Does this by recursively looking through filled coercion holes until
|
|
| 583 | +-- one is found that is not yet filled in, at which point this aborts.
|
|
| 584 | +zonkRewriterSet :: RewriterSet -> ZonkM RewriterSet
|
|
| 585 | +zonkRewriterSet (RewriterSet set)
|
|
| 586 | + = nonDetStrictFoldUniqSet go (return emptyRewriterSet) set
|
|
| 587 | + -- this does not introduce non-determinism, because the only
|
|
| 588 | + -- monadic action is to read, and the combining function is
|
|
| 589 | + -- commutative
|
|
| 590 | + where
|
|
| 591 | + go :: CoercionHole -> ZonkM RewriterSet -> ZonkM RewriterSet
|
|
| 592 | + go hole m_acc = unionRewriterSet <$> check_hole hole <*> m_acc
|
|
| 593 | + |
|
| 594 | + check_hole :: CoercionHole -> ZonkM RewriterSet
|
|
| 595 | + check_hole hole = do { m_co <- unpackCoercionHole_maybe hole
|
|
| 596 | + ; case m_co of
|
|
| 597 | + Nothing -> return (unitRewriterSet hole)
|
|
| 598 | + Just co -> unUCHM (check_co co) }
|
|
| 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 | - |
|
| 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 | + |