[Git][ghc/ghc][wip/T24676] Emit an equality constraint in make_kinds_ok
Simon Peyton Jones (@simonpj)
gitlab at gitlab.haskell.org
Mon May 20 16:39:18 UTC 2024
Simon Peyton Jones pushed to branch wip/T24676 at Glasgow Haskell Compiler / GHC
Commits:
f4ccf0cd by Simon Peyton Jones at 2024-05-20T17:34:31+01:00
Emit an equality constraint in make_kinds_ok
Makes QL a tiny bit more robust
Consider:
k :: Type
co :: k ~ Type
f :: forall (a :: k). Proxy k a -> blah
q :: Proxy Type (forall b. b -> b)
x = ... f q ...
When QL-ing (f q) we'll instantiate `a` with `kappa` and qlUnify
Proxy k kappa ~ Proxy Type (forall b. b->b)
Ql-Unifying k with Type will fail; fine.
If ql-unifying (kappa::k) with (forall b. b->b) fails, then kappa will
end up as a mono-tyvar and subsequent unification will fail. But it
can succed with (kappa := (forall b. b->b) |> co), where we emit
an equalityconstraint for `co`.
- - - - -
1 changed file:
- compiler/GHC/Tc/Gen/App.hs
Changes:
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -21,11 +21,9 @@ module GHC.Tc.Gen.App
import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcPolyExpr )
-import GHC.Types.Var
-import GHC.Builtin.Types ( multiplicityTy )
-import GHC.Tc.Gen.Head
-import Language.Haskell.Syntax.Basic
import GHC.Hs
+
+import GHC.Tc.Gen.Head
import GHC.Tc.Errors.Types
import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.Unify
@@ -38,6 +36,7 @@ import GHC.Tc.Types.Evidence
import GHC.Tc.Types.Origin
import GHC.Tc.Utils.TcType as TcType
import GHC.Tc.Zonk.TcType
+
import GHC.Core.ConLike (ConLike(..))
import GHC.Core.DataCon (dataConConcreteTyVars)
import GHC.Core.TyCon
@@ -47,20 +46,29 @@ import GHC.Core.TyCo.Subst (substTyWithInScope)
import GHC.Core.TyCo.FVs
import GHC.Core.Type
import GHC.Core.Coercion
-import GHC.Types.Var.Set
+
+import GHC.Builtin.Types ( multiplicityTy )
import GHC.Builtin.PrimOps( tagToEnumKey )
import GHC.Builtin.Names
import GHC.Driver.DynFlags
+
+import GHC.Types.Var
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Types.Name.Reader
import GHC.Types.SrcLoc
+import GHC.Types.Var.Set
import GHC.Types.Var.Env ( emptyTidyEnv, mkInScopeSet )
+import GHC.Types.Basic( TypeOrKind(..) )
+
import GHC.Data.Maybe
+
import GHC.Utils.Misc
import GHC.Utils.Outputable as Outputable
import GHC.Utils.Panic
+
import qualified GHC.LanguageExtensions as LangExt
+import Language.Haskell.Syntax.Basic
import Control.Monad
import Data.Function
@@ -1882,29 +1890,43 @@ qlUnify delta ty1 ty2
-- Passes the occurs check
, not (isConcreteTyVar kappa) || isConcreteType ty2
-- Don't unify a concrete instantiatiation variable with a non-concrete type
- = do { let kappa_kind = tyVarKind kappa
- ty2_kind = typeKind ty2
- ; kinds_ok <- go_kinds kappa_kind ty2_kind
- ; when kinds_ok $ -- If kinds_ok is False, we simply no-op
- -- See Note [Actual unification during QuickLook] (UQL2)
- do { traceTc "qlUnify:update" $
- hang (ppr kappa <+> dcolon <+> ppr kappa_kind)
- 2 (text ":=" <+> ppr ty2 <+> dcolon <+> ppr ty2_kind)
- ; liftZonkM $ writeMetaTyVar kappa ty2 }}
+ = do { ty2' <- make_kinds_ok kappa ty2
+ ; traceTc "qlUnify:update" $
+ ppr kappa <+> text ":=" <+> ppr ty2
+ ; liftZonkM $ writeMetaTyVar kappa ty2' }
| otherwise
= return () -- Occurs-check or forall-bound variable
- go_kinds :: TcKind -> TcKind -> TcM Bool
+ make_kinds_ok :: TcTyVar -> TcType -> TcM TcType
+ -- Don't call unifyKind! Instead try to make the kinds equal with
+ -- unifyKind; and if that fails just emit an equality
-- See Note [Actual unification during QuickLook] (UQL2)
- go_kinds kind1 kind2
- | kind1 `tcEqType` kind2 = return True
- | otherwise = do { qlUnify delta kind1 kind2
- ; liftZonkM $
- do { kind1 <- zonkTcType kind1
- ; kind2 <- zonkTcType kind2
- ; return (kind1 `tcEqType` kind2) } }
-
+ make_kinds_ok kappa ty2
+ | kind1 `tcEqType` kind2
+ = return ty2
+ | otherwise
+ = do { qlUnify delta kind1 kind2
+ ; (kind1, kind2) <- liftZonkM $
+ do { kind1 <- zonkTcType kind1
+ ; kind2 <- zonkTcType kind2
+ ; return (kind1, kind2) }
+ ; if (kind1 `tcEqType` kind2)
+ then return ty2
+ else
+ do { co <- emitWantedEq orig KindLevel Nominal kind1 kind2
+ ; traceTc "make_kinds_ok" $
+ vcat [ hang (ppr kappa <+> dcolon <+> ppr kind1 <+> text ":=")
+ 2 (ppr ty2 <+> dcolon <+> ppr kind2)
+ , text "co:" <+> ppr co ]
+ ; return (mkCastTy ty2 co) } }
+ where
+ kind1 = tyVarKind kappa
+ kind2 = typeKind ty2
+ orig = TypeEqOrigin { uo_actual = kind1
+ , uo_expected = kind2
+ , uo_thing = Just (TypeThing ty2)
+ , uo_visible = True }
{- Note [Actual unification during QuickLook]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f4ccf0cdbd9ba531ce71726a8b37df584b929ebf
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f4ccf0cdbd9ba531ce71726a8b37df584b929ebf
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240520/f7f90437/attachment-0001.html>
More information about the ghc-commits
mailing list