[Git][ghc/ghc][wip/T24810] Cast visibilities correctly

Simon Peyton Jones (@simonpj) gitlab at gitlab.haskell.org
Fri May 17 16:33:04 UTC 2024



Simon Peyton Jones pushed to branch wip/T24810 at Glasgow Haskell Compiler / GHC


Commits:
f5627b7c by Simon Peyton Jones at 2024-05-17T17:32:29+01:00
Cast visibilities correctly

- - - - -


5 changed files:

- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Types/Var.hs


Changes:

=====================================
compiler/GHC/Core/TyCo/Rep.hs
=====================================
@@ -1195,6 +1195,21 @@ among branches, but that doesn't quite concern us here.)
 The Int in the AxiomInstCo constructor is the 0-indexed number
 of the chosen branch.
 
+Note [Required foralls in Core]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider the CoreExpr (Lam a e) where `a` is a TyVar, and (e::e_ty).
+It has type
+   forall a{Specified}. e_ty
+Note the Specified visibility;
+the Core type just isn't able to express more than one visiblity, and we pick `Specified`.
+See `exprType` and `mkLamType` in GHC.Core.Utils, and `GHC.Type.Var.coreLamForAllTyFlag`.
+
+So how can we ever get a term of type (forall a -> e_ty)?  Answer: /only/ via a
+cast built with ForAllCo.  See `GHC.Tc.Types.Evidence.mkWpForAllCast`.  This does
+not seem very satisfying, but it does the job.
+
+See also Note [ForAllTy and type equality] in GHC.Core.TyCo.Compare.
+
 Note [ForAllCo]
 ~~~~~~~~~~~~~~~
 See also Note [ForAllTy and type equality] in GHC.Core.TyCo.Compare.
@@ -1255,6 +1270,7 @@ Several things to note here
   flag `GHC.Type.Var.coreTyLamForAllTyFlag`, not (forall a -> ty).
   See `GHC.Type.Var.coreTyLamForAllTyFlag` and `GHC.Core.Utils.mkLamType`.
   The only way to get a term of type (forall a -> ty) is to cast a lambda.
+  See Note [Required foralls in Core].
 
 (FC5) In a /type/, in (ForAllTy cv ty) where cv is a CoVar, we insist that
   `cv` must appear free in `ty`; see Note [Unused coercion variable in ForAllTy]


=====================================
compiler/GHC/Core/Utils.hs
=====================================
@@ -170,7 +170,7 @@ mkLamTypes :: [Var] -> Type -> Type
 mkLamType v body_ty
    | isTyVar v
    = mkForAllTy (Bndr v coreTyLamForAllTyFlag) body_ty
-     -- coreTyLamForAllTyFlag: see (FC4) in Note [ForAllCo]
+     -- coreTyLamForAllTyFlag: see Note [Required foralls in Core]
      --                        in GHC.Core.TyCo.Rep
 
    | isCoVar v


=====================================
compiler/GHC/Tc/Types/Evidence.hs
=====================================
@@ -7,7 +7,7 @@ module GHC.Tc.Types.Evidence (
 
   -- * HsWrapper
   HsWrapper(..),
-  (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpVisTyLam,
+  (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpForAllCast,
   mkWpEvLams, mkWpLet, mkWpFun, mkWpCastN, mkWpCastR, mkWpEta,
   collectHsWrapBinders,
   idHsWrapper, isIdHsWrapper,
@@ -258,20 +258,20 @@ mkWpEvVarApps vs = mk_co_app_fn WpEvApp (map (EvExpr . evId) vs)
 mkWpTyLams :: [TyVar] -> HsWrapper
 mkWpTyLams ids = mk_co_lam_fn WpTyLam ids
 
--- Construct a type lambda and cast its type
--- from `forall tv. res` to `forall tv -> res`.
+-- mkWpForAllCast [tv{vis}] constructs a cast
+--   forall tv. res  ~R#   forall tv{vis} res`.
+-- See Note [Required foralls in Core]
 --
--- (\ @tv -> e )
---    `cast` (forall (tv[spec]~[req] :: <*>_N). <res>_R       -- ForAllCo is the evidence that...
---              :: (forall tv. res) ~R# (forall tv -> res))   -- invisible and visible foralls are representationally equal
---
-mkWpVisTyLam :: TyVar -> Type -> HsWrapper
-mkWpVisTyLam tv res =
-  WpCast (mkForAllCo tv coreTyLamForAllTyFlag Required kind_co body_co)
-  <.> WpTyLam tv
+-- It's a no-op if all binders are invisible;
+-- but in that case we refrain from calling it.
+mkWpForAllCast :: [ForAllTyBinder] -> Type -> HsWrapper
+mkWpForAllCast bndrs res_ty
+  = mkWpCastR (go bndrs)
   where
-    kind_co = mkNomReflCo (varType tv)
-    body_co = mkRepReflCo res
+    go []                 = mkRepReflCo res_ty
+    go (Bndr tv vis : bs) = mkForAllCo tv coreTyLamForAllTyFlag vis kind_co (go bs)
+      where
+        kind_co = mkNomReflCo (varType tv)
 
 mkWpEvLams :: [Var] -> HsWrapper
 mkWpEvLams ids = mk_co_lam_fn WpEvLam ids


=====================================
compiler/GHC/Tc/Utils/Instantiate.hs
=====================================
@@ -247,8 +247,13 @@ skolemiseRequired skolem_info n_req sigma
       , not (null bndrs)
       = do { (subst', bndrs1) <- tcInstSkolTyVarBndrsX skolem_info subst bndrs
            ; let tvs1 = binderVars bndrs1
+                 -- fix_up_vis: see Note [Required foralls in Core]
+                 fix_up_vis | n_req == n_req'
+                            = idHsWrapper
+                            | otherwise
+                            = mkWpForAllCast bndrs1 (substTy subst' inner_ty)
            ; go n_req' subst'
-                (wrap <.> mkWpTyLams tvs1)
+                (wrap <.> fix_up_vis <.> mkWpTyLams tvs1)
                 (acc_nms   ++ map (tyVarName . binderVar) bndrs)
                 (acc_bndrs ++ bndrs1)
                 ev_vars


=====================================
compiler/GHC/Types/Var.hs
=====================================
@@ -503,7 +503,7 @@ isSpecifiedForAllTyFlag _                         = False
 coreTyLamForAllTyFlag :: ForAllTyFlag
 -- ^ The ForAllTyFlag on a (Lam a e) term, where `a` is a type variable.
 -- If you want other ForAllTyFlag, use a cast.
--- See Note [ForAllCo] in GHC.Core.TyCo.Rep
+-- See Note [Required foralls in Core] in GHC.Core.TyCo.Rep
 coreTyLamForAllTyFlag = Specified
 
 instance Outputable ForAllTyFlag where



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5627b7c846aa6a8776323e3cbc3a8e59b650741

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5627b7c846aa6a8776323e3cbc3a8e59b650741
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/20240517/f36545af/attachment-0001.html>


More information about the ghc-commits mailing list