[Git][ghc/ghc][wip/sand-witch/DIB-INSTANCES] Remove arity inference in type declarations (#23514)
Andrei Borzenkov (@sand-witch)
gitlab at gitlab.haskell.org
Wed Jun 14 13:53:08 UTC 2023
Andrei Borzenkov pushed to branch wip/sand-witch/DIB-INSTANCES at Glasgow Haskell Compiler / GHC
Commits:
4eaa6859 by Andrei Borzenkov at 2023-06-14T17:50:40+04:00
Remove arity inference in type declarations (#23514)
Arity inference in type declarations was introduced
as a workaround for the lack of @k-binders.
They were added in 4aea0a72040, so I simplified all
of this by simply removing arity inference altogether.
This is part of GHC Proposal #425 "Invisible binders in type
declarations".
- - - - -
18 changed files:
- compiler/GHC/Core/Type.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Splice.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- + testsuite/tests/rename/should_compile/T23514b.hs
- testsuite/tests/rename/should_compile/all.T
- + testsuite/tests/rename/should_fail/T23514a.hs
- + testsuite/tests/rename/should_fail/T23514a.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/saks/should_compile/T16724.stdout
- testsuite/tests/saks/should_compile/saks020.hs
- testsuite/tests/saks/should_compile/saks030.hs
- testsuite/tests/saks/should_compile/saks032.hs
- testsuite/tests/typecheck/should_fail/T18640a.hs
- testsuite/tests/typecheck/should_fail/T18640a.stderr
- testsuite/tests/typecheck/should_fail/T18640c.hs
- testsuite/tests/typecheck/should_fail/T18640c.stderr
Changes:
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -60,7 +60,7 @@ module GHC.Core.Type (
mkTyConBindersPreferAnon,
mkPiTy, mkPiTys,
piResultTy, piResultTys,
- applyTysX, dropForAlls,
+ applyTysX, dropForAlls, dropInvisForAlls,
mkFamilyTyConApp,
buildSynTyCon,
@@ -1937,6 +1937,14 @@ dropForAlls ty = go ty
go ty | Just ty' <- coreView ty = go ty'
go res = res
+-- | Drops all invisible ForAllTys
+dropInvisForAlls :: Type -> Type
+dropInvisForAlls ty = go ty
+ where
+ go (ForAllTy (Bndr _ Invisible{}) res) = go res
+ go ty | Just ty' <- coreView ty = go ty'
+ go res = res
+
-- | Attempts to take a forall type apart, but only if it's a proper forall,
-- with a named binder
splitForAllTyCoVar_maybe :: Type -> Maybe (TyCoVar, Type)
=====================================
compiler/GHC/Iface/Syntax.hs
=====================================
@@ -863,12 +863,7 @@ pprIfaceDecl ss (IfaceData { ifName = tycon, ifCType = ctype,
cons = visibleIfConDecls condecls
pp_where = ppWhen (gadt && not (null cons)) $ text "where"
pp_cons = ppr_trim (map show_con cons) :: [SDoc]
- pp_kind = ppUnless (if ki_sig_printable
- then isIfaceRhoType kind
- -- Even in the presence of a standalone kind signature, a non-tau
- -- result kind annotation cannot be discarded as it determines the arity.
- -- See Note [Arity inference in kcCheckDeclHeader_sig] in GHC.Tc.Gen.HsType
- else isIfaceLiftedTypeKind kind)
+ pp_kind = ppUnless (ki_sig_printable || isIfaceLiftedTypeKind kind)
(dcolon <+> ppr kind)
pp_lhs = case parent of
=====================================
compiler/GHC/Tc/Gen/HsType.hs
=====================================
@@ -2557,35 +2557,25 @@ kcCheckDeclHeader_sig sig_kind name flav
-- extended with both 'implicit_tcv_prs' and 'explicit_tv_prs'.
; ctx_k <- kc_res_ki
- -- Work out extra_arity, the number of extra invisible binders from
- -- the kind signature that should be part of the TyCon's arity.
- -- See Note [Arity inference in kcCheckDeclHeader_sig]
- ; let n_invis_tcbs = countWhile isInvisibleTyConBinder excess_sig_tcbs
- invis_arity = case ctx_k of
- AnyKind -> n_invis_tcbs -- No kind signature, so make all the invisible binders
- -- the signature into part of the arity of the TyCon
- OpenKind -> n_invis_tcbs -- Result kind is (TYPE rr), so again make all the
- -- invisible binders part of the arity of the TyCon
- TheKind ki -> 0 `max` (n_invis_tcbs - invisibleTyBndrCount ki)
-
- ; let (invis_tcbs, resid_tcbs) = splitAt invis_arity excess_sig_tcbs
- ; let sig_res_kind' = mkTyConKind resid_tcbs sig_res_kind
-
- ; traceTc "kcCheckDeclHeader_sig 2" $ vcat [ ppr excess_sig_tcbs
- , ppr invis_arity, ppr invis_tcbs
- , ppr n_invis_tcbs ]
+ ; let sig_res_kind' = mkTyConKind excess_sig_tcbs sig_res_kind
+
+ ; traceTc "kcCheckDeclHeader_sig 2" (ppr excess_sig_tcbs)
-- Unify res_ki (from the type declaration) with the residual kind from
-- the kind signature. Don't forget to apply the skolemising 'subst' first.
; case ctx_k of
AnyKind -> return () -- No signature
- _ -> do { res_ki <- newExpectedKind ctx_k
- ; discardResult (unifyKind Nothing sig_res_kind' res_ki) }
+ OpenKind ->
+ do { res_ki <- newExpectedKind ctx_k
+ ; discardResult (unifyKind Nothing (dropInvisForAlls sig_res_kind') res_ki) }
+ TheKind _ ->
+ do { res_ki <- newExpectedKind ctx_k
+ ; discardResult (unifyKind Nothing sig_res_kind' res_ki) }
-- Add more binders for data/newtype, so the result kind has no arrows
-- See Note [Datatype return kinds]
- ; if null resid_tcbs || not (needsEtaExpansion flav)
- then return (invis_tcbs, sig_res_kind')
+ ; if null excess_sig_tcbs || not (needsEtaExpansion flav)
+ then return ([], sig_res_kind')
else return (excess_sig_tcbs, sig_res_kind)
}
@@ -2780,86 +2770,6 @@ Basic plan is this:
part of the signature (k -> Type) with the kind signature of the decl,
(j -> Type). This unification, done in kcCheckDeclHeader, needs TcTyVars.
- * The tricky extra_arity part is described in
- Note [Arity inference in kcCheckDeclHeader_sig]
-
-Note [Arity inference in kcCheckDeclHeader_sig]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider these declarations:
- type family S1 :: forall k2. k1 -> k2 -> Type
- type family S2 (a :: k1) (b :: k2) :: Type
-
-Both S1 and S2 can be given the same standalone kind signature:
- type S1 :: forall k1 k2. k1 -> k2 -> Type
- type S2 :: forall k1 k2. k1 -> k2 -> Type
-
-And, indeed, tyConKind S1 == tyConKind S2. However,
-tyConBinders and tyConResKind for S1 and S2 are different:
-
- tyConBinders S1 == [spec k1]
- tyConResKind S1 == forall k2. k1 -> k2 -> Type
- tyConKind S1 == forall k1 k2. k1 -> k2 -> Type
-
- tyConBinders S2 == [spec k1, spec k2, anon-vis (a :: k1), anon-vis (b :: k2)]
- tyConResKind S2 == Type
- tyConKind S1 == forall k1 k2. k1 -> k2 -> Type
-
-This difference determines the /arity/:
- tyConArity tc == length (tyConBinders tc)
-That is, the arity of S1 is 1, while the arity of S2 is 4.
-
-'kcCheckDeclHeader_sig' needs to infer the desired arity, to split the
-standalone kind signature into binders and the result kind. It does so
-in two rounds:
-
-1. matchUpSigWithDecl matches up
- - the [TyConBinder] from (applying splitTyConKind to) the kind signature
- - with the [LHsTyVarBndr] from the type declaration.
- That may leave some excess TyConBinder: in the case of S2 there are
- no excess TyConBinders, but in the case of S1 there are two (since
- there are no LHsTYVarBndrs.
-
-2. Split off further TyConBinders (in the case of S1, one more) to
- make it possible to unify the residual return kind with the
- signature in the type declaration. More precisely, split off such
- enough invisible that the remainder of the standalone kind
- signature and the user-written result kind signature have the same
- number of invisible quantifiers.
-
-As another example consider the following declarations:
-
- type F :: Type -> forall j. j -> forall k1 k2. (k1, k2) -> Type
- type family F a b
-
- type G :: Type -> forall j. j -> forall k1 k2. (k1, k2) -> Type
- type family G a b :: forall r2. (r1, r2) -> Type
-
-For both F and G, the signature (after splitTyConKind) has
- sig_tcbs :: [TyConBinder]
- = [ anon-vis (@a_aBq), spec (@j_auA), anon-vis (@(b_aBr :: j_auA))
- , spec (@k1_auB), spec (@k2_auC)
- , anon-vis (@(c_aBs :: (k1_auB, k2_auC)))]
-
-matchUpSigWithDecl will consume the first three of these, passing on
- excess_sig_tcbs
- = [ spec (@k1_auB), spec (@k2_auC)
- , anon-vis (@(c_aBs :: (k1_auB, k2_auC)))]
-
-For F, there is no result kind signature in the declaration for F, so
-we absorb all invisible binders into F's arity. The resulting arity of
-F is 3+2=5.
-
-Now, in the case of G, we have a result kind sig 'forall r2. (r2,r2)->Type'.
-This has one invisible binder, so we split of enough extra binders from
-our excess_sig_tcbs to leave just one to match 'r2'.
-
- res_ki = forall r2. (r1, r2) -> Type
- kisig = forall k1 k2. (k1, k2) -> Type
- ^^^
- split off this one.
-
-The resulting arity of G is 3+1=4.
-
Note [discardResult in kcCheckDeclHeader_sig]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We use 'unifyKind' to check inline kind annotations in declaration headers
=====================================
compiler/GHC/Tc/Gen/Splice.hs
=====================================
@@ -796,7 +796,7 @@ tcTExpTy m_ty exp_ty
TcRnTHError $ TypedTHError $ TypedTHWithPolyType exp_ty
; codeCon <- tcLookupTyCon codeTyConName
; let rep = getRuntimeRep exp_ty
- ; return (mkTyConApp codeCon [rep, m_ty, exp_ty]) }
+ ; return (mkTyConApp codeCon [m_ty, rep, exp_ty]) }
quotationCtxtDoc :: LHsExpr GhcRn -> SDoc
quotationCtxtDoc br_body
=====================================
libraries/template-haskell/Language/Haskell/TH/Syntax.hs
=====================================
@@ -378,8 +378,11 @@ The splice will evaluate to (MkAge 3) and you can't add that to
4::Int. So you can't coerce a (Code Q Age) to a (Code Q Int). -}
-- Code constructor
-
+#if __GLASGOW_HASKELL__ >= 907
+type Code :: (Kind.Type -> Kind.Type) -> forall r. TYPE r -> Kind.Type
+#else
type Code :: (Kind.Type -> Kind.Type) -> TYPE r -> Kind.Type
+#endif
type role Code representational nominal -- See Note [Role of TExp]
newtype Code m a = Code
{ examineCode :: m (TExp a) -- ^ Underlying monadic value
=====================================
testsuite/tests/rename/should_compile/T23514b.hs
=====================================
@@ -0,0 +1,9 @@
+{-# LANGUAGE TypeFamilies, DataKinds #-}
+module T23514b where
+
+import GHC.Types
+
+type F :: Type -> forall k. Maybe k
+type family F x @k where
+ F Int @Type = Just Bool
+ F Int = Just Either
=====================================
testsuite/tests/rename/should_compile/all.T
=====================================
@@ -212,3 +212,4 @@ test('T22122', [expect_broken(22122), extra_files(['T22122_aux.hs'])], multimod_
test('T23240', [req_th, extra_files(['T23240_aux.hs'])], multimod_compile, ['T23240', '-v0'])
test('T23318', normal, compile, ['-Wduplicate-exports'])
test('T23434', normal, compile, [''])
+test('T23514b', normal, compile, [''])
=====================================
testsuite/tests/rename/should_fail/T23514a.hs
=====================================
@@ -0,0 +1,9 @@
+{-# LANGUAGE TypeFamilies, DataKinds #-}
+module T23514a where
+
+import GHC.Types
+
+type F :: Type -> forall k. Maybe k
+type family F x where
+ F Int @Type = Just Bool
+ F Int = Just Either
=====================================
testsuite/tests/rename/should_fail/T23514a.stderr
=====================================
@@ -0,0 +1,6 @@
+
+T23514a.hs:9:17: error: [GHC-83865]
+ • Expected kind ‘forall k. Maybe k’,
+ but ‘Just Either’ has kind ‘Maybe (* -> * -> *)’
+ • In the type ‘Just Either’
+ In the type family declaration for ‘F’
=====================================
testsuite/tests/rename/should_fail/all.T
=====================================
@@ -199,3 +199,4 @@ test('RnUnexpectedStandaloneDeriving', normal, compile_fail, [''])
test('RnStupidThetaInGadt', normal, compile_fail, [''])
test('PackageImportsDisabled', normal, compile_fail, [''])
test('ImportLookupIllegal', normal, compile_fail, [''])
+test('T23514a', normal, compile_fail, [''])
=====================================
testsuite/tests/saks/should_compile/T16724.stdout
=====================================
@@ -1,6 +1,6 @@
type T1 :: forall k (a :: k). Type
-type family T1 @k @a
+type family T1
-- Defined at T16724.hs:11:1
type T2 :: forall {k} (a :: k). Type
-type family T2 @{k} @a
+type family T2
-- Defined at T16724.hs:15:1
=====================================
testsuite/tests/saks/should_compile/saks020.hs
=====================================
@@ -6,4 +6,4 @@ module SAKS_020 where
import Data.Kind (Type)
type T :: forall k. k -> forall j. j -> Type
-data T (x :: hk) :: hj -> Type
+data T (x :: hk) @hj :: hj -> Type
=====================================
testsuite/tests/saks/should_compile/saks030.hs
=====================================
@@ -10,7 +10,7 @@ import Data.Type.Equality
type T1 :: forall k (a :: k). Bool
type T2 :: k -> Bool
-type family T1 where
+type family T1 @k @a where
T1 @Bool @True = False
T1 @Bool @False = True
=====================================
testsuite/tests/saks/should_compile/saks032.hs
=====================================
@@ -18,4 +18,4 @@ type F1 :: Type -> forall j. j -> forall k1 k2. (k1, k2) -> Type
type family F1 a b
type F2 :: Type -> forall j. j -> forall k1 k2. (k1, k2) -> Type
-type family F2 a b :: forall r2. (r1, r2) -> Type
+type family F2 a b @r1 :: forall r2. (r1, r2) -> Type
=====================================
testsuite/tests/typecheck/should_fail/T18640a.hs
=====================================
@@ -8,4 +8,4 @@ module T18640a where
import Data.Kind
type F2 :: forall a b. Type -> a
-type family F2 :: forall b. Type -> Type where
+type family F2 @a :: forall b. Type -> Type where
=====================================
testsuite/tests/typecheck/should_fail/T18640a.stderr
=====================================
@@ -5,5 +5,5 @@ T18640a.hs:11:1: error: [GHC-25897]
Actual: forall (b :: k). * -> a
‘a’ is a rigid type variable bound by
the type family declaration for ‘F2’
- at T18640a.hs:10:19
+ at T18640a.hs:11:17
• In the type family declaration for ‘F2’
=====================================
testsuite/tests/typecheck/should_fail/T18640c.hs
=====================================
@@ -11,4 +11,4 @@ type F1 :: forall k -> Type
type family F1 k :: Type
type F2 :: forall x. forall k -> x
-type F2 = F1
+type F2 k = F1 k
=====================================
testsuite/tests/typecheck/should_fail/T18640c.stderr
=====================================
@@ -1,10 +1,8 @@
-T18640c.hs:14:11: error: [GHC-25897]
- • Couldn't match kind ‘x’ with ‘*’
- Expected kind ‘forall (k1 :: k) -> x’,
- but ‘F1’ has kind ‘forall (k1 :: k) -> *’
+T18640c.hs:14:13: error: [GHC-25897]
+ • Expected kind ‘x’, but ‘F1 k’ has kind ‘*’
‘x’ is a rigid type variable bound by
the type synonym declaration for ‘F2’
at T18640c.hs:13:19
- • In the type ‘F1’
+ • In the type ‘F1 k’
In the type declaration for ‘F2’
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4eaa68595592067eadbcae9c37ff2597bf3fa29b
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4eaa68595592067eadbcae9c37ff2597bf3fa29b
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/20230614/eba149ec/attachment-0001.html>
More information about the ghc-commits
mailing list