Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
-
e0a84ca0
by Simon Peyton Jones at 2025-10-27T16:36:30+00:00
7 changed files:
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Utils/EndoOS.hs
Changes:
| ... | ... | @@ -128,7 +128,7 @@ Note [Instantiation variables are short lived] |
| 128 | 128 | |
| 129 | 129 | TL;DR: instantiation variables are short-lived. So it is fine for them
|
| 130 | 130 | to have an infinite level (=QLInstVar) because they are monomorphised
|
| 131 | - before do anything like skolem-escape checks.
|
|
| 131 | + before we do anything like skolem-escape checks.
|
|
| 132 | 132 | |
| 133 | 133 | * The constraint solver never sees an instantiation variable
|
| 134 | 134 | [not quite true; see below]
|
| ... | ... | @@ -648,16 +648,22 @@ There are lots of wrinkles of course: |
| 648 | 648 | because we want to /gather/ the equality constraint (to put in the implication)
|
| 649 | 649 | rather than /emit/ them into the monad, as `wrapUnifierAndEmit` does.
|
| 650 | 650 | |
| 651 | -(SF6) We solve the nested constraints right away. In the past we instead generated
|
|
| 652 | - an `Implication` to be solved later, but we no longer have a convenient place
|
|
| 653 | - to accumulate such an implication for later solving. Instead we just try to solve
|
|
| 654 | - them on the spot, and abandon the attempt if we fail.
|
|
| 655 | - |
|
| 656 | - In the latter case we are left with an unsolved (forall a. blah) ~ (forall b. blah),
|
|
| 657 | - and it may not be clear /why/ we couldn't solve it. But on balance the error
|
|
| 658 | - messages improve: it is easier to understand that
|
|
| 659 | - (forall a. a->a) ~ (forall b. b->Int)
|
|
| 660 | - is insoluble than it is to understand a message about matching `a` with `Int`.
|
|
| 651 | +(SF6) We solve the nested constraints right away. In a type-correct program,
|
|
| 652 | + this attempt will usually succeed. But if we don't completely solve it, we
|
|
| 653 | + abandon the attempt and keep the origin forall-equality.
|
|
| 654 | + |
|
| 655 | + In the abandon-the-attempt case, we are left with an unsolved
|
|
| 656 | + (forall a. blah) ~ (forall b. blah)
|
|
| 657 | + |
|
| 658 | + and it may not be immediately apparent /why/ we couldn't solve it. But actually
|
|
| 659 | + such errors messages can be /better/. For example, it is easier to understand
|
|
| 660 | + that (forall a. a->a) ~ (forall b. b->Int) is insoluble than it is to understand a
|
|
| 661 | + message about matching `a` with `Int`, because `a` is a skolem.
|
|
| 662 | + |
|
| 663 | + Historical note: In the past we instead generated an `Implication`, storing it in
|
|
| 664 | + a dedicated field `wl_implics` in the work-list to be solved later. But that
|
|
| 665 | + plumbing was tiresome, and now we just try to solve them on the spot, and abandon
|
|
| 666 | + the attempt if we fail.
|
|
| 661 | 667 | -}
|
| 662 | 668 | |
| 663 | 669 | {- Note [Unwrap newtypes first]
|
| ... | ... | @@ -2942,15 +2948,14 @@ lookup_eq_in_qcis :: CtEvidence -> EqRel -> TcType -> TcType -> SolverStage () |
| 2942 | 2948 | -- Why? See Note [Looking up primitive equalities in quantified constraints]
|
| 2943 | 2949 | -- See also GHC.Tc.Solver.Dict Note [Equality superclasses in quantified constraints]
|
| 2944 | 2950 | lookup_eq_in_qcis (CtGiven {}) _ _ _
|
| 2945 | - = nopStage ()
|
|
| 2951 | + = nopStage () -- Never look up Givens in quantified constraints
|
|
| 2946 | 2952 | |
| 2947 | 2953 | lookup_eq_in_qcis ev@(CtWanted (WantedCt { ctev_dest = dest, ctev_loc = loc })) eq_rel lhs rhs
|
| 2948 | 2954 | = do { ev_binds_var <- simpleStage getTcEvBindsVar
|
| 2949 | 2955 | ; ics <- simpleStage getInertCans
|
| 2950 | - ; if null (inert_qcis ics)
|
|
| 2956 | + ; if null (inert_qcis ics) -- Shortcut common case
|
|
| 2951 | 2957 | || isCoEvBindsVar ev_binds_var -- See Note [Instances in no-evidence implications]
|
| 2952 | - then -- Shortcut common case
|
|
| 2953 | - nopStage ()
|
|
| 2958 | + then nopStage ()
|
|
| 2954 | 2959 | else -- Try looking for both (lhs~rhs) anr (rhs~lhs); see #23333
|
| 2955 | 2960 | do { try NotSwapped; try IsSwapped } }
|
| 2956 | 2961 | where
|
| ... | ... | @@ -414,18 +414,18 @@ updInertIrreds irred |
| 414 | 414 | |
| 415 | 415 | {- Note [Kick out after filling a coercion hole]
|
| 416 | 416 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 417 | -If we we solve `kco` and have `co` in the inert set whose rewriter-set includes `kco`,
|
|
| 417 | +If we solve `kco` and have `co` in the inert set whose rewriter-set includes `kco`,
|
|
| 418 | 418 | we should kick out `co` so that we can now unify it, which might unlock other stuff.
|
| 419 | 419 | See Note [Unify only if the rewriter set is empty] in GHC.Tc.Solver.Equality for
|
| 420 | 420 | why solving `kco` might unlock `co`, especially (URW2).
|
| 421 | 421 | |
| 422 | 422 | Hence `kickOutAfterFillingCoercionHole`. It looks at inert constraints that are
|
| 423 | 423 | * Wanted
|
| 424 | - * Of form alpha ~ rhs, where alpha is a unification variable
|
|
| 424 | + * Of the form alpha ~ rhs, where alpha is a unification variable
|
|
| 425 | 425 | and kicks out any that will have an empty rewriter set after filling the hole.
|
| 426 | 426 | |
| 427 | 427 | Wrinkles:
|
| 428 | -(KOC1) If co's rewriter-set is {kco, xco}, there is on point in kicking it out,
|
|
| 428 | +(KOC1) If co's rewriter-set is {kco, xco}, there is no point in kicking it out,
|
|
| 429 | 429 | because it still can't be unified. So we only kick out if the co's
|
| 430 | 430 | rewriter-set becomes empty.
|
| 431 | 431 |
| ... | ... | @@ -529,7 +529,7 @@ Here are the moving parts: |
| 529 | 529 | IdDetails: RepPolyId [ r :-> ConcreteFRR (FixedRuntimeRepOrigin b (..)) ]
|
| 530 | 530 | |
| 531 | 531 | * When instantiating the type of an Id at a call site, at the call to
|
| 532 | - GHC.Tc.Utils.Instantiate.instantiateSigma in GHC.Tc.Gen.App.tcInstFun,
|
|
| 532 | + GHC.Tc.Utils.Instantiate.instantiateSigmaQL in GHC.Tc.Gen.App.tcInstFun,
|
|
| 533 | 533 | create ConcreteTv metavariables (instead of TauTvs) based on the
|
| 534 | 534 | ConcreteTyVars stored in the IdDetails of the Id.
|
| 535 | 535 |
| ... | ... | @@ -285,7 +285,7 @@ topInstantiate orig sigma |
| 285 | 285 | , (theta, body_ty) <- tcSplitPhiTy phi_ty
|
| 286 | 286 | , not (null tvs && null theta)
|
| 287 | 287 | = do { (subst, inst_tvs) <- newMetaTyVarsX empty_subst tvs
|
| 288 | - -- No need to worry about concrete tyvars here (c.f. instantiateSigma)
|
|
| 288 | + -- No need to worry about concrete tyvars here (c.f. instantiateSigmaQL)
|
|
| 289 | 289 | -- See Note [Representation-polymorphism checking built-ins]
|
| 290 | 290 | -- in GHC.Tc.Utils.Concrete.
|
| 291 | 291 |
| ... | ... | @@ -1084,7 +1084,7 @@ When we instantiate 'coerce' in the previous example, we obtain a substitution |
| 1084 | 1084 | |
| 1085 | 1085 | which we need to apply to the 'frr_type' field in order for the type variables
|
| 1086 | 1086 | in the error message to match up.
|
| 1087 | -This is done by the call to 'substConcreteTvOrigin' in 'instantiateSigma'.
|
|
| 1087 | +This is done by the call to 'substConcreteTvOrigin' in 'instantiateSigmaQL'.
|
|
| 1088 | 1088 | |
| 1089 | 1089 | Wrinkle [Extending the substitution]
|
| 1090 | 1090 | |
| ... | ... | @@ -1094,7 +1094,7 @@ Wrinkle [Extending the substitution] |
| 1094 | 1094 | bad2 :: forall {s} (z :: TYPE s). z -> z
|
| 1095 | 1095 | bad2 = coerce @z
|
| 1096 | 1096 | |
| 1097 | - Then 'instantiateSigma' will only instantiate the inferred type variable 'r'
|
|
| 1097 | + Then 'instantiateSigmaQL' will only instantiate the inferred type variable 'r'
|
|
| 1098 | 1098 | of 'coerce', as it needs to leave 'a' un-instantiated so that the visible
|
| 1099 | 1099 | type application '@z' makes sense. In this case, we end up with a substitution
|
| 1100 | 1100 |
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | -- Mostly for backwards compatibility.
|
| 5 | 5 | |
| 6 | 6 | -- One-shot endomorphisms
|
| 7 | --- Like GHC.Internal.Data.Semigroup.Internal.Endo, but uting
|
|
| 7 | +-- Like GHC.Internal.Data.Semigroup.Internal.Endo, but using
|
|
| 8 | 8 | -- the one-shot trick from
|
| 9 | 9 | -- Note [The one-shot state monad trick] in GHC.Utils.Monad.
|
| 10 | 10 |