Simon Peyton Jones pushed to branch wip/T27844 at Glasgow Haskell Compiler / GHC
Commits:
-
a4233abb
by Simon Peyton Jones at 2026-09-29T00:07:46+01:00
6 changed files:
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Utils/Unify.hs
Changes:
| ... | ... | @@ -630,7 +630,7 @@ be sigmas and not taus. |
| 630 | 630 | ~~~~~~~~~~~~~~~~~~~~~~
|
| 631 | 631 | In the GHCi debugger we use unification variables whose MetaInfo is
|
| 632 | 632 | RuntimeUnkTv. The special property of a RuntimeUnkTv is that it can
|
| 633 | -unify with a polytype (see GHC.Tc.Utils.Unify.checkTypeEq).
|
|
| 633 | +unify with a polytype (see GHC.Tc.Solver.Equality.checkTypeEqNoUnification).
|
|
| 634 | 634 | If we don't do this `:print <term>` will fail if the type of <term>
|
| 635 | 635 | has nested `forall`s or `=>`s.
|
| 636 | 636 |
| ... | ... | @@ -21,6 +21,7 @@ import GHC.Tc.Types.Evidence |
| 21 | 21 | import GHC.Tc.Types.Constraint
|
| 22 | 22 | import GHC.Tc.Types.CtLoc
|
| 23 | 23 | import GHC.Tc.Types.Origin
|
| 24 | +import GHC.Tc.Types( TcM )
|
|
| 24 | 25 | import GHC.Tc.Utils.Unify
|
| 25 | 26 | import GHC.Tc.Utils.TcType
|
| 26 | 27 | import GHC.Tc.Instance.Family ( tcUnwrapNewtype_maybe )
|
| ... | ... | @@ -36,8 +37,8 @@ import GHC.Core.Coercion |
| 36 | 37 | import GHC.Core.Reduction
|
| 37 | 38 | import GHC.Core.FamInstEnv ( FamInstEnvs )
|
| 38 | 39 | import GHC.Core
|
| 39 | -import GHC.Types.Var
|
|
| 40 | 40 | |
| 41 | +import GHC.Types.Var
|
|
| 41 | 42 | import GHC.Types.Basic
|
| 42 | 43 | import GHC.Types.Name.Reader
|
| 43 | 44 | import GHC.Types.Var.Env
|
| ... | ... | @@ -49,6 +50,8 @@ import GHC.Utils.Misc |
| 49 | 50 | import GHC.Utils.Monad
|
| 50 | 51 | |
| 51 | 52 | import GHC.Data.Pair
|
| 53 | +import GHC.Data.Bag
|
|
| 54 | + |
|
| 52 | 55 | import Control.Monad
|
| 53 | 56 | import Data.Maybe ( isJust, isNothing )
|
| 54 | 57 | import Data.List ( zip4 )
|
| ... | ... | @@ -2257,7 +2260,8 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs |
| 2257 | 2260 | else rewriteEqEvidence ev swapped
|
| 2258 | 2261 | (mkReflRedn Nominal (mkTyVarTy tv)) rhs_redn
|
| 2259 | 2262 | emptyCoHoleSet
|
| 2260 | - -- emptyCoHoleSet: rhs_redn has no CoercionHoles
|
|
| 2263 | + -- emptyCoHoleSet: we are about to /solve/ this
|
|
| 2264 | + -- constraint, so its CoHoleSet doesn't matter
|
|
| 2261 | 2265 | |
| 2262 | 2266 | ; let tv_ty = mkTyVarTy tv
|
| 2263 | 2267 | final_rhs = reductionReducedType rhs_redn
|
| ... | ... | @@ -2285,21 +2289,12 @@ canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs |
| 2285 | 2289 | -- We can't unify, but we can see if this equality can go in the inert set
|
| 2286 | 2290 | -- and be used to rewrite other constraints.
|
| 2287 | 2291 | -- See Note [Equalities where unification fails]
|
| 2288 | - = do { -- Do checkTypeEq to guarantee (TyEq:OC), (TyEq:F)
|
|
| 2292 | + = do { -- Do checkTypeEqNoUnfication to guarantee (TyEq:OC), (TyEq:F)
|
|
| 2289 | 2293 | -- Must do the occurs check even on tyvar/tyvar equalities,
|
| 2290 | 2294 | -- in case have x ~ (y :: ..x...); this is #12593.
|
| 2291 | - ; check_result <- checkTypeEq ev eq_rel lhs rhs
|
|
| 2295 | + ; check_result <- checkTypeEqNoUnification ev eq_rel lhs rhs
|
|
| 2292 | 2296 | ; case check_result of
|
| 2293 | 2297 | PuFail reason
|
| 2294 | -{-
|
|
| 2295 | - | reason `cterHasOnlyProblems` do_not_prevent_rewriting
|
|
| 2296 | - -> do { new_ev <- rewriteEqEvidenceSwapOnly ev eq_rel swapped lhs rhs
|
|
| 2297 | - ; continueWith $ Right $
|
|
| 2298 | - EqCt { eq_ev = new_ev, eq_eq_rel = eq_rel
|
|
| 2299 | - , eq_lhs = lhs , eq_rhs = rhs } }
|
|
| 2300 | - |
|
| 2301 | - | otherwise
|
|
| 2302 | --}
|
|
| 2303 | 2298 | -> -- We can't unify, and this equality should not be used to rewrite
|
| 2304 | 2299 | -- other constraints (e.g. because it has an occurs check).
|
| 2305 | 2300 | -- So add it to the inert Irreds.
|
| ... | ... | @@ -2307,19 +2302,27 @@ canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs |
| 2307 | 2302 | ; finishCanWithIrred (NonCanonicalReason reason) new_ev }
|
| 2308 | 2303 | |
| 2309 | 2304 | PuOK new_eqs rhs_redn
|
| 2310 | - -> -- Claim: there should be no new_eqs
|
|
| 2311 | - -- The non-unification check does non promotion nor type-family
|
|
| 2312 | - -- flattening for Wanteds
|
|
| 2305 | + -> -- Put this constraint into the inert set, so that it will be used
|
|
| 2306 | + -- to solve or rewrite other constraints.
|
|
| 2307 | + --
|
|
| 2308 | + -- NB: checkTypeEqNoUnification does not check for
|
|
| 2309 | + -- (b) skolem-escape (tefTyVar_levelCheck = LC_None)
|
|
| 2310 | + -- (a) concreteness (tefTyVar_concreteCheck = CC_None)
|
|
| 2311 | + -- So an equality whose only problem is e.g. skolem-escape will
|
|
| 2312 | + -- return PuOK, will be put in the inert set, will be used for
|
|
| 2313 | + -- rewriting. That is fine.
|
|
| 2314 | + --
|
|
| 2315 | + -- assertPpr (isEmptyCts new_eqs):
|
|
| 2316 | + -- checkTypeEqNoUnification does neither promotion nor type-family
|
|
| 2317 | + -- flattening for Wanteds, and hence creates no equalities to solve
|
|
| 2313 | 2318 | assertPpr (isEmptyCts new_eqs)
|
| 2314 | 2319 | (vcat [ text "new_eqs" <+> ppr new_eqs
|
| 2315 | 2320 | , text "rhs_redn" <+> ppr rhs_redn
|
| 2316 | 2321 | , text "lhs" <+> ppr lhs
|
| 2317 | 2322 | , text "rhs" <+> ppr rhs ]) $
|
| 2318 | - do { emitWork new_eqs
|
|
| 2319 | - ; let new_holes = rewriterSetFromCts new_eqs
|
|
| 2320 | - lhs_ty = canEqLHSType lhs
|
|
| 2323 | + do { let lhs_ty = canEqLHSType lhs
|
|
| 2321 | 2324 | lhs_redn = mkReflRedn (eqRelRole eq_rel) lhs_ty
|
| 2322 | - ; new_ev <- rewriteEqEvidence ev swapped lhs_redn rhs_redn new_holes
|
|
| 2325 | + ; new_ev <- rewriteEqEvidence ev swapped lhs_redn rhs_redn emptyCoHoleSet
|
|
| 2323 | 2326 | |
| 2324 | 2327 | -- Important: even if the coercion is Refl,
|
| 2325 | 2328 | -- * new_ev has reductionReducedType on the RHS
|
| ... | ... | @@ -2330,19 +2333,54 @@ canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs |
| 2330 | 2333 | , eq_lhs = lhs
|
| 2331 | 2334 | , eq_rhs = reductionReducedType rhs_redn } } }
|
| 2332 | 2335 | |
| 2333 | -{-
|
|
| 2334 | --- | Some problems prevent /unification/ but not /rewriting/:
|
|
| 2335 | ---
|
|
| 2336 | --- Skolem-escape: if we have [W] alpha[2] ~ Maybe b[3]
|
|
| 2337 | --- we can't unify (skolem-escape); but it /is/ canonical,
|
|
| 2338 | --- and hence we /can/ use it for rewriting
|
|
| 2339 | ---
|
|
| 2340 | --- Concrete-ness: alpha[conc] ~ b[sk]
|
|
| 2341 | --- We can use it to rewrite; we still have to solve the original
|
|
| 2342 | -do_not_prevent_rewriting :: CheckTyEqResult
|
|
| 2343 | -do_not_prevent_rewriting = cteProblem cteSkolemEscape S.<>
|
|
| 2344 | - cteProblem cteConcrete
|
|
| 2345 | --}
|
|
| 2336 | +checkTypeEqNoUnification :: CtEvidence -> EqRel -> CanEqLHS -> TcType
|
|
| 2337 | + -> TcS (PuResult Ct Reduction)
|
|
| 2338 | +-- Used for general CanEqLHSs, when we have decided that we cannot unify
|
|
| 2339 | +checkTypeEqNoUnification ev eq_rel lhs rhs =
|
|
| 2340 | + case ev of
|
|
| 2341 | + CtGiven {} ->
|
|
| 2342 | + do { traceTcS "checkTypeEqNoUnification (given) {" (vcat [ text "lhs:" <+> ppr lhs
|
|
| 2343 | + , text "rhs:" <+> ppr rhs ])
|
|
| 2344 | + ; check_result <- wrapTcS (checkTyEqRhs given_flags rhs)
|
|
| 2345 | + ; traceTcS "checkTypeEqNoUnification }" (ppr check_result)
|
|
| 2346 | + ; case check_result of
|
|
| 2347 | + PuFail reason -> return (PuFail reason)
|
|
| 2348 | + PuOK prs redn -> do { new_givens <- mapBagM mk_new_given prs
|
|
| 2349 | + ; emitWork new_givens
|
|
| 2350 | + ; updInertSet (addCycleBreakerBindings prs)
|
|
| 2351 | + ; return (pure redn) } }
|
|
| 2352 | + CtWanted {} -> do { traceTcS "checkTypeEqNoUnification (wanted) {" $
|
|
| 2353 | + vcat [ text "lhs:" <+> ppr lhs
|
|
| 2354 | + , text "rhs:" <+> ppr rhs ]
|
|
| 2355 | + ; check_result <- wrapTcS (checkTyEqRhs wanted_flags rhs)
|
|
| 2356 | + ; traceTcS "checkTypeEqNoUnification }" (ppr check_result)
|
|
| 2357 | + ; return check_result }
|
|
| 2358 | + where
|
|
| 2359 | + wanted_flags :: TyEqFlags TcM Ct
|
|
| 2360 | + wanted_flags = notUnifying_TEFTask occ_prob lhs
|
|
| 2361 | + -- See Note [Don't cycle-break Wanteds when not unifying]
|
|
| 2362 | + |
|
| 2363 | + given_flags :: TyEqFlags TcM (TcTyVar, TcType)
|
|
| 2364 | + given_flags = wanted_flags { tef_fam_app = mkTEFA_Break ev eq_rel BreakGiven }
|
|
| 2365 | + -- TEFA_Break used for: [G] a ~ Maybe (F a)
|
|
| 2366 | + -- or [G] F a ~ Maybe (F a)
|
|
| 2367 | + |
|
| 2368 | + -- occ_prob: see Note [Occurs check and representational equality]
|
|
| 2369 | + occ_prob = case eq_rel of
|
|
| 2370 | + NomEq -> cteInsolubleOccurs
|
|
| 2371 | + ReprEq -> cteSolubleOccurs
|
|
| 2372 | + |
|
| 2373 | + ---------------------------
|
|
| 2374 | + mk_new_given :: (TcTyVar, TcType) -> TcS Ct
|
|
| 2375 | + mk_new_given (new_tv, fam_app)
|
|
| 2376 | + = mkNonCanonical . CtGiven <$> newGivenEv cb_loc (given_pred, given_term)
|
|
| 2377 | + where
|
|
| 2378 | + new_ty = mkTyVarTy new_tv
|
|
| 2379 | + given_pred = mkNomEqPred fam_app new_ty
|
|
| 2380 | + given_term = evCoercion $ mkNomReflCo new_ty -- See Detail (4) of Note
|
|
| 2381 | + |
|
| 2382 | + -- See Detail (7) of the Note
|
|
| 2383 | + cb_loc = updateCtLocOrigin (ctEvLoc ev) CycleBreakerOrigin
|
|
| 2346 | 2384 | |
| 2347 | 2385 | ----------------------
|
| 2348 | 2386 | finishCanWithIrred :: CtIrredReason -> CtEvidence
|
| ... | ... | @@ -2371,16 +2409,53 @@ inert set so that it can be used to rewrite other Wanteds. (There are many |
| 2371 | 2409 | reasons by unification might not happen: the LHS is not a touchable unification
|
| 2372 | 2410 | variable, it has rewriters, it's a Given etc.)
|
| 2373 | 2411 | |
| 2374 | -* In this case we call `checkTypeEq`to see if it is canonical (which in turn
|
|
| 2375 | - calls `checkTypeEqRhs`).
|
|
| 2412 | +* In this case we call `checkTypeEqNoUnification`to see if it is canonical (which
|
|
| 2413 | + in turn calls `checkTypeEqRhs` with suitable flags).
|
|
| 2376 | 2414 | |
| 2377 | -* Even if `checkTypeEq` returns `PuFail`, we may /still/ be able to add it to the inert
|
|
| 2378 | - set, depending on the reason for failure; examples are given in `do_not_prevent_rewriting`.
|
|
| 2415 | +* NB: we do /not/ try to take advantage of the case where
|
|
| 2416 | + `canEqCanLHSFinish_try_unification` has already called `checkTyEqRhs`; doing so
|
|
| 2417 | + caused #27844. (The first call did fam-app breaking, which concealed a genuine
|
|
| 2418 | + occurs check.) It's just too clever; better to do the simple thing.
|
|
| 2379 | 2419 | |
| 2380 | -* NB: we do /not/ try to take advantage of the case where `canEqCanLHSFinish_try_unification`
|
|
| 2381 | - has already called `checkTyEqRhs`; doing so caused #27844. (The first call did fam-app
|
|
| 2382 | - breaking, which concealed a genuine occurs check.) It's just too clever; better to do
|
|
| 2383 | - the simple thing.
|
|
| 2420 | +Note [Don't cycle-break Wanteds when not unifying]
|
|
| 2421 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 2422 | +Consdier
|
|
| 2423 | + [W] a[2] ~ Maybe (F a[2])
|
|
| 2424 | + |
|
| 2425 | +Should we cycle-break this Wanted, thus?
|
|
| 2426 | + |
|
| 2427 | + [W] a[2] ~ Maybe delta[2]
|
|
| 2428 | + [W] delta[2] ~ F a[2]
|
|
| 2429 | + |
|
| 2430 | +For a start, this is dodgy because we might just unify delta, thus undoing
|
|
| 2431 | +what we have done, and getting an infinite loop in the solver. Even if we
|
|
| 2432 | +somehow prevented ourselves from doing so, is there any merit in the split?
|
|
| 2433 | +Maybe: perhaps we can use that equality on `a` to unlock other constraints?
|
|
| 2434 | +Consider
|
|
| 2435 | + type instance F (Maybe _) = Bool
|
|
| 2436 | + |
|
| 2437 | + [G] g1: a ~ Maybe Bool
|
|
| 2438 | + [W] w1: a ~ Maybe (F a)
|
|
| 2439 | + |
|
| 2440 | +If we loop-break w1 to get
|
|
| 2441 | + [W] w1': a ~ Maybe gamma
|
|
| 2442 | + [W] w3: gamma ~ F a
|
|
| 2443 | +Now rewrite w3 with w1'
|
|
| 2444 | + [W] w3': gamma ~ F (Maybe gamma)
|
|
| 2445 | +Now use the type instance to get
|
|
| 2446 | + gamma := Bool
|
|
| 2447 | +Now we are left with
|
|
| 2448 | + [W] w1': a ~ Maybe Bool
|
|
| 2449 | +which we can solve from the Given.
|
|
| 2450 | + |
|
| 2451 | +BUT in this situation we could have rewritten the
|
|
| 2452 | +/original/ Wanted from the Given, like this:
|
|
| 2453 | + [W] w1': Maybe Bool ~ Maybe (F (Maybe Bool))
|
|
| 2454 | +and that is readily soluble.
|
|
| 2455 | + |
|
| 2456 | +In short: loop-breaking Wanteds, when we aren't unifying,
|
|
| 2457 | +seems of no merit. Hence TEFA_Recurse, rather than TEFA_Break,
|
|
| 2458 | +in `wanted_flags` in `checkTypeEqNoUnification`.
|
|
| 2384 | 2459 | |
| 2385 | 2460 | Note [Equalities with heterogeneous kinds]
|
| 2386 | 2461 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -2565,8 +2640,7 @@ The details depend on whether we're working with a Given or a Wanted. |
| 2565 | 2640 | Given
|
| 2566 | 2641 | -----
|
| 2567 | 2642 | We emit a new Given, [G] F a ~ cbv, equating the type family application
|
| 2568 | -to our new cbv. This is actually done by `break_given` in
|
|
| 2569 | -`GHC.Tc.Solver.Monad.checkTypeEq`.
|
|
| 2643 | +to our new cbv. This is actually done by `break_given` in `checkTypeEqNoUnification`.
|
|
| 2570 | 2644 | |
| 2571 | 2645 | Note its orientation: The type family ends up on the left; see
|
| 2572 | 2646 | Note [Orienting TyFamLHS/TyFamLHS]. No special treatment for
|
| ... | ... | @@ -983,7 +983,7 @@ How do we establish these conditions? |
| 983 | 983 | with S(fw,_).
|
| 984 | 984 | |
| 985 | 985 | * (T3) is guaranteed by an occurs-check on the work item.
|
| 986 | - This is done during canonicalisation, in checkTypeEq; invariant
|
|
| 986 | + This is done during canonicalisation, in checkTyEqRhs; invariant
|
|
| 987 | 987 | (TyEq:OC) of CEqCan. See also Note [EqCt occurs check] in GHC.Tc.Types.Constraint.
|
| 988 | 988 | |
| 989 | 989 | * (T4) is established by GHC.Tc.Solver.Monad.kickOutRewritable. If the inert
|
| ... | ... | @@ -117,10 +117,7 @@ module GHC.Tc.Solver.Monad ( |
| 117 | 117 | getDefaultInfo, getDynFlags, getGlobalRdrEnvTcS,
|
| 118 | 118 | matchFam, matchFamTcM,
|
| 119 | 119 | checkWellLevelledDFun,
|
| 120 | - pprEq,
|
|
| 121 | - |
|
| 122 | - -- Enforcing invariants for type equalities
|
|
| 123 | - checkTypeEq
|
|
| 120 | + pprEq
|
|
| 124 | 121 | ) where
|
| 125 | 122 | |
| 126 | 123 | import GHC.Prelude
|
| ... | ... | @@ -2302,57 +2299,6 @@ wrapUnifier rws loc role do_unifications |
| 2302 | 2299 | ************************************************************************
|
| 2303 | 2300 | -}
|
| 2304 | 2301 | |
| 2305 | -checkTypeEq :: CtEvidence -> EqRel -> CanEqLHS -> TcType
|
|
| 2306 | - -> TcS (PuResult Ct Reduction)
|
|
| 2307 | --- Used for general CanEqLHSs, ones that do
|
|
| 2308 | --- not have a touchable type variable on the LHS (i.e. not unifying)
|
|
| 2309 | -checkTypeEq ev eq_rel lhs rhs =
|
|
| 2310 | - case ev of
|
|
| 2311 | - CtGiven {} ->
|
|
| 2312 | - do { traceTcS "checkTypeEq (given) {" (vcat [ text "lhs:" <+> ppr lhs
|
|
| 2313 | - , text "rhs:" <+> ppr rhs ])
|
|
| 2314 | - ; check_result <- wrapTcS (checkTyEqRhs given_flags rhs)
|
|
| 2315 | - ; traceTcS "checkTypeEq }" (ppr check_result)
|
|
| 2316 | - ; case check_result of
|
|
| 2317 | - PuFail reason -> return (PuFail reason)
|
|
| 2318 | - PuOK prs redn -> do { new_givens <- mapBagM mk_new_given prs
|
|
| 2319 | - ; emitWork new_givens
|
|
| 2320 | - ; updInertSet (addCycleBreakerBindings prs)
|
|
| 2321 | - ; return (pure redn) } }
|
|
| 2322 | - CtWanted {} -> do { traceTcS "checkTypeEq (wanted) {" $
|
|
| 2323 | - vcat [ text "lhs:" <+> ppr lhs
|
|
| 2324 | - , text "rhs:" <+> ppr rhs ]
|
|
| 2325 | - ; check_result <- wrapTcS (checkTyEqRhs wanted_flags rhs)
|
|
| 2326 | - ; traceTcS "checkTypeEq }" (ppr check_result)
|
|
| 2327 | - ; return check_result }
|
|
| 2328 | - where
|
|
| 2329 | - wanted_flags :: TyEqFlags TcM Ct
|
|
| 2330 | - wanted_flags = notUnifying_TEFTask occ_prob lhs
|
|
| 2331 | - -- checkTypeEq deals only with the non-unifying case
|
|
| 2332 | - |
|
| 2333 | - given_flags :: TyEqFlags TcM (TcTyVar, TcType)
|
|
| 2334 | - given_flags = wanted_flags { tef_fam_app = mkTEFA_Break ev eq_rel BreakGiven }
|
|
| 2335 | - -- TEFA_Break used for: [G] a ~ Maybe (F a)
|
|
| 2336 | - -- or [G] F a ~ Maybe (F a)
|
|
| 2337 | - |
|
| 2338 | - -- occ_prob: see Note [Occurs check and representational equality]
|
|
| 2339 | - occ_prob = case eq_rel of
|
|
| 2340 | - NomEq -> cteInsolubleOccurs
|
|
| 2341 | - ReprEq -> cteSolubleOccurs
|
|
| 2342 | - |
|
| 2343 | - ---------------------------
|
|
| 2344 | - mk_new_given :: (TcTyVar, TcType) -> TcS Ct
|
|
| 2345 | - mk_new_given (new_tv, fam_app)
|
|
| 2346 | - = mkNonCanonical . CtGiven <$> newGivenEv cb_loc (given_pred, given_term)
|
|
| 2347 | - where
|
|
| 2348 | - new_ty = mkTyVarTy new_tv
|
|
| 2349 | - given_pred = mkNomEqPred fam_app new_ty
|
|
| 2350 | - given_term = evCoercion $ mkNomReflCo new_ty -- See Detail (4) of Note
|
|
| 2351 | - |
|
| 2352 | - -- See Detail (7) of the Note
|
|
| 2353 | - cb_loc = updateCtLocOrigin (ctEvLoc ev) CycleBreakerOrigin
|
|
| 2354 | - |
|
| 2355 | --------------------------
|
|
| 2356 | 2302 | -- | Fill in CycleBreakerTvs with the variables they stand for.
|
| 2357 | 2303 | -- See Note [Type equality cycles] in GHC.Tc.Solver.Equality
|
| 2358 | 2304 | restoreTyVarCycles :: InertSet -> TcM ()
|
| ... | ... | @@ -2368,43 +2314,4 @@ restoreTyVarCycles is |
| 2368 | 2314 | (a ~R# b a) is soluble if b later turns out to be Identity
|
| 2369 | 2315 | So we treat this as a "soluble occurs check".
|
| 2370 | 2316 | |
| 2371 | -Note [Don't cycle-break Wanteds when not unifying]
|
|
| 2372 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 2373 | -Consdier
|
|
| 2374 | - [W] a[2] ~ Maybe (F a[2])
|
|
| 2375 | - |
|
| 2376 | -Should we cycle-break this Wanted, thus?
|
|
| 2377 | - |
|
| 2378 | - [W] a[2] ~ Maybe delta[2]
|
|
| 2379 | - [W] delta[2] ~ F a[2]
|
|
| 2380 | - |
|
| 2381 | -For a start, this is dodgy because we might just unify delta, thus undoing
|
|
| 2382 | -what we have done, and getting an infinite loop in the solver. Even if we
|
|
| 2383 | -somehow prevented ourselves from doing so, is there any merit in the split?
|
|
| 2384 | -Maybe: perhaps we can use that equality on `a` to unlock other constraints?
|
|
| 2385 | -Consider
|
|
| 2386 | - type instance F (Maybe _) = Bool
|
|
| 2387 | - |
|
| 2388 | - [G] g1: a ~ Maybe Bool
|
|
| 2389 | - [W] w1: a ~ Maybe (F a)
|
|
| 2390 | - |
|
| 2391 | -If we loop-break w1 to get
|
|
| 2392 | - [W] w1': a ~ Maybe gamma
|
|
| 2393 | - [W] w3: gamma ~ F a
|
|
| 2394 | -Now rewrite w3 with w1'
|
|
| 2395 | - [W] w3': gamma ~ F (Maybe gamma)
|
|
| 2396 | -Now use the type instance to get
|
|
| 2397 | - gamma := Bool
|
|
| 2398 | -Now we are left with
|
|
| 2399 | - [W] w1': a ~ Maybe Bool
|
|
| 2400 | -which we can solve from the Given.
|
|
| 2401 | - |
|
| 2402 | -BUT in this situation we could have rewritten the
|
|
| 2403 | -/original/ Wanted from the Given, like this:
|
|
| 2404 | - [W] w1': Maybe Bool ~ Maybe (F (Maybe Bool))
|
|
| 2405 | -and that is readily soluble.
|
|
| 2406 | - |
|
| 2407 | -In short: loop-breaking Wanteds, when we aren't unifying,
|
|
| 2408 | -seems of no merit. Hence TEFA_Recurse, rather than TEFA_Break,
|
|
| 2409 | -in `wanted_flags` in `checkTypeEq`.
|
|
| 2410 | 2317 | -} |
| ... | ... | @@ -524,7 +524,7 @@ isInsolubleReason (InsolubleFunDepReason {}) = True |
| 524 | 524 | ------------------------------------------------------------------------------
|
| 525 | 525 | |
| 526 | 526 | -- | A /set/ of problems in checking the validity of a type equality.
|
| 527 | --- See 'checkTypeEq'.
|
|
| 527 | +-- See 'GHC.Tc.Utils.Unify.checkTyEqRhs'.
|
|
| 528 | 528 | newtype CheckTyEqResult = CTER Word8
|
| 529 | 529 | |
| 530 | 530 | -- | No problems in checking the validity of a type equality.
|
| ... | ... | @@ -3617,7 +3617,7 @@ instance Outputable SimpleUnifyResult where |
| 3617 | 3617 | simpleUnifyCheck :: UnifyCheckCaller -> TcLevel -> TcTyVar -> TcType -> SimpleUnifyResult
|
| 3618 | 3618 | -- ^ A fast check for unification. May return "not sure", in which case
|
| 3619 | 3619 | -- unification might still be OK, but it'll take more work to do
|
| 3620 | --- (use the full 'checkTypeEq').
|
|
| 3620 | +-- (use the full 'checkTyEqRhs').
|
|
| 3621 | 3621 | --
|
| 3622 | 3622 | -- It returns SUC_CannotUnify for
|
| 3623 | 3623 | -- * Touchability failure
|
| ... | ... | @@ -4289,7 +4289,7 @@ NB: We never see a TyVarLHS here, such as |
| 4289 | 4289 | [G] a ~ F tys here
|
| 4290 | 4290 | because we'd have swapped it to
|
| 4291 | 4291 | [G] F tys ~ a
|
| 4292 | -in canEqCanLHS2, before getting to checkTypeEq.
|
|
| 4292 | +in canEqCanLHS2, before getting to checkTyEqRhs.
|
|
| 4293 | 4293 | -}
|
| 4294 | 4294 | |
| 4295 | 4295 | check_ty_eq_rhs :: forall m a
|
| ... | ... | @@ -4813,7 +4813,6 @@ promote_meta_tyvar info dest_lvl occ_tv |
| 4813 | 4813 | touchabilityTest :: TcLevel -> TcTyVar -> Bool
|
| 4814 | 4814 | -- ^ This is the key test for untouchability:
|
| 4815 | 4815 | -- See Note [Unification preconditions] in GHC.Tc.Utils.Unify
|
| 4816 | 4816 | --
|
| 4817 | 4817 | -- @True@ <=> the variable is touchable
|
| 4818 | 4818 | touchabilityTest given_eq_lvl tv
|