Simon Peyton Jones pushed to branch wip/T26543b at Glasgow Haskell Compiler / GHC
Commits:
-
5e6c1f43
by Simon Peyton Jones at 2026-10-01T13:07:42+01:00
7 changed files:
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- testsuite/tests/typecheck/should_compile/LocalGivenEqs.hs
Changes:
| ... | ... | @@ -2584,15 +2584,15 @@ turn controls the behaviour of the workhorse: GHC.Tc.Utils.Unify.checkTyEqRhs. |
| 2584 | 2584 | |
| 2585 | 2585 | The details depend on whether we're working with a Given or a Wanted.
|
| 2586 | 2586 | |
| 2587 | -Given
|
|
| 2588 | ------
|
|
| 2587 | +Note [Type equality cycles: Givens]
|
|
| 2588 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 2589 | 2589 | We emit a new Given, [G] F a ~ cbv, equating the type family application
|
| 2590 | 2590 | to our new cbv. This is actually done by `break_given` in
|
| 2591 | 2591 | `GHC.Tc.Solver.Monad.checkTypeEq`.
|
| 2592 | 2592 | |
| 2593 | -Note its orientation: The type family ends up on the left; see
|
|
| 2594 | -Note [Orienting TyFamLHS/TyFamLHS]. No special treatment for
|
|
| 2595 | -CycleBreakerTvs is necessary. This scenario is now easily soluble, by using
|
|
| 2593 | +Note its orientation: The type family ends up on the left;
|
|
| 2594 | +see Note [Orienting TyFamLHS/TyFamLHS]. No special treatment for
|
|
| 2595 | +GivenCycleBreakerTvs is necessary. This scenario is now easily soluble, by using
|
|
| 2596 | 2596 | the first Given to rewrite the Wanted, which can now be solved.
|
| 2597 | 2597 | |
| 2598 | 2598 | (The first Given actually also rewrites the second one, giving
|
| ... | ... | @@ -2613,10 +2613,11 @@ to |
| 2613 | 2613 | |
| 2614 | 2614 | Note that
|
| 2615 | 2615 | * `cbv` is a fresh cycle breaker variable.
|
| 2616 | -* `cbv` is a meta-tyvar, but it is completely untouchable.
|
|
| 2616 | +* `cbv` is a meta-tyvar, of flavour GivenCycleBreakerTv, but it is
|
|
| 2617 | + completely untouchable.
|
|
| 2617 | 2618 | * We track the cycle-breaker variables in inert_cycle_breakers in InertSet
|
| 2618 | -* We eventually fill in the cycle-breakers, with `cbv := F lhs`.
|
|
| 2619 | - No one else fills in CycleBreakerTvs!
|
|
| 2619 | +* We eventually fill in the cycle-breakers, with `cbv := F lhs`,
|
|
| 2620 | + via `restoreTyVarCycles`. No one else fills in GivenCycleBreakerTvs!
|
|
| 2620 | 2621 | * The evidence for the new `F lhs ~ cbv` constraint is Refl, because we know
|
| 2621 | 2622 | this fill-in is ultimately going to happen.
|
| 2622 | 2623 | * In `inert_cycle_breakers`, we remember the (cbv, F lhs) pair; that is, we
|
| ... | ... | @@ -2626,8 +2627,8 @@ Note that |
| 2626 | 2627 | * This fill-in is done when solving is complete, by restoreTyVarCycles
|
| 2627 | 2628 | in nestImplicTcS and runTcSWithEvBinds.
|
| 2628 | 2629 | |
| 2629 | -Wanted
|
|
| 2630 | -------
|
|
| 2630 | +Note [Type equality cycles: Wanteds]
|
|
| 2631 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 2631 | 2632 | First, we do not cycle-break unless the LHS is a unifiable type variable
|
| 2632 | 2633 | See Note [Don't cycle-break Wanteds when not unifying] in GHC.Tc.Solver.Monad.
|
| 2633 | 2634 | |
| ... | ... | @@ -2686,9 +2687,9 @@ to unify the cbvs: |
| 2686 | 2687 | [W] AllEqF '[Bool] alpha
|
| 2687 | 2688 | |
| 2688 | 2689 | Without the logic detailed in this Note, we're stuck here, as AllEqF cannot
|
| 2689 | -reduce and alpha cannot unify. Let's instead apply our cycle-breaker approach,
|
|
| 2690 | -just as described above. We thus invent cbv1 and cbv2 and unify
|
|
| 2691 | -alpha := cbv1 -> cbv2, yielding (after zonking)
|
|
| 2690 | +reduce and alpha cannot unify (occurs check). Let's instead apply our
|
|
| 2691 | +cycle-breaker approach, just as described above. We thus invent cbv1 and cbv2
|
|
| 2692 | +and unify alpha := (cbv1 : cbv2), yielding (after zonking)
|
|
| 2692 | 2693 | |
| 2693 | 2694 | [W] Head (cbv1 : cbv2) ~ cbv1
|
| 2694 | 2695 | [W] Tail (cbv1 : cbv2) ~ cbv2
|
| ... | ... | @@ -2726,8 +2727,8 @@ Note that we need to unify the cbvs here; if we did not, there would be |
| 2726 | 2727 | no way to solve those constraints. That's why the cycle-breakers are
|
| 2727 | 2728 | ordinary TauTvs.
|
| 2728 | 2729 | |
| 2729 | -How all this is implemented
|
|
| 2730 | ----------------------------
|
|
| 2730 | +Note [Type equality cycles: implementation]
|
|
| 2731 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 2731 | 2732 | We implement all this via the `TEFA_Break` constructor of `TyEqFamApp`,
|
| 2732 | 2733 | itself stored in the `tef_fam_app` field of `TyEqFlags`, which controls
|
| 2733 | 2734 | the behaviour of `GHC.Tc.Utils.Unify.checkTyEqRhs`. The `TEFA_Break`
|
| ... | ... | @@ -2854,7 +2855,7 @@ More details: |
| 2854 | 2855 | CycleBreakerOrigin. This works for both Givens and Wanteds, as we need the
|
| 2855 | 2856 | logic in the W case for e.g. typecheck/should_fail/T17139. Because this
|
| 2856 | 2857 | logic needs to work for Wanteds, too, we cannot simply look for a
|
| 2857 | - CycleBreakerTv on the left: Wanteds don't use them.
|
|
| 2858 | + GivenCycleBreakerTv on the left: Wanteds don't use them.
|
|
| 2858 | 2859 | |
| 2859 | 2860 | |
| 2860 | 2861 | **********************************************************************
|
| ... | ... | @@ -304,7 +304,7 @@ instance Outputable WorkList where |
| 304 | 304 | ********************************************************************* -}
|
| 305 | 305 | |
| 306 | 306 | type CycleBreakerVarStack = NE.NonEmpty (Bag (TcTyVar, TcType))
|
| 307 | - -- ^ a stack of (CycleBreakerTv, original family applications) lists
|
|
| 307 | + -- ^ A stack of (GivenCycleBreakerTv, original family applications) lists
|
|
| 308 | 308 | -- first element in the stack corresponds to current implication;
|
| 309 | 309 | -- later elements correspond to outer implications
|
| 310 | 310 | -- used to undo the cycle-breaking needed to handle
|
| ... | ... | @@ -324,6 +324,8 @@ data InertSet |
| 324 | 324 | -- See `resetInertCans`
|
| 325 | 325 | |
| 326 | 326 | , inert_cycle_breakers :: CycleBreakerVarStack
|
| 327 | + -- The equalities for /given/ cycle breakers, GivenCycleBreakerTvs
|
|
| 328 | + -- See Note [
|
|
| 327 | 329 | |
| 328 | 330 | , inert_famapp_cache :: FunEqMap Reduction
|
| 329 | 331 | -- Just a hash-cons cache for use when reducing family applications
|
| ... | ... | @@ -1942,7 +1944,8 @@ prohibitedSuperClassSolve given_loc wanted_loc |
| 1942 | 1944 | |
| 1943 | 1945 | {- *********************************************************************
|
| 1944 | 1946 | * *
|
| 1945 | - Cycle breakers
|
|
| 1947 | + Given Cycle breakers
|
|
| 1948 | + See Note [Type equality cycles: Givens] in GHC.Tc.Solver.Equality
|
|
| 1946 | 1949 | * *
|
| 1947 | 1950 | ********************************************************************* -}
|
| 1948 | 1951 |
| ... | ... | @@ -2344,12 +2344,12 @@ checkTypeEq ev eq_rel lhs rhs = |
| 2344 | 2344 | given_pred = mkNomEqPred fam_app new_ty
|
| 2345 | 2345 | given_term = evCoercion $ mkNomReflCo new_ty -- See Detail (4) of Note
|
| 2346 | 2346 | |
| 2347 | - -- See Detail (7) of the Note
|
|
| 2347 | + -- See Detail (7) of Note [Type equality cycles: implementation]
|
|
| 2348 | 2348 | cb_loc = updateCtLocOrigin (ctEvLoc ev) CycleBreakerOrigin
|
| 2349 | 2349 | |
| 2350 | 2350 | -------------------------
|
| 2351 | 2351 | -- | Fill in CycleBreakerTvs with the variables they stand for.
|
| 2352 | --- See Note [Type equality cycles] in GHC.Tc.Solver.Equality
|
|
| 2352 | +-- See Note [Type equality cycles: Givens] in GHC.Tc.Solver.Equality
|
|
| 2353 | 2353 | restoreTyVarCycles :: InertSet -> TcM ()
|
| 2354 | 2354 | restoreTyVarCycles is
|
| 2355 | 2355 | = TcM.liftZonkM
|
| ... | ... | @@ -726,11 +726,11 @@ cloneMetaTyVarName name |
| 726 | 726 | metaInfoToTyVarName :: MetaInfo -> FastString
|
| 727 | 727 | metaInfoToTyVarName meta_info =
|
| 728 | 728 | case meta_info of
|
| 729 | - TauTv -> fsLit "t"
|
|
| 730 | - TyVarTv -> fsLit "a"
|
|
| 731 | - RuntimeUnkTv -> fsLit "r"
|
|
| 732 | - CycleBreakerTv -> fsLit "b"
|
|
| 733 | - ConcreteTv {} -> fsLit "c"
|
|
| 729 | + TauTv -> fsLit "t"
|
|
| 730 | + TyVarTv -> fsLit "a"
|
|
| 731 | + RuntimeUnkTv -> fsLit "r"
|
|
| 732 | + GivenCycleBreakerTv -> fsLit "b"
|
|
| 733 | + ConcreteTv {} -> fsLit "c"
|
|
| 734 | 734 | |
| 735 | 735 | newAnonMetaTyVar :: MetaInfo -> Kind -> TcM TcTyVar
|
| 736 | 736 | newAnonMetaTyVar mi = newNamedAnonMetaTyVar (metaInfoToTyVarName mi) mi
|
| ... | ... | @@ -824,7 +824,7 @@ cloneAnonMetaTyVar info tv kind |
| 824 | 824 | -- in GHC.Tc.Solver.Equality.
|
| 825 | 825 | newCycleBreakerTyVar :: TcKind -> TcM TcTyVar
|
| 826 | 826 | newCycleBreakerTyVar kind
|
| 827 | - = do { details <- newMetaDetails CycleBreakerTv
|
|
| 827 | + = do { details <- newMetaDetails GivenCycleBreakerTv
|
|
| 828 | 828 | ; name <- newMetaTyVarName (fsLit "cbv")
|
| 829 | 829 | ; return (mkTcTyVar name kind details) }
|
| 830 | 830 |
| ... | ... | @@ -688,9 +688,10 @@ data MetaInfo |
| 688 | 688 | | RuntimeUnkTv -- ^ A unification variable used in the GHCi debugger.
|
| 689 | 689 | -- It /is/ allowed to unify with a polytype, unlike TauTv
|
| 690 | 690 | |
| 691 | - | CycleBreakerTv -- ^ Used to fix occurs-check problems in Givens
|
|
| 692 | - -- See Note [Type equality cycles] in
|
|
| 693 | - -- GHC.Tc.Solver.Equality
|
|
| 691 | + | GivenCycleBreakerTv -- ^ Used to fix occurs-check problems in Givens
|
|
| 692 | + -- Never used for Wanteds
|
|
| 693 | + -- See Note [Type equality cycles] in
|
|
| 694 | + -- GHC.Tc.Solver.Equality
|
|
| 694 | 695 | |
| 695 | 696 | | ConcreteTv ConcreteTvOrigin
|
| 696 | 697 | -- ^ A unification variable that can only be unified
|
| ... | ... | @@ -705,11 +706,11 @@ instance Outputable MetaDetails where |
| 705 | 706 | ppr (Indirect ty) = text "Indirect" <+> ppr ty
|
| 706 | 707 | |
| 707 | 708 | instance Outputable MetaInfo where
|
| 708 | - ppr TauTv = text "tau"
|
|
| 709 | - ppr TyVarTv = text "tyv"
|
|
| 710 | - ppr RuntimeUnkTv = text "rutv"
|
|
| 711 | - ppr CycleBreakerTv = text "cbv"
|
|
| 712 | - ppr (ConcreteTv {}) = text "conc"
|
|
| 709 | + ppr TauTv = text "tau"
|
|
| 710 | + ppr TyVarTv = text "tyv"
|
|
| 711 | + ppr RuntimeUnkTv = text "rutv"
|
|
| 712 | + ppr GivenCycleBreakerTv = text "cbv"
|
|
| 713 | + ppr (ConcreteTv {}) = text "conc"
|
|
| 713 | 714 | |
| 714 | 715 | -- | What caused us to create a 'ConcreteTv' metavariable?
|
| 715 | 716 | -- See Note [ConcreteTv] in GHC.Tc.Utils.Concrete.
|
| ... | ... | @@ -1299,7 +1300,7 @@ isRuntimeUnkTyVar tv |
| 1299 | 1300 | |
| 1300 | 1301 | isCycleBreakerTyVar tv
|
| 1301 | 1302 | | isTyVar tv -- See Note [Coercion variables in free variable lists]
|
| 1302 | - , MetaTv { mtv_info = CycleBreakerTv } <- tcTyVarDetails tv
|
|
| 1303 | + , MetaTv { mtv_info = GivenCycleBreakerTv } <- tcTyVarDetails tv
|
|
| 1303 | 1304 | = True
|
| 1304 | 1305 | |
| 1305 | 1306 | | otherwise
|
| ... | ... | @@ -1350,8 +1351,8 @@ metaTyVarInfo tv |
| 1350 | 1351 | |
| 1351 | 1352 | isTouchableInfo :: MetaInfo -> Bool
|
| 1352 | 1353 | isTouchableInfo info
|
| 1353 | - | CycleBreakerTv <- info = False
|
|
| 1354 | - | otherwise = True
|
|
| 1354 | + | GivenCycleBreakerTv <- info = False
|
|
| 1355 | + | otherwise = True
|
|
| 1355 | 1356 | |
| 1356 | 1357 | metaTyVarTcLevel :: TcTyVar -> TcLevel
|
| 1357 | 1358 | metaTyVarTcLevel tv
|
| ... | ... | @@ -3235,11 +3235,11 @@ lhsPriority tv |
| 3235 | 3235 | -> 5 -- Eliminate instantiation variables first
|
| 3236 | 3236 | | otherwise
|
| 3237 | 3237 | -> case info of
|
| 3238 | - CycleBreakerTv -> 0
|
|
| 3239 | - TyVarTv -> 1
|
|
| 3240 | - ConcreteTv {} -> 2
|
|
| 3241 | - TauTv -> 3
|
|
| 3242 | - RuntimeUnkTv -> 4
|
|
| 3238 | + GivenCycleBreakerTv -> 0
|
|
| 3239 | + TyVarTv -> 1
|
|
| 3240 | + ConcreteTv {} -> 2
|
|
| 3241 | + TauTv -> 3
|
|
| 3242 | + RuntimeUnkTv -> 4
|
|
| 3243 | 3243 | |
| 3244 | 3244 | {- Note [Unification preconditions]
|
| 3245 | 3245 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -3285,7 +3285,7 @@ There are five reasons not to unify: |
| 3285 | 3285 | structured type. So if 'ty' is a structured type, such as (Maybe x),
|
| 3286 | 3286 | don't unify.
|
| 3287 | 3287 | |
| 3288 | - * CycleBreakerTv: never unified, except by restoreTyVarCycles.
|
|
| 3288 | + * GivenCycleBreakerTv: never unified, except by restoreGivenCycles.
|
|
| 3289 | 3289 | |
| 3290 | 3290 | 4. (CONCRETE) A ConcreteTv can only unify with a concrete type,
|
| 3291 | 3291 | by definition.
|
| ... | ... | @@ -3390,7 +3390,7 @@ So we look for a positive reason to swap, using a three-step test: |
| 3390 | 3390 | touchable and can be unified.
|
| 3391 | 3391 | |
| 3392 | 3392 | Tie-breaking rules for MetaTvs:
|
| 3393 | - - CycleBreakerTv: This is essentially a stand-in for another type;
|
|
| 3393 | + - GivenCycleBreakerTv: This is essentially a stand-in for another type;
|
|
| 3394 | 3394 | it's untouchable and should have the same priority as a skolem: 0.
|
| 3395 | 3395 | |
| 3396 | 3396 | - TyVarTv: These can unify only with another tyvar, but we can't unify
|
| ... | ... | @@ -4112,13 +4112,14 @@ wantConcreteCheck = \case |
| 4112 | 4112 | -- where @cbv@ is a fresh loop-breaker tyvar (for Given), or
|
| 4113 | 4113 | -- just a fresh 'TauTv' (for Wanted)
|
| 4114 | 4114 | famAppBreaker :: FamAppBreaker a -> TcType -> TcM (PuResult a Reduction)
|
| 4115 | -famAppBreaker BreakGiven fam_app
|
|
| 4115 | +famAppBreaker BreakGiven fam_app -- Givens
|
|
| 4116 | 4116 | = do { new_tv <- TcM.newCycleBreakerTyVar (typeKind fam_app)
|
| 4117 | 4117 | ; return (PuOK (unitBag (new_tv, fam_app))
|
| 4118 | 4118 | (mkReflRedn Nominal (mkTyVarTy new_tv))) }
|
| 4119 | 4119 | -- Why reflexive? See Detail (4) of Note [Type equality cycles]
|
| 4120 | 4120 | -- in GHC.Tc.Solver.Equality
|
| 4121 | -famAppBreaker (BreakWanted ev lhs_tv) fam_app
|
|
| 4121 | + |
|
| 4122 | +famAppBreaker (BreakWanted ev lhs_tv) fam_app -- Wanteds
|
|
| 4122 | 4123 | -- Occurs check or skolem escape; so flatten
|
| 4123 | 4124 | = do { reason <- checkPromoteFreeVars cteInsolubleOccurs
|
| 4124 | 4125 | (tyVarName lhs_tv) lhs_tv_lvl
|
| ... | ... | @@ -4861,7 +4862,7 @@ checkTopShape info xi |
| 4861 | 4862 | RuntimeUnk -> True
|
| 4862 | 4863 | MetaTv { mtv_info = TyVarTv } -> True
|
| 4863 | 4864 | _ -> False
|
| 4864 | - CycleBreakerTv -> False -- We never unify these
|
|
| 4865 | + GivenCycleBreakerTv -> False -- We never unify these
|
|
| 4865 | 4866 | _ -> True
|
| 4866 | 4867 | |
| 4867 | 4868 | --------------------------------------------------------------------------------
|
| ... | ... | @@ -5174,14 +5175,14 @@ mightEqualLater inert_set given_pred given_loc wanted_pred wanted_loc |
| 5174 | 5175 | |
| 5175 | 5176 | -- True for TauTv and TyVarTv (and RuntimeUnkTv) meta-tyvars
|
| 5176 | 5177 | -- (as they can be unified)
|
| 5177 | - -- and also for CycleBreakerTvs that mentions meta-tyvars
|
|
| 5178 | + -- and also for GivenCycleBreakerTvs that mentions meta-tyvars
|
|
| 5178 | 5179 | mentions_meta_ty_var :: TyVar -> Bool
|
| 5179 | 5180 | mentions_meta_ty_var tv
|
| 5180 | 5181 | | isMetaTyVar tv
|
| 5181 | 5182 | = case metaTyVarInfo tv of
|
| 5182 | 5183 | -- See Examples 8 and 9 in the Note
|
| 5183 | - CycleBreakerTv -> anyFreeVarsOfType mentions_meta_ty_var
|
|
| 5184 | - (lookupCycleBreakerVar tv inert_set)
|
|
| 5184 | + GivenCycleBreakerTv -> anyFreeVarsOfType mentions_meta_ty_var
|
|
| 5185 | + (lookupCycleBreakerVar tv inert_set)
|
|
| 5185 | 5186 | _ -> True
|
| 5186 | 5187 | | otherwise
|
| 5187 | 5188 | = False
|
| ... | ... | @@ -5224,7 +5225,7 @@ We want to solve w1 using g1 and g2. The presence of g3 is irrelevant, because |
| 5224 | 5225 | we cannot unify 'f[tau:1] v[tau:1]' and 'g[sk:1] x[sk:3]' due to skolem escape.
|
| 5225 | 5226 | -}
|
| 5226 | 5227 | |
| 5227 | --- | Return the type family application a CycleBreakerTv maps to.
|
|
| 5228 | +-- | Return the type family application a GivenCycleBreakerTv maps to.
|
|
| 5228 | 5229 | lookupCycleBreakerVar :: TcTyVar -- ^ cbv, must be a CycleBreakerTv
|
| 5229 | 5230 | -> InertSet
|
| 5230 | 5231 | -> TcType -- ^ type family application the cbv maps to
|
| ... | ... | @@ -22,7 +22,7 @@ it mentions b in its RHS. It thus triggers Note [Type equality cycles] |
| 22 | 22 | in GHC.Tc.Solver.Equality. That Note says we change the situation to
|
| 23 | 23 | [G] b ~ cbv GhcPs
|
| 24 | 24 | [G] Body b ~ cbv
|
| 25 | -for some fresh CycleBreakerTv cbv. Now, our original equality looks to be let-like,
|
|
| 25 | +for some fresh GivenCycleBreakerTv cbv. Now, our original equality looks to be let-like,
|
|
| 26 | 26 | but the new cbv equality is *not* let-like -- note that the variable is on the RHS.
|
| 27 | 27 | The solution is to consider any equality whose free variables are all at the current
|
| 28 | 28 | level to not stop equalities from floating. These are called *local*. Because both
|