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 | + |