summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Zavialov <vlad.z.4096@gmail.com>2022-12-01 21:14:25 +0300
committerVladislav Zavialov <vlad.z.4096@gmail.com>2023-02-03 16:09:24 +0300
commit21cfded1b061bb1ad02537de0c8e8681a5c63f43 (patch)
tree3894826fa3843531dd358e7a1398dbfda501500d
parent8feb93013cf6f093e025c9e9a3213ae1fa0f73a0 (diff)
downloadhaskell-21cfded1b061bb1ad02537de0c8e8681a5c63f43.tar.gz
Invisible binders in type declarations (#22560)wip/int-index/decl-invis-binders
This patch implements @k-binders introduced in GHC Proposal #425 and guarded behind the TypeAbstractions extension: type D :: forall k j. k -> j -> Type data D @k @j a b = ... ^^ ^^ To represent the new syntax, we modify LHsQTyVars as follows: - hsq_explicit :: [LHsTyVarBndr () pass] + hsq_explicit :: [LHsTyVarBndr (HsBndrVis pass) pass] HsBndrVis is a new data type that records the distinction between type variable binders written with and without the @ sign: data HsBndrVis pass = HsBndrRequired | HsBndrInvisible (LHsToken "@" pass) The rest of the patch updates GHC, template-haskell, and haddock to handle the new syntax. Parser: The PsErrUnexpectedTypeAppInDecl error message is removed. The syntax it used to reject is now permitted. Renamer: The @ sign does not affect the scope of a binder, so the changes to the renamer are minimal. See rnLHsTyVarBndrVisFlag. Type checker: There are three code paths that were updated to deal with the newly introduced invisible type variable binders: 1. checking SAKS: see kcCheckDeclHeader_sig, matchUpSigWithDecl 2. checking CUSK: see kcCheckDeclHeader_cusk 3. inference: see kcInferDeclHeader, rejectInvisibleBinders Helper functions bindExplicitTKBndrs_Q_Skol and bindExplicitTKBndrs_Q_Tv are generalized to work with HsBndrVis. Updates the haddock submodule. Metric Increase: MultiLayerModulesTH_OneShot Co-authored-by: Simon Peyton Jones <simon.peytonjones@gmail.com>
-rw-r--r--compiler/GHC/Builtin/Names/TH.hs31
-rw-r--r--compiler/GHC/Core/TyCon.hs19
-rw-r--r--compiler/GHC/Hs/Instances.hs5
-rw-r--r--compiler/GHC/Hs/Type.hs24
-rw-r--r--compiler/GHC/HsToCore/Quote.hs32
-rw-r--r--compiler/GHC/Parser/Errors/Ppr.hs10
-rw-r--r--compiler/GHC/Parser/Errors/Types.hs3
-rw-r--r--compiler/GHC/Parser/PostProcess.hs27
-rw-r--r--compiler/GHC/Rename/HsType.hs24
-rw-r--r--compiler/GHC/Tc/Errors/Ppr.hs36
-rw-r--r--compiler/GHC/Tc/Errors/Types.hs45
-rw-r--r--compiler/GHC/Tc/Gen/HsType.hs201
-rw-r--r--compiler/GHC/Tc/Gen/Splice.hs47
-rw-r--r--compiler/GHC/Tc/TyCl.hs377
-rw-r--r--compiler/GHC/Tc/Utils/TcMType.hs6
-rw-r--r--compiler/GHC/Tc/Utils/TcType.hs46
-rw-r--r--compiler/GHC/ThToHs.hs13
-rw-r--r--compiler/GHC/Types/Error/Codes.hs5
-rw-r--r--compiler/GHC/Types/Hint.hs8
-rw-r--r--compiler/GHC/Types/Hint/Ppr.hs2
-rw-r--r--compiler/Language/Haskell/Syntax/Type.hs20
-rw-r--r--docs/users_guide/9.8.1-notes.rst9
-rw-r--r--docs/users_guide/exts/primitives.rst2
-rw-r--r--docs/users_guide/exts/type_abstractions.rst96
-rw-r--r--libraries/ghci/GHCi/TH/Binary.hs1
-rw-r--r--libraries/template-haskell/Language/Haskell/TH.hs1
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib.hs41
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs35
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Ppr.hs8
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Syntax.hs29
-rw-r--r--libraries/template-haskell/changelog.md9
-rw-r--r--testsuite/tests/dependent/should_compile/T16344b.hs2
-rw-r--r--testsuite/tests/dependent/should_fail/T16344a.hs2
-rw-r--r--testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr32
-rw-r--r--testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr2
-rw-r--r--testsuite/tests/indexed-types/should_fail/T9160.hs2
-rw-r--r--testsuite/tests/parser/should_compile/DumpParsedAst.stderr10
-rw-r--r--testsuite/tests/parser/should_compile/DumpRenamedAst.stderr16
-rw-r--r--testsuite/tests/parser/should_compile/DumpSemis.stderr2
-rw-r--r--testsuite/tests/parser/should_compile/KindSigs.stderr10
-rw-r--r--testsuite/tests/parser/should_compile/T15323.stderr2
-rw-r--r--testsuite/tests/parser/should_compile/T20452.stderr16
-rw-r--r--testsuite/tests/polykinds/T7022a.hs2
-rw-r--r--testsuite/tests/th/ClosedFam2TH.hs6
-rw-r--r--testsuite/tests/th/T10828.hs2
-rw-r--r--testsuite/tests/th/T10828a.hs2
-rw-r--r--testsuite/tests/th/T10828b.hs2
-rw-r--r--testsuite/tests/th/T11345.hs2
-rw-r--r--testsuite/tests/th/T12503.hs2
-rw-r--r--testsuite/tests/th/T13098.hs2
-rw-r--r--testsuite/tests/th/T6018th.hs10
-rw-r--r--testsuite/tests/th/T7667.hs2
-rw-r--r--testsuite/tests/th/T8499.hs2
-rw-r--r--testsuite/tests/th/TH_RichKinds2.hs4
-rw-r--r--testsuite/tests/th/TH_Roles1.hs2
-rw-r--r--testsuite/tests/th/TH_Roles2.hs2
-rw-r--r--testsuite/tests/th/TH_reifyDecl1.stderr7
-rw-r--r--testsuite/tests/typecheck/should_compile/T22560a.hs39
-rw-r--r--testsuite/tests/typecheck/should_compile/T22560b.hs20
-rw-r--r--testsuite/tests/typecheck/should_compile/T22560c.hs29
-rw-r--r--testsuite/tests/typecheck/should_compile/T22560d.hs33
-rw-r--r--testsuite/tests/typecheck/should_compile/T22560d.script10
-rw-r--r--testsuite/tests/typecheck/should_compile/T22560d.stdout8
-rw-r--r--testsuite/tests/typecheck/should_compile/T22560e.hs9
-rw-r--r--testsuite/tests/typecheck/should_compile/all.T5
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_a.hs7
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_a.stderr8
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_b.hs6
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_b.stderr8
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_c.hs6
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_c.stderr5
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_d.hs5
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_d.stderr8
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_ext.hs7
-rw-r--r--testsuite/tests/typecheck/should_fail/T22560_fail_ext.stderr8
-rw-r--r--testsuite/tests/typecheck/should_fail/all.T5
-rw-r--r--utils/check-exact/ExactPrint.hs10
m---------utils/haddock0
78 files changed, 1173 insertions, 420 deletions
diff --git a/compiler/GHC/Builtin/Names/TH.hs b/compiler/GHC/Builtin/Names/TH.hs
index bea3b9715f..251b171970 100644
--- a/compiler/GHC/Builtin/Names/TH.hs
+++ b/compiler/GHC/Builtin/Names/TH.hs
@@ -109,8 +109,11 @@ templateHaskellNames = [
-- TyVarBndr
plainTVName, kindedTVName,
plainInvisTVName, kindedInvisTVName,
+ plainBndrTVName, kindedBndrTVName,
-- Specificity
specifiedSpecName, inferredSpecName,
+ -- Visibility
+ bndrReqName, bndrInvisName,
-- Role
nominalRName, representationalRName, phantomRName, inferRName,
-- Kind
@@ -156,7 +159,9 @@ templateHaskellNames = [
expQTyConName, fieldExpTyConName, predTyConName,
stmtTyConName, decsTyConName, conTyConName, bangTypeTyConName,
varBangTypeTyConName, typeQTyConName, expTyConName, decTyConName,
- typeTyConName, tyVarBndrUnitTyConName, tyVarBndrSpecTyConName, clauseTyConName,
+ typeTyConName,
+ tyVarBndrUnitTyConName, tyVarBndrSpecTyConName, tyVarBndrVisTyConName,
+ clauseTyConName,
patQTyConName, funDepTyConName, decsQTyConName,
ruleBndrTyConName, tySynEqnTyConName,
roleTyConName, codeTyConName, injAnnTyConName, kindTyConName,
@@ -492,11 +497,20 @@ plainInvisTVName, kindedInvisTVName :: Name
plainInvisTVName = libFun (fsLit "plainInvisTV") plainInvisTVIdKey
kindedInvisTVName = libFun (fsLit "kindedInvisTV") kindedInvisTVIdKey
+plainBndrTVName, kindedBndrTVName :: Name
+plainBndrTVName = libFun (fsLit "plainBndrTV") plainBndrTVIdKey
+kindedBndrTVName = libFun (fsLit "kindedBndrTV") kindedBndrTVIdKey
+
-- data Specificity = ...
specifiedSpecName, inferredSpecName :: Name
specifiedSpecName = libFun (fsLit "specifiedSpec") specifiedSpecKey
inferredSpecName = libFun (fsLit "inferredSpec") inferredSpecKey
+-- data BndrVis = ...
+bndrReqName, bndrInvisName :: Name
+bndrReqName = libFun (fsLit "bndrReq") bndrReqKey
+bndrInvisName = libFun (fsLit "bndrInvis") bndrInvisKey
+
-- data Role = ...
nominalRName, representationalRName, phantomRName, inferRName :: Name
nominalRName = libFun (fsLit "nominalR") nominalRIdKey
@@ -569,7 +583,7 @@ patQTyConName, expQTyConName, stmtTyConName,
varBangTypeTyConName, typeQTyConName,
decsQTyConName, ruleBndrTyConName, tySynEqnTyConName, roleTyConName,
derivClauseTyConName, kindTyConName,
- tyVarBndrUnitTyConName, tyVarBndrSpecTyConName,
+ tyVarBndrUnitTyConName, tyVarBndrSpecTyConName, tyVarBndrVisTyConName,
derivStrategyTyConName :: Name
-- These are only used for the types of top-level splices
expQTyConName = libTc (fsLit "ExpQ") expQTyConKey
@@ -589,6 +603,7 @@ derivClauseTyConName = thTc (fsLit "DerivClause") derivClauseTyConKey
kindTyConName = thTc (fsLit "Kind") kindTyConKey
tyVarBndrUnitTyConName = libTc (fsLit "TyVarBndrUnit") tyVarBndrUnitTyConKey
tyVarBndrSpecTyConName = libTc (fsLit "TyVarBndrSpec") tyVarBndrSpecTyConKey
+tyVarBndrVisTyConName = libTc (fsLit "TyVarBndrVis") tyVarBndrVisTyConKey
derivStrategyTyConName = thTc (fsLit "DerivStrategy") derivStrategyTyConKey
-- quasiquoting
@@ -652,7 +667,7 @@ quoteClassKey = mkPreludeClassUnique 201
expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey,
patTyConKey,
stmtTyConKey, conTyConKey, typeQTyConKey, typeTyConKey,
- tyVarBndrUnitTyConKey, tyVarBndrSpecTyConKey,
+ tyVarBndrUnitTyConKey, tyVarBndrSpecTyConKey, tyVarBndrVisTyConKey,
decTyConKey, bangTypeTyConKey, varBangTypeTyConKey,
fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey,
funDepTyConKey, predTyConKey,
@@ -694,6 +709,7 @@ decsTyConKey = mkPreludeTyConUnique 236
tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237
codeTyConKey = mkPreludeTyConUnique 238
modNameTyConKey = mkPreludeTyConUnique 239
+tyVarBndrVisTyConKey = mkPreludeTyConUnique 240
{- *********************************************************************
* *
@@ -1022,6 +1038,10 @@ plainInvisTVIdKey, kindedInvisTVIdKey :: Unique
plainInvisTVIdKey = mkPreludeMiscIdUnique 482
kindedInvisTVIdKey = mkPreludeMiscIdUnique 483
+plainBndrTVIdKey, kindedBndrTVIdKey :: Unique
+plainBndrTVIdKey = mkPreludeMiscIdUnique 484
+kindedBndrTVIdKey = mkPreludeMiscIdUnique 485
+
-- data Role = ...
nominalRIdKey, representationalRIdKey, phantomRIdKey, inferRIdKey :: Unique
nominalRIdKey = mkPreludeMiscIdUnique 416
@@ -1106,6 +1126,11 @@ specifiedSpecKey, inferredSpecKey :: Unique
specifiedSpecKey = mkPreludeMiscIdUnique 498
inferredSpecKey = mkPreludeMiscIdUnique 499
+-- data BndrVis = ...
+bndrReqKey, bndrInvisKey :: Unique
+bndrReqKey = mkPreludeMiscIdUnique 800 -- TODO (int-index): make up some room in the 5** numberspace?
+bndrInvisKey = mkPreludeMiscIdUnique 801
+
{-
************************************************************************
* *
diff --git a/compiler/GHC/Core/TyCon.hs b/compiler/GHC/Core/TyCon.hs
index 0311ba32bd..b549fb7cb1 100644
--- a/compiler/GHC/Core/TyCon.hs
+++ b/compiler/GHC/Core/TyCon.hs
@@ -25,7 +25,8 @@ module GHC.Core.TyCon(
mkRequiredTyConBinder,
mkAnonTyConBinder, mkAnonTyConBinders,
tyConBinderForAllTyFlag, tyConBndrVisForAllTyFlag, isNamedTyConBinder,
- isVisibleTyConBinder, isInvisibleTyConBinder, isVisibleTcbVis,
+ isVisibleTyConBinder, isInvisibleTyConBinder,
+ isVisibleTcbVis, isInvisSpecTcbVis,
-- ** Field labels
tyConFieldLabels, lookupTyConFieldLabel,
@@ -508,6 +509,10 @@ isVisibleTcbVis :: TyConBndrVis -> Bool
isVisibleTcbVis (NamedTCB vis) = isVisibleForAllTyFlag vis
isVisibleTcbVis AnonTCB = True
+isInvisSpecTcbVis :: TyConBndrVis -> Bool
+isInvisSpecTcbVis (NamedTCB Specified) = True
+isInvisSpecTcbVis _ = False
+
isInvisibleTyConBinder :: VarBndr tv TyConBndrVis -> Bool
-- Works for IfaceTyConBinder too
isInvisibleTyConBinder tcb = not (isVisibleTyConBinder tcb)
@@ -883,8 +888,8 @@ data TyConDetails =
promDcInfo :: PromDataConInfo -- ^ See comments with 'PromDataConInfo'
}
- -- | These exist only during type-checking. See Note [How TcTyCons work]
- -- in "GHC.Tc.TyCl"
+ -- | These exist only during type-checking.
+ -- See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in "GHC.Tc.TyCl"
| TcTyCon {
-- NB: the tyConArity of a TcTyCon must match
-- the number of Required (positional, user-specified)
@@ -918,7 +923,7 @@ where
* tyConArity = length required_tvs
tcTyConScopedTyVars are used only for MonoTcTyCons, not PolyTcTyCons.
-See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.Utils.TcType.
+See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.TyCl
Note [Representation-polymorphic TyCons]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1837,13 +1842,11 @@ mkSumTyCon name binders res_kind cons parent
-- right-hand side. It lives only during the type-checking of a
-- mutually-recursive group of tycons; it is then zonked to a proper
-- TyCon in zonkTcTyCon.
--- See also Note [Kind checking recursive type and class declarations]
--- in "GHC.Tc.TyCl".
+-- See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in "GHC.Tc.TyCl"
mkTcTyCon :: Name
-> [TyConBinder]
-> Kind -- ^ /result/ kind only
-> [(Name,TcTyVar)] -- ^ Scoped type variables;
- -- see Note [How TcTyCons work] in GHC.Tc.TyCl
-> Bool -- ^ Is this TcTyCon generalised already?
-> TyConFlavour -- ^ What sort of 'TyCon' this represents
-> TyCon
@@ -1988,7 +1991,7 @@ isInjectiveTyCon (TyCon { tyConDetails = details }) role
go (TcTyCon {}) _ = True
-- Reply True for TcTyCon to minimise knock on type errors
- -- See Note [How TcTyCons work] item (1) in GHC.Tc.TyCl
+ -- See (W1) in Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.TyCl
-- | 'isGenerativeTyCon' is true of 'TyCon's for which this property holds
diff --git a/compiler/GHC/Hs/Instances.hs b/compiler/GHC/Hs/Instances.hs
index 74d75fb7be..7ffd65c1c4 100644
--- a/compiler/GHC/Hs/Instances.hs
+++ b/compiler/GHC/Hs/Instances.hs
@@ -450,6 +450,11 @@ deriving instance (Data body) => Data (HsRecFields GhcTc body)
-- ---------------------------------------------------------------------
-- Data derivations from GHC.Hs.Type ----------------------------------
+-- deriving instance Data (HsBndrVis p)
+deriving instance Data (HsBndrVis GhcPs)
+deriving instance Data (HsBndrVis GhcRn)
+deriving instance Data (HsBndrVis GhcTc)
+
-- deriving instance (DataIdLR p p) => Data (LHsQTyVars p)
deriving instance Data (LHsQTyVars GhcPs)
deriving instance Data (LHsQTyVars GhcRn)
diff --git a/compiler/GHC/Hs/Type.hs b/compiler/GHC/Hs/Type.hs
index 313b8e8fe2..33ed0a20e6 100644
--- a/compiler/GHC/Hs/Type.hs
+++ b/compiler/GHC/Hs/Type.hs
@@ -32,6 +32,7 @@ module GHC.Hs.Type (
HsType(..), HsCoreTy, LHsType, HsKind, LHsKind,
HsForAllTelescope(..), EpAnnForallTy, HsTyVarBndr(..), LHsTyVarBndr,
+ HsBndrVis(..), isHsBndrInvisible,
LHsQTyVars(..),
HsOuterTyVarBndrs(..), HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs,
HsWildCardBndrs(..),
@@ -80,7 +81,7 @@ module GHC.Hs.Type (
mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy,
ignoreParens, hsSigWcType, hsPatSigType,
hsTyKindSig,
- setHsTyVarBndrFlag, hsTyVarBndrFlag,
+ setHsTyVarBndrFlag, hsTyVarBndrFlag, updateHsTyVarBndrFlag,
-- Printing
pprHsType, pprHsForAll,
@@ -184,7 +185,7 @@ mkHsForAllInvisTele :: EpAnnForallTy
mkHsForAllInvisTele an invis_bndrs =
HsForAllInvis { hsf_xinvis = an, hsf_invis_bndrs = invis_bndrs }
-mkHsQTvs :: [LHsTyVarBndr () GhcPs] -> LHsQTyVars GhcPs
+mkHsQTvs :: [LHsTyVarBndr (HsBndrVis GhcPs) GhcPs] -> LHsQTyVars GhcPs
mkHsQTvs tvs = HsQTvs { hsq_ext = noExtField, hsq_explicit = tvs }
emptyLHsQTvs :: LHsQTyVars GhcRn
@@ -285,6 +286,8 @@ type instance XXTyVarBndr (GhcPass _) = DataConCantHappen
hsTyVarBndrFlag :: HsTyVarBndr flag (GhcPass pass) -> flag
hsTyVarBndrFlag (UserTyVar _ fl _) = fl
hsTyVarBndrFlag (KindedTyVar _ fl _ _) = fl
+-- By specialising to (GhcPass p) we know that XXTyVarBndr is DataConCantHappen
+-- so these two equations are exhaustive: extension construction can't happen
-- | Set the attached flag
setHsTyVarBndrFlag :: flag -> HsTyVarBndr flag' (GhcPass pass)
@@ -292,6 +295,14 @@ setHsTyVarBndrFlag :: flag -> HsTyVarBndr flag' (GhcPass pass)
setHsTyVarBndrFlag f (UserTyVar x _ l) = UserTyVar x f l
setHsTyVarBndrFlag f (KindedTyVar x _ l k) = KindedTyVar x f l k
+-- | Update the attached flag
+updateHsTyVarBndrFlag
+ :: (flag -> flag')
+ -> HsTyVarBndr flag (GhcPass pass)
+ -> HsTyVarBndr flag' (GhcPass pass)
+updateHsTyVarBndrFlag f (UserTyVar x flag name) = UserTyVar x (f flag) name
+updateHsTyVarBndrFlag f (KindedTyVar x flag name ki) = KindedTyVar x (f flag) name ki
+
-- | Do all type variables in this 'LHsQTyVars' come with kind annotations?
hsTvbAllKinded :: LHsQTyVars (GhcPass p) -> Bool
hsTvbAllKinded = all (isHsKindedTyVar . unLoc) . hsQTvExplicit
@@ -964,6 +975,15 @@ instance OutputableBndrFlag Specificity p where
pprTyVarBndr (KindedTyVar _ SpecifiedSpec n k) = parens $ hsep [ppr n, dcolon, ppr k]
pprTyVarBndr (KindedTyVar _ InferredSpec n k) = braces $ hsep [ppr n, dcolon, ppr k]
+instance OutputableBndrFlag (HsBndrVis p') p where
+ pprTyVarBndr (UserTyVar _ vis n) = pprHsBndrVis vis $ ppr n
+ pprTyVarBndr (KindedTyVar _ vis n k) =
+ pprHsBndrVis vis $ parens $ hsep [ppr n, dcolon, ppr k]
+
+pprHsBndrVis :: HsBndrVis pass -> SDoc -> SDoc
+pprHsBndrVis HsBndrRequired d = d
+pprHsBndrVis (HsBndrInvisible _) d = char '@' <> d
+
instance OutputableBndrId p => Outputable (HsSigType (GhcPass p)) where
ppr (HsSig { sig_bndrs = outer_bndrs, sig_body = body }) =
pprHsOuterSigTyVarBndrs outer_bndrs <+> ppr body
diff --git a/compiler/GHC/HsToCore/Quote.hs b/compiler/GHC/HsToCore/Quote.hs
index 63094c21dd..88c0c727f5 100644
--- a/compiler/GHC/HsToCore/Quote.hs
+++ b/compiler/GHC/HsToCore/Quote.hs
@@ -2,6 +2,7 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
@@ -513,7 +514,7 @@ repKiSigD (L loc kisig) =
-------------------------
repDataDefn :: Core TH.Name
- -> Either (Core [(M (TH.TyVarBndr ()))])
+ -> Either (Core [(M (TH.TyVarBndr TH.BndrVis))])
-- the repTyClD case
(Core (Maybe [(M (TH.TyVarBndr ()))]), Core (M TH.Type))
-- the repDataFamInstD case
@@ -536,7 +537,7 @@ repDataDefn tc opts
derivs1 }
}
-repSynDecl :: Core TH.Name -> Core [(M (TH.TyVarBndr ()))]
+repSynDecl :: Core TH.Name -> Core [(M (TH.TyVarBndr TH.BndrVis))]
-> LHsType GhcRn
-> MetaM (Core (M TH.Dec))
repSynDecl tc bndrs ty
@@ -1179,6 +1180,17 @@ rep_flag :: Specificity -> MetaM (Core TH.Specificity)
rep_flag SpecifiedSpec = rep2_nw specifiedSpecName []
rep_flag InferredSpec = rep2_nw inferredSpecName []
+instance RepTV (HsBndrVis GhcRn) TH.BndrVis where
+ tyVarBndrName = tyVarBndrVisTyConName
+ repPlainTV (MkC nm) vis = do { (MkC vis') <- rep_bndr_vis vis
+ ; rep2 plainBndrTVName [nm, vis'] }
+ repKindedTV (MkC nm) vis (MkC ki) = do { (MkC vis') <- rep_bndr_vis vis
+ ; rep2 kindedBndrTVName [nm, vis', ki] }
+
+rep_bndr_vis :: HsBndrVis GhcRn -> MetaM (Core TH.BndrVis)
+rep_bndr_vis HsBndrRequired = rep2_nw bndrReqName []
+rep_bndr_vis (HsBndrInvisible _) = rep2_nw bndrInvisName []
+
addHsOuterFamEqnTyVarBinds ::
HsOuterFamEqnTyVarBndrs GhcRn
-> (Core (Maybe [M TH.TyVarBndrUnit]) -> MetaM (Core (M a)))
@@ -1284,7 +1296,7 @@ addHsTyVarBinds fresh_or_reuse exp_tvs thing_inside
addQTyVarBinds :: FreshOrReuse
-> LHsQTyVars GhcRn -- the binders to be added
- -> (Core [(M (TH.TyVarBndr ()))] -> MetaM (Core (M a))) -- action in the ext env
+ -> (Core [(M (TH.TyVarBndr TH.BndrVis))] -> MetaM (Core (M a))) -- action in the ext env
-> MetaM (Core (M a))
addQTyVarBinds fresh_or_reuse qtvs thing_inside =
let HsQTvs { hsq_ext = imp_tvs
@@ -2537,7 +2549,7 @@ repFun (MkC nm) (MkC b) = rep2 funDName [nm, b]
repData :: Bool -- ^ @True@ for a @type data@ declaration.
-- See Note [Type data declarations] in GHC.Rename.Module
-> Core (M TH.Cxt) -> Core TH.Name
- -> Either (Core [(M (TH.TyVarBndr ()))])
+ -> Either (Core [(M (TH.TyVarBndr TH.BndrVis))])
(Core (Maybe [(M (TH.TyVarBndr ()))]), Core (M TH.Type))
-> Core (Maybe (M TH.Kind)) -> Core [(M TH.Con)] -> Core [M TH.DerivClause]
-> MetaM (Core (M TH.Dec))
@@ -2549,7 +2561,7 @@ repData _ (MkC cxt) (MkC _) (Right (MkC mb_bndrs, MkC ty)) (MkC ksig) (MkC cons)
= rep2 dataInstDName [cxt, mb_bndrs, ty, ksig, cons, derivs]
repNewtype :: Core (M TH.Cxt) -> Core TH.Name
- -> Either (Core [(M (TH.TyVarBndr ()))])
+ -> Either (Core [(M (TH.TyVarBndr TH.BndrVis))])
(Core (Maybe [(M (TH.TyVarBndr ()))]), Core (M TH.Type))
-> Core (Maybe (M TH.Kind)) -> Core (M TH.Con) -> Core [M TH.DerivClause]
-> MetaM (Core (M TH.Dec))
@@ -2560,7 +2572,7 @@ repNewtype (MkC cxt) (MkC _) (Right (MkC mb_bndrs, MkC ty)) (MkC ksig) (MkC con)
(MkC derivs)
= rep2 newtypeInstDName [cxt, mb_bndrs, ty, ksig, con, derivs]
-repTySyn :: Core TH.Name -> Core [(M (TH.TyVarBndr ()))]
+repTySyn :: Core TH.Name -> Core [(M (TH.TyVarBndr TH.BndrVis))]
-> Core (M TH.Type) -> MetaM (Core (M TH.Dec))
repTySyn (MkC nm) (MkC tvs) (MkC rhs)
= rep2 tySynDName [nm, tvs, rhs]
@@ -2618,7 +2630,7 @@ repOverlap mb =
just = coreJust overlapTyConName
-repClass :: Core (M TH.Cxt) -> Core TH.Name -> Core [(M (TH.TyVarBndr ()))]
+repClass :: Core (M TH.Cxt) -> Core TH.Name -> Core [(M (TH.TyVarBndr TH.BndrVis))]
-> Core [TH.FunDep] -> Core [(M TH.Dec)]
-> MetaM (Core (M TH.Dec))
repClass (MkC cxt) (MkC cls) (MkC tvs) (MkC fds) (MkC ds)
@@ -2667,13 +2679,13 @@ repTySynInst :: Core (M TH.TySynEqn) -> MetaM (Core (M TH.Dec))
repTySynInst (MkC eqn)
= rep2 tySynInstDName [eqn]
-repDataFamilyD :: Core TH.Name -> Core [(M (TH.TyVarBndr ()))]
+repDataFamilyD :: Core TH.Name -> Core [(M (TH.TyVarBndr TH.BndrVis))]
-> Core (Maybe (M TH.Kind)) -> MetaM (Core (M TH.Dec))
repDataFamilyD (MkC nm) (MkC tvs) (MkC kind)
= rep2 dataFamilyDName [nm, tvs, kind]
repOpenFamilyD :: Core TH.Name
- -> Core [(M (TH.TyVarBndr ()))]
+ -> Core [(M (TH.TyVarBndr TH.BndrVis))]
-> Core (M TH.FamilyResultSig)
-> Core (Maybe TH.InjectivityAnn)
-> MetaM (Core (M TH.Dec))
@@ -2681,7 +2693,7 @@ repOpenFamilyD (MkC nm) (MkC tvs) (MkC result) (MkC inj)
= rep2 openTypeFamilyDName [nm, tvs, result, inj]
repClosedFamilyD :: Core TH.Name
- -> Core [(M (TH.TyVarBndr ()))]
+ -> Core [(M (TH.TyVarBndr TH.BndrVis))]
-> Core (M TH.FamilyResultSig)
-> Core (Maybe TH.InjectivityAnn)
-> Core [(M TH.TySynEqn)]
diff --git a/compiler/GHC/Parser/Errors/Ppr.hs b/compiler/GHC/Parser/Errors/Ppr.hs
index aadb2a0a79..b54f64eb93 100644
--- a/compiler/GHC/Parser/Errors/Ppr.hs
+++ b/compiler/GHC/Parser/Errors/Ppr.hs
@@ -430,14 +430,6 @@ instance Diagnostic PsMessage where
-> mkSimpleDecorated $
text "Malformed" <+> what
<+> text "declaration for" <+> quotes (ppr for)
- PsErrUnexpectedTypeAppInDecl ki what for
- -> mkSimpleDecorated $
- vcat [ text "Unexpected type application"
- <+> text "@" <> ppr ki
- , text "In the" <+> what
- <+> text "declaration for"
- <+> quotes (ppr for)
- ]
PsErrNotADataCon name
-> mkSimpleDecorated $ text "Not a data constructor:" <+> quotes (ppr name)
PsErrInferredTypeVarNotAllowed
@@ -626,7 +618,6 @@ instance Diagnostic PsMessage where
PsErrAtInPatPos -> ErrorWithoutFlag
PsErrParseErrorOnInput{} -> ErrorWithoutFlag
PsErrMalformedDecl{} -> ErrorWithoutFlag
- PsErrUnexpectedTypeAppInDecl{} -> ErrorWithoutFlag
PsErrNotADataCon{} -> ErrorWithoutFlag
PsErrInferredTypeVarNotAllowed -> ErrorWithoutFlag
PsErrIllegalTraditionalRecordSyntax{} -> ErrorWithoutFlag
@@ -767,7 +758,6 @@ instance Diagnostic PsMessage where
PsErrAtInPatPos -> noHints
PsErrParseErrorOnInput{} -> noHints
PsErrMalformedDecl{} -> noHints
- PsErrUnexpectedTypeAppInDecl{} -> noHints
PsErrNotADataCon{} -> noHints
PsErrInferredTypeVarNotAllowed -> noHints
PsErrIllegalTraditionalRecordSyntax{} -> [suggestExtension LangExt.TraditionalRecordSyntax]
diff --git a/compiler/GHC/Parser/Errors/Types.hs b/compiler/GHC/Parser/Errors/Types.hs
index 87f7f8d509..d9e8a4dbdd 100644
--- a/compiler/GHC/Parser/Errors/Types.hs
+++ b/compiler/GHC/Parser/Errors/Types.hs
@@ -367,9 +367,6 @@ data PsMessage
-- | Malformed ... declaration for ...
| PsErrMalformedDecl !SDoc !RdrName
- -- | Unexpected type application in a declaration
- | PsErrUnexpectedTypeAppInDecl !(LHsType GhcPs) !SDoc !RdrName
-
-- | Not a data constructor
| PsErrNotADataCon !RdrName
diff --git a/compiler/GHC/Parser/PostProcess.hs b/compiler/GHC/Parser/PostProcess.hs
index 48e4320faf..890133ff6d 100644
--- a/compiler/GHC/Parser/PostProcess.hs
+++ b/compiler/GHC/Parser/PostProcess.hs
@@ -890,38 +890,37 @@ checkTyVars pp_what equals_or_where tc tparms
= do { tvs <- mapM check tparms
; return (mkHsQTvs tvs) }
where
- check (HsTypeArg _ ki@(L loc _)) = addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
- (PsErrUnexpectedTypeAppInDecl ki pp_what (unLoc tc))
- check (HsValArg ty) = chkParens [] [] emptyComments ty
+ check (HsTypeArg at ki) = chkParens [] [] emptyComments (HsBndrInvisible at) ki
+ check (HsValArg ty) = chkParens [] [] emptyComments HsBndrRequired ty
check (HsArgPar sp) = addFatalError $ mkPlainErrorMsgEnvelope sp $
(PsErrMalformedDecl pp_what (unLoc tc))
-- Keep around an action for adjusting the annotations of extra parens
- chkParens :: [AddEpAnn] -> [AddEpAnn] -> EpAnnComments -> LHsType GhcPs
- -> P (LHsTyVarBndr () GhcPs)
- chkParens ops cps cs (L l (HsParTy an ty))
+ chkParens :: [AddEpAnn] -> [AddEpAnn] -> EpAnnComments -> HsBndrVis GhcPs -> LHsType GhcPs
+ -> P (LHsTyVarBndr (HsBndrVis GhcPs) GhcPs)
+ chkParens ops cps cs bvis (L l (HsParTy an ty))
= let
(o,c) = mkParensEpAnn (realSrcSpan $ locA l)
in
- chkParens (o:ops) (c:cps) (cs Semi.<> epAnnComments an) ty
- chkParens ops cps cs ty = chk ops cps cs ty
+ chkParens (o:ops) (c:cps) (cs Semi.<> epAnnComments an) bvis ty
+ chkParens ops cps cs bvis ty = chk ops cps cs bvis ty
-- Check that the name space is correct!
- chk :: [AddEpAnn] -> [AddEpAnn] -> EpAnnComments -> LHsType GhcPs -> P (LHsTyVarBndr () GhcPs)
- chk ops cps cs (L l (HsKindSig annk (L annt (HsTyVar ann _ (L lv tv))) k))
+ chk :: [AddEpAnn] -> [AddEpAnn] -> EpAnnComments -> HsBndrVis GhcPs -> LHsType GhcPs -> P (LHsTyVarBndr (HsBndrVis GhcPs) GhcPs)
+ chk ops cps cs bvis (L l (HsKindSig annk (L annt (HsTyVar ann _ (L lv tv))) k))
| isRdrTyVar tv
= let
an = (reverse ops) ++ cps
in
return (L (widenLocatedAn (l Semi.<> annt) an)
- (KindedTyVar (addAnns (annk Semi.<> ann) an cs) () (L lv tv) k))
- chk ops cps cs (L l (HsTyVar ann _ (L ltv tv)))
+ (KindedTyVar (addAnns (annk Semi.<> ann) an cs) bvis (L lv tv) k))
+ chk ops cps cs bvis (L l (HsTyVar ann _ (L ltv tv)))
| isRdrTyVar tv
= let
an = (reverse ops) ++ cps
in
return (L (widenLocatedAn l an)
- (UserTyVar (addAnns ann an cs) () (L ltv tv)))
- chk _ _ _ t@(L loc _)
+ (UserTyVar (addAnns ann an cs) bvis (L ltv tv)))
+ chk _ _ _ _ t@(L loc _)
= addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
(PsErrUnexpectedTypeInDecl t pp_what (unLoc tc) tparms equals_or_where)
diff --git a/compiler/GHC/Rename/HsType.hs b/compiler/GHC/Rename/HsType.hs
index f9720a53e1..519b1ce318 100644
--- a/compiler/GHC/Rename/HsType.hs
+++ b/compiler/GHC/Rename/HsType.hs
@@ -975,7 +975,8 @@ bindHsQTyVars doc mb_assoc body_kv_occs hsq_bndrs thing_inside
-- This is the only call site for bindLHsTyVarBndrs where we pass
-- NoWarnUnusedForalls, which suppresses -Wunused-foralls warnings.
-- See Note [Suppress -Wunused-foralls when binding LHsQTyVars].
- do { let -- The SrcSpan that rnImplicitTvOccs will attach to each Name will
+ do { rn_bndrs <- traverse rnLHsTyVarBndrVisFlag rn_bndrs
+ ; let -- The SrcSpan that rnImplicitTvOccs will attach to each Name will
-- span the entire declaration to which the LHsQTyVars belongs,
-- which will be reflected in warning and error messages. We can
-- be a little more precise than that by pointing to the location
@@ -1003,7 +1004,7 @@ bindHsQTyVars doc mb_assoc body_kv_occs hsq_bndrs thing_inside
-- The in-tree API annotations extend the LHsTyVarBndr location to
-- include surrounding parens. for error messages to be
-- compatible, we recreate the location from the contents
- get_bndr_loc :: LHsTyVarBndr () GhcPs -> SrcSpan
+ get_bndr_loc :: LHsTyVarBndr flag GhcPs -> SrcSpan
get_bndr_loc (L _ (UserTyVar _ _ ln)) = getLocA ln
get_bndr_loc (L _ (KindedTyVar _ _ ln lk))
= combineSrcSpans (getLocA ln) (getLocA lk)
@@ -1239,6 +1240,25 @@ bindLHsTyVarBndr doc mb_assoc (L loc (KindedTyVar x fl lrdr@(L lv _) kind))
$ thing_inside (L loc (KindedTyVar x fl (L lv tv_nm) kind'))
; return (b, fvs1 `plusFV` fvs2) }
+-- Check for TypeAbstractions and update the type parameter of HsBndrVis.
+-- The binder itself is already renamed and is returned unmodified.
+rnLHsTyVarBndrVisFlag
+ :: LHsTyVarBndr (HsBndrVis GhcPs) GhcRn
+ -> RnM (LHsTyVarBndr (HsBndrVis GhcRn) GhcRn)
+rnLHsTyVarBndrVisFlag (L loc bndr) = do
+ let lbndr = L loc (updateHsTyVarBndrFlag rnHsBndrVis bndr)
+ unlessXOptM LangExt.TypeAbstractions $
+ when (isHsBndrInvisible (hsTyVarBndrFlag bndr)) $
+ addErr (TcRnIllegalInvisTyVarBndr lbndr)
+ return lbndr
+
+-- rnHsBndrVis is a no-op. We could use 'coerce' in an ideal world,
+-- but GHC can't crack this nut because type families are involved:
+-- HsBndrInvisible stores (LHsToken "@" pass), which is defined via XRec.
+rnHsBndrVis :: HsBndrVis GhcPs -> HsBndrVis GhcRn
+rnHsBndrVis HsBndrRequired = HsBndrRequired
+rnHsBndrVis (HsBndrInvisible at) = HsBndrInvisible at
+
newTyVarNameRn :: Maybe a -- associated class
-> LocatedN RdrName -> RnM Name
newTyVarNameRn mb_assoc lrdr@(L _ rdr)
diff --git a/compiler/GHC/Tc/Errors/Ppr.hs b/compiler/GHC/Tc/Errors/Ppr.hs
index 9880c13a9c..aba12a139f 100644
--- a/compiler/GHC/Tc/Errors/Ppr.hs
+++ b/compiler/GHC/Tc/Errors/Ppr.hs
@@ -1307,6 +1307,30 @@ instance Diagnostic TcRnMessage where
sigs = sig1 : sig2 : otherSigs
+ TcRnIllegalInvisTyVarBndr bndr ->
+ mkSimpleDecorated $
+ hang (text "Illegal invisible type variable binder:")
+ 2 (ppr bndr)
+
+ TcRnInvalidInvisTyVarBndr name hs_bndr ->
+ mkSimpleDecorated $
+ vcat [ hang (text "Invalid invisible type variable binder:")
+ 2 (ppr hs_bndr)
+ , text "There is no matching forall-bound variable"
+ , text "in the standalone kind signature for" <+> quotes (ppr name) <> dot
+ , text "NB." <+> vcat [
+ text "Only" <+> quotes (text "forall a.") <+> text "-quantification matches invisible binders,",
+ text "whereas" <+> quotes (text "forall {a}.") <+> text "and" <+> quotes (text "forall a ->") <+> text "do not."
+ ]]
+
+ TcRnInvisBndrWithoutSig _ hs_bndr ->
+ mkSimpleDecorated $
+ vcat [ hang (text "Invalid invisible type variable binder:")
+ 2 (ppr hs_bndr)
+ , text "Either a standalone kind signature (SAKS)"
+ , text "or a complete user-supplied kind (CUSK, legacy feature)"
+ , text "is required to use invisible binders." ]
+
diagnosticReason = \case
TcRnUnknownMessage m
-> diagnosticReason m
@@ -1734,6 +1758,12 @@ instance Diagnostic TcRnMessage where
-> ErrorWithoutFlag
TcRnDuplicateMinimalSig{}
-> ErrorWithoutFlag
+ TcRnIllegalInvisTyVarBndr{}
+ -> ErrorWithoutFlag
+ TcRnInvalidInvisTyVarBndr{}
+ -> ErrorWithoutFlag
+ TcRnInvisBndrWithoutSig{}
+ -> ErrorWithoutFlag
diagnosticHints = \case
TcRnUnknownMessage m
@@ -2173,6 +2203,12 @@ instance Diagnostic TcRnMessage where
-> noHints
TcRnDuplicateMinimalSig{}
-> noHints
+ TcRnIllegalInvisTyVarBndr{}
+ -> [suggestExtension LangExt.TypeAbstractions]
+ TcRnInvalidInvisTyVarBndr{}
+ -> noHints
+ TcRnInvisBndrWithoutSig name _
+ -> [SuggestAddStandaloneKindSignature name]
diagnosticCode = constructorCode
diff --git a/compiler/GHC/Tc/Errors/Types.hs b/compiler/GHC/Tc/Errors/Types.hs
index c1b8461839..7166828ef5 100644
--- a/compiler/GHC/Tc/Errors/Types.hs
+++ b/compiler/GHC/Tc/Errors/Types.hs
@@ -2011,7 +2011,7 @@ data TcRnMessage where
Test cases: saks/should_fail/saks_fail008
-}
- TcRnTooManyBinders :: !Kind -> ![LHsTyVarBndr () GhcRn] -> TcRnMessage
+ TcRnTooManyBinders :: !Kind -> ![LHsTyVarBndr (HsBndrVis GhcRn) GhcRn] -> TcRnMessage
{- TcRnDifferentNamesForTyVar is an error that indicates different names being
used for the same type variable.
@@ -2923,6 +2923,49 @@ data TcRnMessage where
Test cases: rename/should_fail/RnMultipleMinimalPragmaFail
-}
TcRnDuplicateMinimalSig :: LSig GhcPs -> LSig GhcPs -> [LSig GhcPs] -> TcRnMessage
+ {-| 'TcRnIllegalInvisTyVarBndr' is an error that occurs
+ when invisible type variable binders in type declarations
+ are used without enabling the @TypeAbstractions@ extension.
+
+ Example:
+ {-# LANGUAGE NoTypeAbstractions #-} -- extension disabled
+ data T @k (a :: k) @(j :: Type) (b :: j)
+ ^^ ^^^^^^^^^^^^
+
+ Test case: T22560_fail_ext
+ -}
+ TcRnIllegalInvisTyVarBndr
+ :: !(LHsTyVarBndr (HsBndrVis GhcRn) GhcRn)
+ -> TcRnMessage
+
+ {-| 'TcRnInvalidInvisTyVarBndr' is an error that occurs
+ when an invisible type variable binder has no corresponding
+ @forall k.@ quantifier in the standalone kind signature.
+
+ Example:
+ type P :: forall a -> Type
+ data P @a = MkP
+
+ Test cases: T22560_fail_a T22560_fail_b
+ -}
+ TcRnInvalidInvisTyVarBndr
+ :: !Name
+ -> !(LHsTyVarBndr (HsBndrVis GhcRn) GhcRn)
+ -> TcRnMessage
+
+ {-| 'TcRnInvisBndrWithoutSig' is an error triggered by attempting to use
+ an invisible type variable binder in a type declaration without a
+ standalone kind signature or a complete user-supplied kind.
+
+ Example:
+ data T @k (a :: k) -- No CUSK, no SAKS
+
+ Test case: T22560_fail_d
+ -}
+ TcRnInvisBndrWithoutSig
+ :: !Name
+ -> !(LHsTyVarBndr (HsBndrVis GhcRn) GhcRn)
+ -> TcRnMessage
deriving Generic
diff --git a/compiler/GHC/Tc/Gen/HsType.hs b/compiler/GHC/Tc/Gen/HsType.hs
index bf15393048..01d5df6782 100644
--- a/compiler/GHC/Tc/Gen/HsType.hs
+++ b/compiler/GHC/Tc/Gen/HsType.hs
@@ -2304,10 +2304,10 @@ data InitialKindStrategy
| InitialKindInfer
-- Does the declaration have a standalone kind signature (SAKS) or a complete
--- user-specified kind (CUSK)?
+-- user-supplied kind (CUSK)?
data SAKS_or_CUSK
= SAKS Kind -- Standalone kind signature, fully zonked! (zonkTcTypeToType)
- | CUSK -- Complete user-specified kind (CUSK)
+ | CUSK -- Complete user-supplied kind (CUSK)
instance Outputable SAKS_or_CUSK where
ppr (SAKS k) = text "SAKS" <+> ppr k
@@ -2364,7 +2364,7 @@ kcCheckDeclHeader_cusk name flav
-- See Note [Required, Specified, and Inferred for types] in GHC.Tc.TyCl
= addTyConFlavCtxt name flav $
do { skol_info <- mkSkolemInfo skol_info_anon
- ; (tclvl, wanted, (scoped_kvs, (tc_tvs, res_kind)))
+ ; (tclvl, wanted, (scoped_kvs, (tc_bndrs, res_kind)))
<- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_cusk" $
bindImplicitTKBndrs_Q_Skol skol_info kv_ns $
bindExplicitTKBndrs_Q_Skol skol_info ctxt_kind hs_tvs $
@@ -2372,7 +2372,7 @@ kcCheckDeclHeader_cusk name flav
-- Now, because we're in a CUSK,
-- we quantify over the mentioned kind vars
- ; let spec_req_tkvs = scoped_kvs ++ tc_tvs
+ ; let spec_req_tkvs = scoped_kvs ++ binderVars tc_bndrs
all_kinds = res_kind : map tyVarKind spec_req_tkvs
; candidates <- candidateQTyVarsOfKinds all_kinds
@@ -2384,9 +2384,9 @@ kcCheckDeclHeader_cusk name flav
candidates `delCandidates` spec_req_tkvs
-- NB: 'inferred' comes back sorted in dependency order
- ; scoped_kvs <- mapM zonkTyCoVarKind scoped_kvs -- scoped_kvs and tc_tvs are skolems,
- ; tc_tvs <- mapM zonkTyCoVarKind tc_tvs -- so zonkTyCoVarKind suffices
- ; res_kind <- zonkTcType res_kind
+ ; scoped_kvs <- mapM zonkTyCoVarKind scoped_kvs -- scoped_kvs and tc_bndrs are skolems,
+ ; tc_bndrs <- mapM zonkTyCoVarBndrKind tc_bndrs -- so zonkTyCoVarKind suffices
+ ; res_kind <- zonkTcType res_kind
; let mentioned_kv_set = candidateKindVars candidates
specified = scopedSort scoped_kvs
@@ -2394,15 +2394,15 @@ kcCheckDeclHeader_cusk name flav
all_tcbs = mkNamedTyConBinders Inferred inferred
++ mkNamedTyConBinders Specified specified
- ++ map (mkRequiredTyConBinder mentioned_kv_set) tc_tvs
+ ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs
-- Eta expand if necessary; we are building a PolyTyCon
; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind
- ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ tc_tvs)
+ ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs)
final_tcbs = all_tcbs `chkAppend` eta_tcbs
tycon = mkTcTyCon name final_tcbs res_kind all_tv_prs
- True -- it is generalised
+ True -- Make a PolyTcTyCon, fully generalised
flav
; reportUnsolvedEqualities skol_info (binderVars final_tcbs)
@@ -2422,7 +2422,7 @@ kcCheckDeclHeader_cusk name flav
, text "scoped_kvs" <+> ppr scoped_kvs
, text "spec_req_tvs" <+> pprTyVars spec_req_tkvs
, text "all_kinds" <+> ppr all_kinds
- , text "tc_tvs" <+> pprTyVars tc_tvs
+ , text "tc_tvs" <+> pprTyVars (binderVars tc_bndrs)
, text "res_kind" <+> ppr res_kind
, text "inferred" <+> ppr inferred
, text "specified" <+> ppr specified
@@ -2437,6 +2437,15 @@ kcCheckDeclHeader_cusk name flav
ctxt_kind | tcFlavourIsOpen flav = TheKind liftedTypeKind
| otherwise = AnyKind
+-- | Create a TyConBinder for a user-written type variable binder.
+mkExplicitTyConBinder :: TyCoVarSet -- variables that are used dependently
+ -> VarBndr TyVar (HsBndrVis GhcRn)
+ -> TyConBinder
+mkExplicitTyConBinder dep_set (Bndr tv flag) =
+ case flag of
+ HsBndrRequired -> mkRequiredTyConBinder dep_set tv
+ HsBndrInvisible{} -> mkNamedTyConBinder Specified tv
+
-- | Kind-check a 'LHsQTyVars'. Used in 'inferInitialKind' (for tycon kinds and
-- other kinds).
--
@@ -2449,15 +2458,16 @@ kcInferDeclHeader
-> TcM MonoTcTyCon -- ^ A suitably-kinded non-generalized TcTyCon
kcInferDeclHeader name flav
(HsQTvs { hsq_ext = kv_ns
- , hsq_explicit = hs_tvs }) kc_res_ki
+ , hsq_explicit = hs_bndrs }) kc_res_ki
-- No standalone kind signature and no CUSK.
-- See Note [Required, Specified, and Inferred for types] in GHC.Tc.TyCl
= addTyConFlavCtxt name flav $
- do { (scoped_kvs, (tc_tvs, res_kind))
+ do { rejectInvisibleBinders name hs_bndrs
+ ; (scoped_kvs, (tc_bndrs, res_kind))
-- Why bindImplicitTKBndrs_Q_Tv which uses newTyVarTyVar?
-- See Note [Inferring kinds for type declarations] in GHC.Tc.TyCl
- <- bindImplicitTKBndrs_Q_Tv kv_ns $
- bindExplicitTKBndrs_Q_Tv ctxt_kind hs_tvs $
+ <- bindImplicitTKBndrs_Q_Tv kv_ns $
+ bindExplicitTKBndrs_Q_Tv ctxt_kind hs_bndrs $
newExpectedKind =<< kc_res_ki
-- Why "_Tv" not "_Skol"? See third wrinkle in
-- Note [Inferring kinds for type declarations] in GHC.Tc.TyCl,
@@ -2467,12 +2477,17 @@ kcInferDeclHeader name flav
-- recursive group.
-- See Note [Inferring kinds for type declarations] in GHC.Tc.TyCl
+ tc_tvs = binderVars tc_bndrs
+ -- Discard visibility flags. We made sure all of them are HsBndrRequired
+ -- by the call to rejectInvisibleBinders above.
+
tc_binders = mkAnonTyConBinders tc_tvs
- -- Also, note that tc_binders has the tyvars from only the
- -- user-written tyvarbinders. See S1 in Note [How TcTyCons work]
- -- in GHC.Tc.TyCl
+ -- This has to be mkAnonTyConBinder!
+ -- See Note [No polymorphic recursion in type decls] in GHC.Tc.TyCl
--
- -- mkAnonTyConBinder: see Note [No polymorphic recursion]
+ -- Also, note that tc_binders has the tyvars from only the
+ -- user-written type variable binders.
+ -- See S1 Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.TyCl
all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ tc_tvs)
-- NB: bindExplicitTKBndrs_Q_Tv does not clone;
@@ -2480,11 +2495,11 @@ kcInferDeclHeader name flav
-- See Note [Cloning for type variable binders]
tycon = mkTcTyCon name tc_binders res_kind all_tv_prs
- False -- not yet generalised
+ False -- Make a MonoTcTyCon
flav
; traceTc "kcInferDeclHeader: not-cusk" $
- vcat [ ppr name, ppr kv_ns, ppr hs_tvs
+ vcat [ ppr name, ppr kv_ns, ppr hs_bndrs
, ppr scoped_kvs
, ppr tc_tvs, ppr (mkTyConKind tc_binders res_kind) ]
; return tycon }
@@ -2492,6 +2507,17 @@ kcInferDeclHeader name flav
ctxt_kind | tcFlavourIsOpen flav = TheKind liftedTypeKind
| otherwise = AnyKind
+-- rejectInvisibleBinders is called on on the inference code path; there is
+-- no standalone kind signature, nor CUSK.
+-- See Note [No inference for invisible binders in type decls] in GHC.Tc.TyCl
+rejectInvisibleBinders :: Name -> [LHsTyVarBndr (HsBndrVis GhcRn) GhcRn] -> TcM ()
+rejectInvisibleBinders name = mapM_ check_bndr_vis
+ where
+ check_bndr_vis :: LHsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcM ()
+ check_bndr_vis bndr =
+ when (isHsBndrInvisible (hsTyVarBndrFlag (unLoc bndr))) $
+ addErr (TcRnInvisBndrWithoutSig name bndr)
+
-- | Kind-check a declaration header against a standalone kind signature.
-- See Note [kcCheckDeclHeader_sig]
kcCheckDeclHeader_sig
@@ -2521,7 +2547,7 @@ kcCheckDeclHeader_sig sig_kind name flav
; (tclvl, wanted, (implicit_tvs, (skol_tcbs, (extra_tcbs, tycon_res_kind))))
<- pushLevelAndSolveEqualitiesX "kcCheckDeclHeader_sig" $ -- #16687
bindImplicitTKBndrs_Q_Tv implicit_nms $ -- Q means don't clone
- matchUpSigWithDecl sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind ->
+ matchUpSigWithDecl name sig_tcbs sig_res_kind hs_tv_bndrs $ \ excess_sig_tcbs sig_res_kind ->
do { -- Kind-check the result kind annotation, if present:
-- data T a b :: res_ki where ...
-- ^^^^^^^^^
@@ -2600,7 +2626,9 @@ kcCheckDeclHeader_sig sig_kind name flav
-- NB: all_tcbs must bind the tyvars in the range of all_tv_prs
-- because the tv_prs is used when (say) typechecking the RHS of
-- a type synonym.
- ; let tc = mkTcTyCon name swizzled_tcbs swizzled_kind all_tv_prs True flav
+ ; let tc = mkTcTyCon name swizzled_tcbs swizzled_kind all_tv_prs
+ True -- Make a PolyTcTyCon, fully generalised
+ flav
; traceTc "kcCheckDeclHeader_sig }" $ vcat
[ text "tyConName = " <+> ppr (tyConName tc)
@@ -2612,9 +2640,10 @@ kcCheckDeclHeader_sig sig_kind name flav
; return tc }
matchUpSigWithDecl
- :: [TcTyConBinder] -- TcTyConBinders (with skolem TcTyVars) from the separate kind signature
+ :: Name -- Name of the type constructor for error messages
+ -> [TcTyConBinder] -- TcTyConBinders (with skolem TcTyVars) from the separate kind signature
-> TcKind -- The tail end of the kind signature
- -> [LHsTyVarBndr () GhcRn] -- User-written binders in decl
+ -> [LHsTyVarBndr (HsBndrVis GhcRn) GhcRn] -- User-written binders in decl
-> ([TcTyConBinder] -> TcKind -> TcM a) -- All user-written binders are in scope
-- Argument is excess TyConBinders and tail kind
-> TcM ( [TcTyConBinder] -- Skolemised binders, with TcTyVars
@@ -2622,7 +2651,7 @@ matchUpSigWithDecl
-- See Note [Matching a kind signature with a declaration]
-- Invariant: Length of returned TyConBinders + length of excess TyConBinders
-- = length of incoming TyConBinders
-matchUpSigWithDecl sig_tcbs sig_res_kind hs_bndrs thing_inside
+matchUpSigWithDecl name sig_tcbs sig_res_kind hs_bndrs thing_inside
= go emptySubst sig_tcbs hs_bndrs
where
go subst tcbs []
@@ -2633,23 +2662,22 @@ matchUpSigWithDecl sig_tcbs sig_res_kind hs_bndrs thing_inside
go _ [] hs_bndrs
= failWithTc (TcRnTooManyBinders sig_res_kind hs_bndrs)
- go subst (tcb : tcbs') hs_bndrs
- | Bndr tv vis <- tcb
- , isVisibleTcbVis vis
- , (L _ hs_bndr : hs_bndrs') <- hs_bndrs -- hs_bndrs is non-empty
+ go subst (tcb : tcbs') hs_bndrs@(hs_bndr : hs_bndrs')
+ | zippable (binderFlag tcb) (hsTyVarBndrFlag (unLoc hs_bndr))
= -- Visible TyConBinder, so match up with the hs_bndrs
- do { let tv' = updateTyVarKind (substTy subst) $
+ do { let Bndr tv vis = tcb
+ tv' = updateTyVarKind (substTy subst) $
setTyVarName tv (getName hs_bndr)
-- Give the skolem the Name of the HsTyVarBndr, so that if it
-- appears in an error message it has a name and binding site
-- that come from the type declaration, not the kind signature
subst' = extendTCvSubstWithClone subst tv tv'
- ; tc_hs_bndr hs_bndr (tyVarKind tv')
+ ; tc_hs_bndr (unLoc hs_bndr) (tyVarKind tv')
; (tcbs', res) <- tcExtendTyVarEnv [tv'] $
go subst' tcbs' hs_bndrs'
; return (Bndr tv' vis : tcbs', res) }
- | otherwise
+ | skippable (binderFlag tcb)
= -- Invisible TyConBinder, so do not consume one of the hs_bndrs
do { let (subst', tcb') = substTyConBinderX subst tcb
; (tcbs', res) <- go subst' tcbs' hs_bndrs
@@ -2657,7 +2685,14 @@ matchUpSigWithDecl sig_tcbs sig_res_kind hs_bndrs thing_inside
-- HsTyVarBndr for an invisible TyConBinder
; return (tcb' : tcbs', res) }
- tc_hs_bndr :: HsTyVarBndr () GhcRn -> TcKind -> TcM ()
+ | otherwise =
+ -- At this point we conclude that:
+ -- * the quantifier (tcb) is visible: (ty -> ...), (forall a -> ...)
+ -- * the binder (hs_bndr) is invisible: @t, @(t :: k)
+ -- Any other combination should have been handled by the zippable/skippable clauses.
+ failWithTc (TcRnInvalidInvisTyVarBndr name hs_bndr)
+
+ tc_hs_bndr :: HsTyVarBndr (HsBndrVis GhcRn) GhcRn -> TcKind -> TcM ()
tc_hs_bndr (UserTyVar _ _ _) _
= return ()
tc_hs_bndr (KindedTyVar _ _ (L _ hs_nm) lhs_kind) expected_kind
@@ -2665,6 +2700,17 @@ matchUpSigWithDecl sig_tcbs sig_res_kind hs_bndrs thing_inside
; discardResult $ -- See Note [discardResult in kcCheckDeclHeader_sig]
unifyKind (Just (NameThing hs_nm)) sig_kind expected_kind }
+ -- See GHC Proposal #425, section "Kind checking",
+ -- where zippable and skippable are defined.
+ zippable :: TyConBndrVis -> HsBndrVis GhcRn -> Bool
+ zippable vis HsBndrRequired = isVisibleTcbVis vis
+ zippable vis (HsBndrInvisible _) = isInvisSpecTcbVis vis
+
+ -- See GHC Proposal #425, section "Kind checking",
+ -- where zippable and skippable are defined.
+ skippable :: TyConBndrVis -> Bool
+ skippable vis = not (isVisibleTcbVis vis)
+
substTyConBinderX :: Subst -> TyConBinder -> (Subst, TyConBinder)
substTyConBinderX subst (Bndr tv vis)
= (subst', Bndr tv' vis)
@@ -2704,7 +2750,7 @@ Basic plan is this:
NB: these TyConBinders contain TyVars, not TcTyVars.
* matchUpSigWithDecl: match the [TyConBinder] from the signature with
- the [LHsTyVarBndr () GhcRn] from the declaration. The latter are the
+ the [LHsTyVarBndr (HsBndrVis GhcRn) GhcRn] from the declaration. The latter are the
explicit, user-written binders. e.g.
data T (a :: k) b = ....
There may be more of the former than the latter, because the former
@@ -2853,54 +2899,6 @@ signature, not by the inline kind annotation:
This (Id Bool) will not show up anywhere after we're done validating it, so we
have no use for the produced coercion.
--}
-
-{- Note [No polymorphic recursion]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Should this kind-check?
- data T ka (a::ka) b = MkT (T Type Int Bool)
- (T (Type -> Type) Maybe Bool)
-
-Notice that T is used at two different kinds in its RHS. No!
-This should not kind-check. Polymorphic recursion is known to
-be a tough nut.
-
-Previously, we laboriously (with help from the renamer)
-tried to give T the polymorphic kind
- T :: forall ka -> ka -> kappa -> Type
-where kappa is a unification variable, even in the inferInitialKinds
-phase (which is what kcInferDeclHeader is all about). But
-that is dangerously fragile (see the ticket).
-
-Solution: make kcInferDeclHeader give T a straightforward
-monomorphic kind, with no quantification whatsoever. That's why
-we use mkAnonTyConBinder for all arguments when figuring out
-tc_binders.
-
-But notice that (#16322 comment:3)
-
-* The algorithm successfully kind-checks this declaration:
- data T2 ka (a::ka) = MkT2 (T2 Type a)
-
- Starting with (inferInitialKinds)
- T2 :: (kappa1 :: kappa2 :: *) -> (kappa3 :: kappa4 :: *) -> *
- we get
- kappa4 := kappa1 -- from the (a:ka) kind signature
- kappa1 := Type -- From application T2 Type
-
- These constraints are soluble so generaliseTcTyCon gives
- T2 :: forall (k::Type) -> k -> *
-
- But now the /typechecking/ (aka desugaring, tcTyClDecl) phase
- fails, because the call (T2 Type a) in the RHS is ill-kinded.
-
- We'd really prefer all errors to show up in the kind checking
- phase.
-
-* This algorithm still accepts (in all phases)
- data T3 ka (a::ka) = forall b. MkT3 (T3 Type b)
- although T3 is really polymorphic-recursive too.
- Perhaps we should somehow reject that.
Note [Kind variable ordering for associated types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -3047,7 +3045,7 @@ tcTKTelescope mode tele thing_inside = case tele of
-- HsOuterTyVarBndrs
--------------------------------------
-bindOuterTKBndrsX :: OutputableBndrFlag flag 'Renamed
+bindOuterTKBndrsX :: OutputableBndrFlag flag 'Renamed -- Only to support traceTc
=> SkolemMode
-> HsOuterTyVarBndrs flag GhcRn
-> TcM a
@@ -3124,7 +3122,7 @@ bindOuterFamEqnTKBndrs skol_info
-- sm_clone=False: see Note [Cloning for type variable binders]
---------------
-tcOuterTKBndrs :: OutputableBndrFlag flag 'Renamed
+tcOuterTKBndrs :: OutputableBndrFlag flag 'Renamed -- Only to support traceTc
=> SkolemInfo
-> HsOuterTyVarBndrs flag GhcRn
-> TcM a -> TcM (HsOuterTyVarBndrs flag GhcTc, a)
@@ -3135,7 +3133,7 @@ tcOuterTKBndrs skol_info
-- Do not clone the outer binders
-- See Note [Cloning for type variable binders] under "must not"
-tcOuterTKBndrsX :: OutputableBndrFlag flag 'Renamed
+tcOuterTKBndrsX :: OutputableBndrFlag flag 'Renamed -- Only to support traceTc
=> SkolemMode -> SkolemInfo
-> HsOuterTyVarBndrs flag GhcRn
-> TcM a -> TcM (HsOuterTyVarBndrs flag GhcTc, a)
@@ -3156,7 +3154,7 @@ tcOuterTKBndrsX skol_mode skol_info outer_bndrs thing_inside
-- Explicit tyvar binders
--------------------------------------
-tcExplicitTKBndrs :: OutputableBndrFlag flag 'Renamed
+tcExplicitTKBndrs :: OutputableBndrFlag flag 'Renamed -- Only to suppor traceTc
=> SkolemInfo
-> [LHsTyVarBndr flag GhcRn]
-> TcM a
@@ -3164,7 +3162,7 @@ tcExplicitTKBndrs :: OutputableBndrFlag flag 'Renamed
tcExplicitTKBndrs skol_info
= tcExplicitTKBndrsX (smVanilla { sm_clone = True, sm_tvtv = SMDSkolemTv skol_info })
-tcExplicitTKBndrsX :: OutputableBndrFlag flag 'Renamed
+tcExplicitTKBndrsX :: OutputableBndrFlag flag 'Renamed -- Only to suppor traceTc
=> SkolemMode
-> [LHsTyVarBndr flag GhcRn]
-> TcM a
@@ -3199,14 +3197,14 @@ tcExplicitTKBndrsX skol_mode bndrs thing_inside = case nonEmpty bndrs of
-- | Skolemise the 'HsTyVarBndr's in an 'HsForAllTelescope' with the supplied
-- 'TcTyMode'.
bindExplicitTKBndrs_Skol
- :: (OutputableBndrFlag flag 'Renamed)
+ :: (OutputableBndrFlag flag 'Renamed) -- Only to suppor traceTc
=> SkolemInfo
-> [LHsTyVarBndr flag GhcRn]
-> TcM a
-> TcM ([VarBndr TyVar flag], a)
bindExplicitTKBndrs_Tv
- :: (OutputableBndrFlag flag 'Renamed)
+ :: (OutputableBndrFlag flag 'Renamed) -- Only to suppor traceTc
=> [LHsTyVarBndr flag GhcRn]
-> TcM a
-> TcM ([VarBndr TyVar flag], a)
@@ -3216,33 +3214,34 @@ bindExplicitTKBndrs_Tv = bindExplicitTKBndrsX (smVanilla { sm_clone = True, sm
-- sm_clone: see Note [Cloning for type variable binders]
bindExplicitTKBndrs_Q_Skol
- :: SkolemInfo
+ :: (OutputableBndrFlag flag 'Renamed) -- Only to support traceTc
+ => SkolemInfo
-> ContextKind
- -> [LHsTyVarBndr () GhcRn]
+ -> [LHsTyVarBndr flag GhcRn]
-> TcM a
- -> TcM ([TcTyVar], a)
+ -> TcM ([VarBndr TyVar flag], a)
bindExplicitTKBndrs_Q_Tv
- :: ContextKind
- -> [LHsTyVarBndr () GhcRn]
+ :: (OutputableBndrFlag flag 'Renamed) -- Only to support traceTc
+ => ContextKind
+ -> [LHsTyVarBndr flag GhcRn]
-> TcM a
- -> TcM ([TcTyVar], a)
+ -> TcM ([VarBndr TyVar flag], a)
-- These do not clone: see Note [Cloning for type variable binders]
bindExplicitTKBndrs_Q_Skol skol_info ctxt_kind hs_bndrs thing_inside
- = mapFst binderVars $
- bindExplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True
+ = bindExplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True
, sm_kind = ctxt_kind, sm_tvtv = SMDSkolemTv skol_info })
hs_bndrs thing_inside
-- sm_clone=False: see Note [Cloning for type variable binders]
bindExplicitTKBndrs_Q_Tv ctxt_kind hs_bndrs thing_inside
- = mapFst binderVars $
- bindExplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True
+ = bindExplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True
, sm_tvtv = SMDTyVarTv, sm_kind = ctxt_kind })
hs_bndrs thing_inside
-- sm_clone=False: see Note [Cloning for type variable binders]
-bindExplicitTKBndrsX :: (OutputableBndrFlag flag 'Renamed)
+bindExplicitTKBndrsX
+ :: (OutputableBndrFlag flag 'Renamed) -- Only to support traceTc
=> SkolemMode
-> [LHsTyVarBndr flag GhcRn]
-> TcM a
diff --git a/compiler/GHC/Tc/Gen/Splice.hs b/compiler/GHC/Tc/Gen/Splice.hs
index 943c8dcbd2..9192490847 100644
--- a/compiler/GHC/Tc/Gen/Splice.hs
+++ b/compiler/GHC/Tc/Gen/Splice.hs
@@ -2135,7 +2135,7 @@ reifyTyCon tc
injRHS = map (reifyName . tyVarName)
(filterByList ms tvs)
in (sig, inj)
- ; tvs' <- reifyTyVars (tyConVisibleTyVars tc)
+ ; tvs' <- reifyTyConBinders tc
; let tfHead =
TH.TypeFamilyHead (reifyName tc) tvs' resultSig injectivity
; if isOpenTypeFamilyTyCon tc
@@ -2156,7 +2156,7 @@ reifyTyCon tc
; kind' <- fmap Just (reifyKind res_kind)
- ; tvs' <- reifyTyVars (tyConVisibleTyVars tc)
+ ; tvs' <- reifyTyConBinders tc
; fam_envs <- tcGetFamInstEnvs
; instances <- reifyFamilyInstances tc (familyInstances fam_envs tc)
; return (TH.FamilyI
@@ -2164,7 +2164,7 @@ reifyTyCon tc
| Just (_, rhs) <- synTyConDefn_maybe tc -- Vanilla type synonym
= do { rhs' <- reifyType rhs
- ; tvs' <- reifyTyVars (tyConVisibleTyVars tc)
+ ; tvs' <- reifyTyConBinders tc
; return (TH.TyConI
(TH.TySynD (reifyName tc) tvs' rhs'))
}
@@ -2182,7 +2182,7 @@ reifyTyCon tc
dataCons = tyConDataCons tc
isGadt = isGadtSyntaxTyCon tc
; cons <- mapM (reifyDataCon isGadt (mkTyVarTys tvs)) dataCons
- ; r_tvs <- reifyTyVars (tyConVisibleTyVars tc)
+ ; r_tvs <- reifyTyConBinders tc
; let name = reifyName tc
deriv = [] -- Don't know about deriving
decl | isTypeDataTyCon tc =
@@ -2310,7 +2310,7 @@ reifyClass cls
; insts <- reifyClassInstances cls (InstEnv.classInstances inst_envs cls)
; assocTys <- concatMapM reifyAT ats
; ops <- concatMapM reify_op op_stuff
- ; tvs' <- reifyTyVars (tyConVisibleTyVars (classTyCon cls))
+ ; tvs' <- reifyTyConBinders (classTyCon cls)
; let dec = TH.ClassD cxt (reifyName cls) tvs' fds' (assocTys ++ ops)
; return (TH.ClassI dec insts) }
where
@@ -2654,6 +2654,43 @@ instance ReifyFlag Specificity TH.Specificity where
reifyFlag SpecifiedSpec = TH.SpecifiedSpec
reifyFlag InferredSpec = TH.InferredSpec
+instance ReifyFlag TyConBndrVis (Maybe TH.BndrVis) where
+ reifyFlag AnonTCB = Just TH.BndrReq
+ reifyFlag (NamedTCB Required) = Just TH.BndrReq
+ reifyFlag (NamedTCB (Invisible _)) =
+ Nothing -- See Note [Reifying invisible type variable binders] and #22828.
+
+-- Currently does not return invisible type variable binders (@k-binders).
+-- See Note [Reifying invisible type variable binders] and #22828.
+reifyTyConBinders :: TyCon -> TcM [TH.TyVarBndr TH.BndrVis]
+reifyTyConBinders tc = fmap (mapMaybe get_bndr) (reifyTyVarBndrs (tyConBinders tc))
+ where
+ get_bndr :: TH.TyVarBndr (Maybe flag) -> Maybe (TH.TyVarBndr flag)
+ get_bndr = sequenceA
+
+{- Note [Reifying invisible type variable binders]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In reifyFlag for TyConBndrVis, we have the following clause:
+
+ reifyFlag (NamedTCB (Invisible _)) = Nothing
+
+This means that reifyTyConBinders doesn't reify invisible type variables as
+@k-binders. However, it is possible (and not hard) to change this.
+Just replace the above clause with:
+
+ reifyFlag (NamedTCB Specified) = Just TH.BndrInvis
+ reifyFlag (NamedTCB Inferred) = Nothing -- Inferred variables can not be bound
+
+There are two reasons we opt not to do that for now.
+ 1. It would be a (sometimes silent) breaking change affecting th-abstraction,
+ aeson, and other libraries that assume that reified binders are visible.
+ 2. It would create an asymmetry with visible kind applications, which are
+ not reified either.
+
+This decision is not set in stone. If a use case for reifying invisible type
+variable binders presents itself, we can reconsider. See #22828.
+-}
+
reifyTyVars :: [TyVar] -> TcM [TH.TyVarBndr ()]
reifyTyVars = reifyTyVarBndrs . map mk_bndr
where
diff --git a/compiler/GHC/Tc/TyCl.hs b/compiler/GHC/Tc/TyCl.hs
index f3e02c0fd0..904fdab397 100644
--- a/compiler/GHC/Tc/TyCl.hs
+++ b/compiler/GHC/Tc/TyCl.hs
@@ -347,6 +347,268 @@ support making synonyms of types with higher-rank kinds. But
you can always specify a CUSK directly to make this work out.
See tc269 for an example.
+Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A TcTyCon is one of the variants of TyCon. First, here are its invariants:
+
+* TcTyCon: a TyCon built with the TcTyCon constructor
+ A TcTyCon contains TcTyVars in its binders and kind
+
+* TcTyConBinder: a TyConBinder with a TcTyVar inside (not a TyVar)
+
+* MonoTcTyCon: a form of TcTyCon
+ - Flag tcTyConIsPoly = False
+
+ - tyConBinders are TcTyConBinders: they contain TcTyVars, which are
+ unification variables (TyVarTv), and whose kinds may contain
+ unification variables.
+
+ - tyConKind: the Monomorphic Recursion Principle:
+ a MonoTcTyCon has a /monomorphic kind/.
+ See Note [No polymorphic recursion in type decls].
+ But the tyConKind may contain free unification variables.
+
+ - tyConScopedTyVars is important; maps a Name to a TyVarTv unification variable
+ The order matters: Specified then Required variables.
+ E.g. in
+ data T a (b :: k) = ...
+ the order will be [k, a, b].
+
+ We do not allow @k-binders in inference mode, so we do not need to worry about
+ data T a @k (b :: k) = ...
+ where we would have to put `k` (Specified) after `a` (Required)
+
+ NB: There are no Inferred binders in tyConScopedTyVars; 'a' may
+ also be poly-kinded, but that kind variable will be added by
+ generaliseTcTyCon, in the passage to a PolyTcTyCon.
+
+ - tyConBinders are irrelevant; we just use tcTyConScopedTyVars
+ Well not /quite/ irrelevant:
+ * its length gives the number of explicit binders, and so allows us to
+ distinguish between the implicit and explicit elements of
+ tyConScopedTyVars.
+ * at construction time (mkTcTyCon) for a MonoTcTyCon (the call to mkTcTyCon
+ in GHC.Tc.Gen.HsType.kcInferDeclHeader) the tyConBinders are used to
+ construct the tyConKind; all must have AnonTCB visiblity so we we get
+ a monokind.
+
+* PolyTcTyCon: a form of TcTyCon
+ - Flag tcTyConIsPoly = True; this is used only to short-cut zonking
+
+ - tyConBinders are still TcTyConBinders, but they are /skolem/ TcTyVars,
+ with fixed kinds, and accurate skolem info: no unification variables here
+
+ tyConBinders includes the Inferred binders if any
+
+ tyConBinders uses the Names from the original, renamed program.
+
+ - tcTyConScopedTyVars is irrelevant: just use (binderVars tyConBinders)
+ All the types have been swizzled back to use the original Names
+ See Note [tyConBinders and lexical scoping] in GHC.Core.TyCon
+
+The main purpose of these TcTyCons is during kind-checking of
+type/class declarations (in GHC.Tc.TyCl). During kind checking we
+come upon knowledge of the eventual tycon in bits and pieces, and we
+use a TcTyCon to record what we know before we are ready to build the
+final TyCon. Here is the plan:
+
+* Step 1 (inferInitialKinds, called from kcTyClGroup
+ inference only, skipped for checking):
+ Make a MonoTcTyCon whose binders are TcTyVars,
+ that may contain free unification variables.
+ See Note [No polymorphic recursion in type decls]
+
+* Step 2 (kcTyClDecl, called from kcTyClGroup)
+ Kind-check the declarations of the group; this step just does
+ unifications that affect the unification variables created in
+ Step 1
+
+* Step 3 (generaliseTcTyCon, called from kcTyClGroup)
+ Generalise that MonoTcTyCon to make a PolyTcTyCon
+ Its binders are skolem TcTyVars, with accurate SkolemInfo
+
+* Step 4 (tcTyClDecl, called from tcTyClDecls)
+ Typecheck the type and class decls to produce a final TyCon
+ Its binders are final TyVars, not TcTyVars
+
+Note that a MonoTcTyCon can contain unification variables, but a
+PolyTcTyCon does not: only skolem TcTyVars. See the invariants above.
+
+More details about /kind inference/:
+
+S1) In kcTyClGroup, we use inferInitialKinds to look over the
+ declaration of any TyCon that lacks a kind signature or
+ CUSK, to determine its "shape"; for example, the number of
+ parameters, and any kind signatures.
+
+ We record that shape record that shape in a MonoTcTyCon; it is
+ "mono" because it has not been been generalised, and its binders
+ and result kind may have free unification variables.
+
+S2) Still in kcTyClGroup, we use kcLTyClDecl to kind-check the
+ body (class methods, data constructors, etc.) of each of
+ these MonoTcTyCons, which has the effect of filling in the
+ metavariables in the tycon's initial kind.
+
+S3) Still in kcTyClGroup, we use generaliseTyClDecl to generalize
+ each MonoTcTyCon to get a PolyTcTyCon, with skolem TcTyVars in it,
+ and a final, fixed kind.
+
+S4) Finally, back in tcTyClDecls, we extend the environment with
+ the PolyTcTyCons, and typecheck each declaration (regardless
+ of kind signatures etc) to get final TyCon.
+
+More details about /kind checking/
+
+S5) In kcTyClGroup, we use checkInitialKinds to get the
+ utterly-final Kind of all TyCons in the group that
+ (a) have a standalone kind signature or
+ (b) have a CUSK.
+ This produces a PolyTcTyCon, that is, a TcTyCon in which the binders
+ and result kind are full of TyVars (not TcTyVars). No unification
+ variables here; everything is in its final form.
+
+Wrinkles:
+
+(W1) When recovering from a type error in a type declaration,
+ we want to put the erroneous TyCon in the environment in a
+ way that won't lead to more errors. We use a PolyTcTyCon for this;
+ see makeRecoveryTyCon.
+
+(W2) tyConScopedTyVars. A challenging piece in all of this is that we
+ end up taking three separate passes over every declaration:
+ - one in inferInitialKind (this pass look only at the head, not the body)
+ - one in kcTyClDecls (to kind-check the body)
+ - a final one in tcTyClDecls (to desugar)
+
+ In the latter two passes, we need to connect the user-written type
+ variables in an LHsQTyVars with the variables in the tycon's
+ inferred kind. Because the tycon might not have a CUSK, this
+ matching up is, in general, quite hard to do. (Look through the
+ git history between Dec 2015 and Apr 2016 for
+ GHC.Tc.Gen.HsType.splitTelescopeTvs!)
+
+ Instead of trying, we just store the list of type variables to
+ bring into scope, in the tyConScopedTyVars field of a MonoTcTyCon.
+ These tyvars are brought into scope by the calls to
+ tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon)
+ in kcTyClDecl.
+
+ In a TcTyCon, why is tyConScopedTyVars :: [(Name,TcTyVar)] rather
+ than just [TcTyVar]? Consider these mutually-recursive decls
+ data T (a :: k1) b = MkT (S a b)
+ data S (c :: k2) d = MkS (T c d)
+ We start with k1 bound to kappa1, and k2 to kappa2; so initially
+ in the (Name,TcTyVar) pairs the Name is that of the TcTyVar. But
+ then kappa1 and kappa2 get unified; so after the zonking in
+ 'generalise' in 'kcTyClGroup' the Name and TcTyVar may differ.
+
+See also Note [Type checking recursive type and class declarations].
+
+Note [No polymorphic recursion in type decls]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In GHC.Tc.HsType.kcInferDeclHeader we use mkAnonTyConBinders to make
+the TyConBinders for the MonoTcTyCon. Here is why.
+
+Should this kind-check (cf #16344)?
+ data T ka (a::ka) b = MkT (T Type Int Bool)
+ (T (Type -> Type) Maybe Bool)
+
+Notice that T is used at two different kinds in its RHS. No!
+This should not kind-check. Polymorphic recursion is known to
+be a tough nut.
+
+Many moons ago, we laboriously (with help from the renamer) tried to give T
+the polymorphic kind
+ T :: forall ka -> ka -> kappa -> Type
+where kappa is a unification variable, even in the inferInitialKinds phase
+(which is what kcInferDeclHeader is all about). But that is dangerously
+fragile (see #16344), because `kappa` might get unified with `ka`, and
+depending on just /when/ that unification happens, the instantiation of T's
+kind would vary between different call sites of T.
+
+We encountered similar trickiness with invisible binders in type
+declarations: see Note [No inference for invisible binders in type decls]
+
+Solution: the Monomorphic Recursion Principle:
+
+ A MonoTcTyCon has a monomoprhic kind (no foralls!)
+
+See the invariants on MonoTcTyCon in Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon].
+
+So kcInferDeclHeader gives T a straightforward monomorphic kind, with no
+quantification whatsoever. That's why we always use mkAnonTyConBinder for
+all arguments when figuring out tc_binders.
+
+But notice that (#16344 comment:3)
+
+* Consider this declaration:
+ data T2 ka (a::ka) = MkT2 (T2 Type a)
+
+ Starting with inferInitialKinds
+ (Step 1 of Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]):
+ MonoTcTyCon binders:
+ ka[tyv] :: (kappa1[tau] :: Type)
+ a[tyv] :: (ka[tyv] :: Type)
+ MonoTcTyCon kind:
+ T2 :: kappa1[tau] -> ka[tyv] -> Type
+
+ Given this kind for T2, in Step 2 we kind-check (T2 Type a)
+ from where we see
+ T2's first arg: (kappa1 ~ Type)
+ T2's second arg: (ka ~ ka)
+ These constraints are soluble by (kappa1 := Type)
+ so generaliseTcTyCon (Step 3) gives
+ T2 :: forall (k::Type) -> k -> *
+
+ But now the /typechecking/ (Step 4, aka desugaring, tcTyClDecl)
+ phase fails, because the call (T2 Type a) in the RHS is ill-kinded.
+
+ We'd really prefer all errors to show up in the kind checking phase.
+
+* This algorithm still accepts (in all phases)
+ data T3 ka (a::ka) = forall b. MkT3 (T3 Type b)
+ although T3 is really polymorphic-recursive too.
+ Perhaps we should somehow reject that.
+
+Note [No inference for invisible binders in type decls]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Suppose we have (#22560):
+ data T @k (a::k) = MkT (...(T ty)...)
+What monokind can we give to T after step 1 of the kind inference
+algorithm described in Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]?
+Remember: Step 1 generates a MonoTcTyCon.
+
+It can't be
+ T :: kappa1 -> kappa2 -> Type
+because the invocation `(T ty)` doesn't have a visible argument for `kappa`.
+Nor can it be
+ T :: forall k. kappa2 -> Type
+because that breaks the Monomorphic Recursion Principle: MonoTcTyCons have
+monomorphic kinds; see Note [No polymorphic recursion in type decls]. It could be
+ T :: kappa1 ->. kappa2 -> type
+where `->.` is a new kind of arrow in kinds, which (like a type-class argument
+in terms) is invisibly instantiated. Or we could fake it with
+ T :: forall _. kappa2 -> Type
+where `_` is a completely fresh variable, but that seems very smelly and makes it
+harder to talk about the Monomorphic Recursion Principle. Moreover we'd need
+some extra fancy types in TyConBinders to record this extra information.
+
+Note that in *terms* we do not allow
+ f @a (x::a) = rhs
+unless `f` has a type signature. So we do the same for types:
+
+ We allow `@` binders in data type declarations ONLY if the
+ type constructor has a standalone kind signature (or a CUSK).
+
+That means that GHC.Tc.Gen.HsType.kcInferDeclHeader, which is used when we
+don't have a kind signature or CUSK, and builds a MonoTcTyCon, we can simply
+reject invisible binders outright (GHC.Tc.Gen.HsType.rejectInvisibleBinders);
+and continue to use mkAnonTyConBinders as described in
+Note [No polymorphic recursion in type decls].
+
+If we get cries of pain we can revist this decision.
+
Note [CUSKs and PolyKinds]
~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
@@ -398,100 +660,6 @@ environment. (This is handled by `allDecls').
See also Note [Kind checking recursive type and class declarations]
-Note [How TcTyCons work]
-~~~~~~~~~~~~~~~~~~~~~~~~
-TcTyCons are used for two distinct purposes
-
-1. When recovering from a type error in a type declaration,
- we want to put the erroneous TyCon in the environment in a
- way that won't lead to more errors. We use a TcTyCon for this;
- see makeRecoveryTyCon.
-
-2. When checking a type/class declaration (in module GHC.Tc.TyCl), we come
- upon knowledge of the eventual tycon in bits and pieces, and we use
- a TcTyCon to record what we know before we are ready to build the
- final TyCon. Here is the plan:
-
- Step 1 (inferInitialKinds, inference only, skipped for checking):
- Make a MonoTcTyCon whose binders are TcTyVars,
- which may contain free unification variables
-
- Step 2 (generaliseTcTyCon)
- Generalise that MonoTcTyCon to make a PolyTcTyCon
- Its binders are skolem TcTyVars, with accurate SkolemInfo
-
- Step 3 (tcTyClDecl)
- Typecheck the type and class decls to produce a final TyCon
- Its binders are final TyVars, not TcTyVars
-
- Note that a MonoTcTyCon can contain unification variables,
- but a PolyTcTyCon does not: only skolem TcTyVars. See
- Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.Utils.TcType
-
- More details about /kind inference/:
-
- S1) In kcTyClGroup, we use inferInitialKinds to look over the
- declaration of any TyCon that lacks a kind signature or
- CUSK, to determine its "shape"; for example, the number of
- parameters, and any kind signatures.
-
- We record that shape record that shape in a MonoTcTyCon; it is
- "mono" because it has not been been generalised, and its binders
- and result kind may have free unification variables.
-
- S2) Still in kcTyClGroup, we use kcLTyClDecl to kind-check the
- body (class methods, data constructors, etc.) of each of
- these MonoTcTyCons, which has the effect of filling in the
- metavariables in the tycon's initial kind.
-
- S3) Still in kcTyClGroup, we use generaliseTyClDecl to generalize
- each MonoTcTyCon to get a PolyTcTyCon, with skolem TcTyVars in it,
- and a final, fixed kind.
-
- S4) Finally, back in TcTyClDecls, we extend the environment with
- the PolyTcTyCons, and typecheck each declaration (regardless
- of kind signatures etc) to get final TyCon.
-
- More details about /kind checking/
-
- S5) In kcTyClGroup, we use checkInitialKinds to get the
- utterly-final Kind of all TyCons in the group that
- (a) have a separate kind signature or
- (b) have a CUSK.
- This produces a PolyTcTyCon, that is, a TcTyCon in which the binders
- and result kind are full of TyVars (not TcTyVars). No unification
- variables here; everything is in its final form.
-
-3. tyConScopedTyVars. A challenging piece in all of this is that we
- end up taking three separate passes over every declaration:
- - one in inferInitialKind (this pass look only at the head, not the body)
- - one in kcTyClDecls (to kind-check the body)
- - a final one in tcTyClDecls (to desugar)
-
- In the latter two passes, we need to connect the user-written type
- variables in an LHsQTyVars with the variables in the tycon's
- inferred kind. Because the tycon might not have a CUSK, this
- matching up is, in general, quite hard to do. (Look through the
- git history between Dec 2015 and Apr 2016 for
- GHC.Tc.Gen.HsType.splitTelescopeTvs!)
-
- Instead of trying, we just store the list of type variables to
- bring into scope, in the tyConScopedTyVars field of a MonoTcTyCon.
- These tyvars are brought into scope by the calls to
- tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon)
- in kcTyClDecl.
-
- In a TcTyCon, why is tyConScopedTyVars :: [(Name,TcTyVar)] rather
- than just [TcTyVar]? Consider these mutually-recursive decls
- data T (a :: k1) b = MkT (S a b)
- data S (c :: k2) d = MkS (T c d)
- We start with k1 bound to kappa1, and k2 to kappa2; so initially
- in the (Name,TcTyVar) pairs the Name is that of the TcTyVar. But
- then kappa1 and kappa2 get unified; so after the zonking in
- 'generalise' in 'kcTyClGroup' the Name and TcTyVar may differ.
-
-See also Note [Type checking recursive type and class declarations].
-
Note [Swizzling the tyvars before generaliseTcTyCon]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This Note only applies when /inferring/ the kind of a TyCon.
@@ -1090,7 +1258,7 @@ Test cases (and tickets) relevant to these design decisions
Note [Inferring kinds for type declarations]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This note deals with /inference/ for type declarations
-that do not have a CUSK. Consider
+that do not have a CUSK or a SAKS. Consider
data T (a :: k1) k2 (x :: k2) = MkT (S a k2 x)
data S (b :: k3) k4 (y :: k4) = MkS (T b k4 y)
@@ -1254,18 +1422,17 @@ It's hard to know when we've actually been tripped up by polymorphic recursion
specifically, so we just include a note to users whenever we infer VDQ. The
testsuite did not show up a single spurious inclusion of this message.
-The context is added in addVDQNote, which looks for a visible TyConBinder
-that also appears in the TyCon's kind. (I first looked at the kind for
-a visible, dependent quantifier, but Note [No polymorphic recursion] in
-GHC.Tc.Gen.HsType defeats that approach.) addVDQNote is used in kcTyClDecl,
-which is used only when inferring the kind of a tycon (never with a CUSK or
-SAK).
+The context is added in addVDQNote, which looks for a visible
+TyConBinder that also appears in the TyCon's kind. (I first looked at
+the kind for a visible, dependent quantifier, but
+ Note [No polymorphic recursion in type decls]
+in GHC.Tc.Gen.HsType defeats that approach.) addVDQNote is used in
+kcTyClDecl, which is used only when inferring the kind of a tycon
+(never with a CUSK or SAKS).
Once upon a time, I (Richard E) thought that the tycon-kind could
not be a forall-type. But this is wrong: data T :: forall k. k -> Type
(with -XNoCUSKs) could end up here. And this is all OK.
-
-
-}
--------------
@@ -1583,7 +1750,7 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM ()
-- TcTyVars rather than create skolemised variables for the bound variables.
-- - inferInitialKinds makes the TcTyCon where the tyvars are TcTyVars
-- - In this function, those TcTyVars are unified with other kind variables during
--- kind inference (see [How TcTyCons work])
+-- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon])
kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) tycon
= tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $
@@ -5130,7 +5297,7 @@ tcMkDeclCtxt decl = hsep [text "In the", pprTyClDeclFlavour decl,
addVDQNote :: TcTyCon -> TcM a -> TcM a
-- See Note [Inferring visible dependent quantification]
--- Only types without a signature (CUSK or SAK) here
+-- Only types without a signature (CUSK or SAKS) here
addVDQNote tycon thing_inside
| assertPpr (isMonoTcTyCon tycon) (ppr tycon $$ ppr tc_kind)
has_vdq
diff --git a/compiler/GHC/Tc/Utils/TcMType.hs b/compiler/GHC/Tc/Utils/TcMType.hs
index 89614378cd..8395bd5540 100644
--- a/compiler/GHC/Tc/Utils/TcMType.hs
+++ b/compiler/GHC/Tc/Utils/TcMType.hs
@@ -79,6 +79,7 @@ module GHC.Tc.Utils.TcMType (
zonkTcType, zonkTcTypes, zonkCo,
zonkTyCoVarKind,
+ zonkTyCoVarBndrKind,
zonkEvVar, zonkWC, zonkImplication, zonkSimples,
zonkId, zonkCoVar,
zonkCt, zonkSkolemInfo, zonkSkolemInfoAnon,
@@ -2317,6 +2318,11 @@ zonkTyCoVarKind :: TyCoVar -> TcM TyCoVar
zonkTyCoVarKind tv = do { kind' <- zonkTcType (tyVarKind tv)
; return (setTyVarKind tv kind') }
+zonkTyCoVarBndrKind :: VarBndr TyCoVar flag -> TcM (VarBndr TyCoVar flag)
+zonkTyCoVarBndrKind (Bndr tv flag) =
+ do { tv' <- zonkTyCoVarKind tv
+ ; return (Bndr tv' flag) }
+
{-
************************************************************************
* *
diff --git a/compiler/GHC/Tc/Utils/TcType.hs b/compiler/GHC/Tc/Utils/TcType.hs
index 67b19c032a..648a508d4b 100644
--- a/compiler/GHC/Tc/Utils/TcType.hs
+++ b/compiler/GHC/Tc/Utils/TcType.hs
@@ -368,7 +368,7 @@ type TcTyVarBinder = TyVarBinder
type TcInvisTVBinder = InvisTVBinder
type TcReqTVBinder = ReqTVBinder
--- See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]
+-- See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] in GHC.Tc.TyCl
type TcTyCon = TyCon
type MonoTcTyCon = TcTyCon
type PolyTcTyCon = TcTyCon
@@ -402,50 +402,6 @@ type TcTyCoVarSet = TyCoVarSet
type TcDTyVarSet = DTyVarSet
type TcDTyCoVarSet = DTyCoVarSet
-{- Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-See Note [How TcTyCons work] in GHC.Tc.TyCl
-
-Invariants:
-
-* TcTyCon: a TyCon built with the TcTyCon constructor
-
-* TcTyConBinder: a TyConBinder with a TcTyVar inside (not a TyVar)
-
-* TcTyCons contain TcTyVars
-
-* MonoTcTyCon:
- - Flag tcTyConIsPoly = False
-
- - tyConScopedTyVars is important; maps a Name to a TyVarTv unification variable
- The order is important: Specified then Required variables. E.g. in
- data T a (b :: k) = ...
- the order will be [k, a, b].
-
- NB: There are no Inferred binders in tyConScopedTyVars; 'a' may
- also be poly-kinded, but that kind variable will be added by
- generaliseTcTyCon, in the passage to a PolyTcTyCon.
-
- - tyConBinders are irrelevant; we just use tcTyConScopedTyVars
- Well not /quite/ irrelevant: its length gives the number of Required binders,
- and so allows up to distinguish between the Specified and Required elements of
- tyConScopedTyVars.
-
-* PolyTcTyCon:
- - Flag tcTyConIsPoly = True; this is used only to short-cut zonking
-
- - tyConBinders are still TcTyConBinders, but they are /skolem/ TcTyVars,
- with fixed kinds, and accurate skolem info: no unification variables here
-
- tyConBinders includes the Inferred binders if any
-
- tyConBinders uses the Names from the original, renamed program.
-
- - tcTyConScopedTyVars is irrelevant: just use (binderVars tyConBinders)
- All the types have been swizzled back to use the original Names
- See Note [tyConBinders and lexical scoping] in GHC.Core.TyCon
-
--}
{- *********************************************************************
* *
diff --git a/compiler/GHC/ThToHs.hs b/compiler/GHC/ThToHs.hs
index 498a17694f..cc3f2fdab7 100644
--- a/compiler/GHC/ThToHs.hs
+++ b/compiler/GHC/ThToHs.hs
@@ -2,6 +2,7 @@
{-# LANGUAGE ConstrainedClassMethods #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE ScopedTypeVariables #-}
@@ -464,7 +465,7 @@ cvtDec (TH.ImplicitParamBindD _ _)
= failWith InvalidImplicitParamBinding
-- Convert a @data@ declaration.
-cvtDataDec :: TH.Cxt -> TH.Name -> [TH.TyVarBndr ()]
+cvtDataDec :: TH.Cxt -> TH.Name -> [TH.TyVarBndr TH.BndrVis]
-> Maybe TH.Kind -> [TH.Con] -> [TH.DerivClause]
-> CvtM (Maybe (LHsDecl GhcPs))
cvtDataDec = cvtGenDataDec False
@@ -472,14 +473,14 @@ cvtDataDec = cvtGenDataDec False
-- Convert a @type data@ declaration.
-- These have neither contexts nor derived clauses.
-- See Note [Type data declarations] in GHC.Rename.Module.
-cvtTypeDataDec :: TH.Name -> [TH.TyVarBndr ()] -> Maybe TH.Kind -> [TH.Con]
+cvtTypeDataDec :: TH.Name -> [TH.TyVarBndr TH.BndrVis] -> Maybe TH.Kind -> [TH.Con]
-> CvtM (Maybe (LHsDecl GhcPs))
cvtTypeDataDec tc tvs ksig constrs
= cvtGenDataDec True [] tc tvs ksig constrs []
-- Convert a @data@ or @type data@ declaration (flagged by the Bool arg).
-- See Note [Type data declarations] in GHC.Rename.Module.
-cvtGenDataDec :: Bool -> TH.Cxt -> TH.Name -> [TH.TyVarBndr ()]
+cvtGenDataDec :: Bool -> TH.Cxt -> TH.Name -> [TH.TyVarBndr TH.BndrVis]
-> Maybe TH.Kind -> [TH.Con] -> [TH.DerivClause]
-> CvtM (Maybe (LHsDecl GhcPs))
cvtGenDataDec type_data ctxt tc tvs ksig constrs derivs
@@ -568,7 +569,7 @@ cvt_ci_decs declDescr decs
; return (listToBag binds', sigs', fams', ats', adts') }
----------------
-cvt_tycl_hdr :: TH.Cxt -> TH.Name -> [TH.TyVarBndr ()]
+cvt_tycl_hdr :: TH.Cxt -> TH.Name -> [TH.TyVarBndr TH.BndrVis]
-> CvtM ( LHsContext GhcPs
, LocatedN RdrName
, LHsQTyVars GhcPs)
@@ -1488,6 +1489,10 @@ instance CvtFlag TH.Specificity Hs.Specificity where
cvtFlag TH.SpecifiedSpec = Hs.SpecifiedSpec
cvtFlag TH.InferredSpec = Hs.InferredSpec
+instance CvtFlag TH.BndrVis (HsBndrVis GhcPs) where
+ cvtFlag TH.BndrReq = HsBndrRequired
+ cvtFlag TH.BndrInvis = HsBndrInvisible noHsTok
+
cvtTvs :: CvtFlag flag flag' => [TH.TyVarBndr flag] -> CvtM [LHsTyVarBndr flag' GhcPs]
cvtTvs tvs = mapM cvt_tv tvs
diff --git a/compiler/GHC/Types/Error/Codes.hs b/compiler/GHC/Types/Error/Codes.hs
index d7b57113ee..e188c89471 100644
--- a/compiler/GHC/Types/Error/Codes.hs
+++ b/compiler/GHC/Types/Error/Codes.hs
@@ -253,7 +253,6 @@ type family GhcDiagnosticCode c = n | n -> c where
GhcDiagnosticCode "PsErrAtInPatPos" = 08382
GhcDiagnosticCode "PsErrParseErrorOnInput" = 66418
GhcDiagnosticCode "PsErrMalformedDecl" = 85316
- GhcDiagnosticCode "PsErrUnexpectedTypeAppInDecl" = 45054
GhcDiagnosticCode "PsErrNotADataCon" = 25742
GhcDiagnosticCode "PsErrInferredTypeVarNotAllowed" = 57342
GhcDiagnosticCode "PsErrIllegalTraditionalRecordSyntax" = 65719
@@ -512,6 +511,9 @@ type family GhcDiagnosticCode c = n | n -> c where
GhcDiagnosticCode "TcRnUnexpectedDefaultSig" = 40700
GhcDiagnosticCode "TcRnBindInBootFile" = 11247
GhcDiagnosticCode "TcRnDuplicateMinimalSig" = 85346
+ GhcDiagnosticCode "TcRnIllegalInvisTyVarBndr" = 58589
+ GhcDiagnosticCode "TcRnInvalidInvisTyVarBndr" = 57916
+ GhcDiagnosticCode "TcRnInvisBndrWithoutSig" = 92337
-- IllegalNewtypeReason
GhcDiagnosticCode "DoesNotHaveSingleField" = 23517
@@ -619,6 +621,7 @@ type family GhcDiagnosticCode c = n | n -> c where
GhcDiagnosticCode "Example outdated error" = 00000
GhcDiagnosticCode "TcRnNameByTemplateHaskellQuote" = 40027
GhcDiagnosticCode "TcRnIllegalBindingOfBuiltIn" = 69639
+ GhcDiagnosticCode "PsErrUnexpectedTypeAppInDecl" = 45054
{- *********************************************************************
* *
diff --git a/compiler/GHC/Types/Hint.hs b/compiler/GHC/Types/Hint.hs
index 9f897feb7f..2c965b7815 100644
--- a/compiler/GHC/Types/Hint.hs
+++ b/compiler/GHC/Types/Hint.hs
@@ -324,6 +324,14 @@ data GhcHint
-}
| SuggestAddStandaloneDerivation
+ {-| Suggests to add a standalone kind signature when GHC
+ can't perform kind inference.
+
+ Triggered by: 'GHC.Tc.Errors.Types.TcRnInvisBndrWithoutSig'
+ Test case(s): typecheck/should_fail/T22560_fail_d
+ -}
+ | SuggestAddStandaloneKindSignature Name
+
{-| Suggests the user to fill in the wildcard constraint to
disambiguate which constraint that is.
diff --git a/compiler/GHC/Types/Hint/Ppr.hs b/compiler/GHC/Types/Hint/Ppr.hs
index 96fbd9f74f..40f261a630 100644
--- a/compiler/GHC/Types/Hint/Ppr.hs
+++ b/compiler/GHC/Types/Hint/Ppr.hs
@@ -143,6 +143,8 @@ instance Outputable GhcHint where
Just (DataFamilyInst {}) -> text "data family"
SuggestAddStandaloneDerivation
-> text "Use a standalone deriving declaration instead"
+ SuggestAddStandaloneKindSignature name
+ -> text "Add a standalone kind signature for" <+> quotes (ppr name)
SuggestFillInWildcardConstraint
-> text "Fill in the wildcard constraint yourself"
SuggestRenameForall
diff --git a/compiler/Language/Haskell/Syntax/Type.hs b/compiler/Language/Haskell/Syntax/Type.hs
index 8898d2400b..f6cbb5443b 100644
--- a/compiler/Language/Haskell/Syntax/Type.hs
+++ b/compiler/Language/Haskell/Syntax/Type.hs
@@ -25,6 +25,7 @@ module Language.Haskell.Syntax.Type (
HsLinearArrowTokens(..),
HsType(..), LHsType, HsKind, LHsKind,
+ HsBndrVis(..), isHsBndrInvisible,
HsForAllTelescope(..), HsTyVarBndr(..), LHsTyVarBndr,
LHsQTyVars(..),
HsOuterTyVarBndrs(..), HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs,
@@ -342,12 +343,12 @@ type LHsTyVarBndr flag pass = XRec pass (HsTyVarBndr flag pass)
data LHsQTyVars pass -- See Note [HsType binders]
= HsQTvs { hsq_ext :: XHsQTvs pass
- , hsq_explicit :: [LHsTyVarBndr () pass]
+ , hsq_explicit :: [LHsTyVarBndr (HsBndrVis pass) pass]
-- Explicit variables, written by the user
}
| XLHsQTyVars !(XXLHsQTyVars pass)
-hsQTvExplicit :: LHsQTyVars pass -> [LHsTyVarBndr () pass]
+hsQTvExplicit :: LHsQTyVars pass -> [LHsTyVarBndr (HsBndrVis pass) pass]
hsQTvExplicit = hsq_explicit
------------------------------------------------
@@ -713,6 +714,21 @@ data HsTyVarBndr flag pass
| XTyVarBndr
!(XXTyVarBndr pass)
+data HsBndrVis pass
+ = HsBndrRequired
+ -- Binder for a visible (required) variable:
+ -- type Dup a = (a, a)
+ -- ^^^
+
+ | HsBndrInvisible (LHsToken "@" pass)
+ -- Binder for an invisible (specified) variable:
+ -- type KindOf @k (a :: k) = k
+ -- ^^^
+
+isHsBndrInvisible :: HsBndrVis pass -> Bool
+isHsBndrInvisible HsBndrInvisible{} = True
+isHsBndrInvisible HsBndrRequired = False
+
-- | Does this 'HsTyVarBndr' come with an explicit kind annotation?
isHsKindedTyVar :: HsTyVarBndr flag pass -> Bool
isHsKindedTyVar (UserTyVar {}) = False
diff --git a/docs/users_guide/9.8.1-notes.rst b/docs/users_guide/9.8.1-notes.rst
index 14c6d5bff6..cc7c76da3e 100644
--- a/docs/users_guide/9.8.1-notes.rst
+++ b/docs/users_guide/9.8.1-notes.rst
@@ -6,6 +6,15 @@ Version 9.8.1
Language
~~~~~~~~
+- GHC Proposal `#425
+ <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0425-decl-invis-binders.rst>`_
+ has been partially implemented. Namely, the ``@k``-binders in type declarations are now permitted::
+
+ type T :: forall k. k -> forall j. j -> Type
+ data T @k (a :: k) @(j :: Type) (b :: j)
+
+ This feature is guarded behind :extension:`TypeAbstractions`.
+
Compiler
~~~~~~~~
diff --git a/docs/users_guide/exts/primitives.rst b/docs/users_guide/exts/primitives.rst
index 9caab6b146..3db2517c68 100644
--- a/docs/users_guide/exts/primitives.rst
+++ b/docs/users_guide/exts/primitives.rst
@@ -378,7 +378,7 @@ only required for ``newtype instance`` declarations, such as ``FooKeyBoolC``
and ``BarTypeWorkRepC`` above.
This extension impacts the determination of whether or not a newtype has
-a Complete User-Specified Kind Signature (CUSK). The exact impact is specified
+a Complete User-Supplied Kind (CUSK). The exact impact is specified
`the section on CUSKs <#complete-kind-signatures>`__.
Unlifted Datatypes
diff --git a/docs/users_guide/exts/type_abstractions.rst b/docs/users_guide/exts/type_abstractions.rst
index ca8761f405..2e5e8ecab7 100644
--- a/docs/users_guide/exts/type_abstractions.rst
+++ b/docs/users_guide/exts/type_abstractions.rst
@@ -93,3 +93,99 @@ additional conservative restriction, that type variables occurring in patterns m
already be in scope, and so are always new variables that only bind whatever type is
matched, rather than ever referring to a variable from an outer scope. Type wildcards
``_`` may be used in any place where no new variable needs binding.
+
+.. _invisible-binders-in-type-declarations:
+
+Invisible Binders in Type Declarations
+--------------------------------------
+
+Syntax
+~~~~~~
+
+The type abstraction syntax can be used in type declaration headers, including
+``type``, ``data``, ``newtype``, ``class``, ``type family``, and ``data family``
+declarations. Here are a few examples::
+
+ type C :: forall k. k -> Constraint
+ class C @k a where ...
+ ^^
+
+ type D :: forall k j. k -> j -> Type
+ data D @k @j (a :: k) (b :: j) = ...
+ ^^ ^^
+
+ type F :: forall p q. p -> q -> (p, q)
+ type family F @p @q a b where ...
+ ^^ ^^
+
+Just as ordinary type parameters, invisible type variable binders may have kind
+annotations::
+
+ type F :: forall p q. p -> q -> (p, q)
+ type family F @(p :: Type) @(q :: Type) (a :: p) (b :: q) where ...
+
+Scope
+~~~~~
+
+The ``@k``-binders scope over the body of the declaration and can be used to bring
+implicit type or kind variables into scope. Consider::
+
+ type C :: forall i. (i -> i -> i) -> Constraint
+ class C @i a where
+ p :: P a i
+
+Without the ``@i`` binder in ``C @i a``, the ``i`` in ``P a i`` would no longer
+refer to the class variable ``i`` and would be implicitly quantified in the
+method signature instead.
+
+Type checking
+~~~~~~~~~~~~~
+
+Invisible type variable binders require either a standalone kind signature or a
+complete user-supplied kind.
+
+If a standalone kind signature is given, GHC will match up ``@k``-binders with
+the corresponding ``forall k.`` quantifiers in the signature::
+
+ type B :: forall k. k -> forall j. j -> Type
+ data B @k (a :: k) @j (b :: j)
+
++------------------------------------+
+| Quantifier-binder pairs of ``B`` |
++==============+=====================+
+| ``forall k.``| ``@k`` |
++--------------+---------------------+
+| ``k ->`` | ``(a :: k)`` |
++--------------+---------------------+
+| ``forall j.``| ``@j`` |
++--------------+---------------------+
+| ``j ->`` | ``(b :: j)`` |
++--------------+---------------------+
+
+The matching is done left-to-right. Consider::
+
+ type S :: forall a b. a -> b -> Type
+ type S @k x y = ...
+
+In this example, ``@k`` is matched with ``forall a.``, not ``forall b.``:
+
++-------------------------------------+
+| Quantifier-binder pairs of ``S`` |
++==============+======================+
+| ``forall a.``| ``@k`` |
++--------------+----------------------+
+| ``forall b.``| |
++--------------+----------------------+
+| ``a ->`` | ``x`` |
++--------------+----------------------+
+| ``b ->`` | ``y`` |
++--------------+----------------------+
+
+When a standalone kind signature is absent but the definition has a complete
+user-supplied kind (and the :extension:`CUSKs` extension is enabled),
+a ``@k``-binder gives rise to a ``forall k.`` quantifier in the inferred kind
+signature. The inferred ``forall k.`` does not float to the left; the order of
+quantifiers continues to match the order of binders in the header::
+
+ -- Inferred kind: forall k. k -> forall j. j -> Type
+ data B @(k :: Type) (a :: k) @(j :: Type) (b :: j) \ No newline at end of file
diff --git a/libraries/ghci/GHCi/TH/Binary.hs b/libraries/ghci/GHCi/TH/Binary.hs
index 236229a9df..6d5447e329 100644
--- a/libraries/ghci/GHCi/TH/Binary.hs
+++ b/libraries/ghci/GHCi/TH/Binary.hs
@@ -27,6 +27,7 @@ instance Binary TH.Info
instance Binary TH.Type
instance Binary TH.TyLit
instance Binary TH.Specificity
+instance Binary TH.BndrVis
instance Binary flag => Binary (TH.TyVarBndr flag)
instance Binary TH.Role
instance Binary TH.Lit
diff --git a/libraries/template-haskell/Language/Haskell/TH.hs b/libraries/template-haskell/Language/Haskell/TH.hs
index ea5df6b1f9..22f434d4e5 100644
--- a/libraries/template-haskell/Language/Haskell/TH.hs
+++ b/libraries/template-haskell/Language/Haskell/TH.hs
@@ -89,6 +89,7 @@ module Language.Haskell.TH(
-- ** Types
Type(..), TyVarBndr(..), TyLit(..), Kind, Cxt, Pred, Syntax.Role(..),
Syntax.Specificity(..),
+ Syntax.BndrVis(..),
FamilyResultSig(..), Syntax.InjectivityAnn(..), PatSynType, BangType, VarBangType,
-- ** Documentation
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib.hs b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
index b52de5b0d3..33a60d771d 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Lib.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
@@ -24,7 +24,7 @@ module Language.Haskell.TH.Lib (
BangTypeQ, VarBangTypeQ, StrictTypeQ, VarStrictTypeQ, FieldExpQ, PatQ,
FieldPatQ, RuleBndrQ, TySynEqnQ, PatSynDirQ, PatSynArgsQ,
FamilyResultSigQ, DerivStrategyQ,
- TyVarBndrUnit, TyVarBndrSpec,
+ TyVarBndrUnit, TyVarBndrSpec, TyVarBndrVis,
-- ** Constructors lifted to 'Q'
-- *** Literals
@@ -77,9 +77,12 @@ module Language.Haskell.TH.Lib (
varK, conK, tupleK, arrowK, listK, appK, starK, constraintK,
-- *** Type variable binders
+ DefaultBndrFlag(defaultBndrFlag),
plainTV, kindedTV,
plainInvisTV, kindedInvisTV,
+ plainBndrTV, kindedBndrTV,
specifiedSpec, inferredSpec,
+ bndrReq, bndrInvis,
-- *** Roles
nominalR, representationalR, phantomR, inferR,
@@ -192,10 +195,10 @@ import Prelude hiding (Applicative(..))
-------------------------------------------------------------------------------
-- * Dec
-tySynD :: Quote m => Name -> [TyVarBndr ()] -> m Type -> m Dec
+tySynD :: Quote m => Name -> [TyVarBndr BndrVis] -> m Type -> m Dec
tySynD tc tvs rhs = do { rhs1 <- rhs; return (TySynD tc tvs rhs1) }
-dataD :: Quote m => m Cxt -> Name -> [TyVarBndr ()] -> Maybe Kind -> [m Con] -> [m DerivClause]
+dataD :: Quote m => m Cxt -> Name -> [TyVarBndr BndrVis] -> Maybe Kind -> [m Con] -> [m DerivClause]
-> m Dec
dataD ctxt tc tvs ksig cons derivs =
do
@@ -204,7 +207,7 @@ dataD ctxt tc tvs ksig cons derivs =
derivs1 <- sequenceA derivs
return (DataD ctxt1 tc tvs ksig cons1 derivs1)
-newtypeD :: Quote m => m Cxt -> Name -> [TyVarBndr ()] -> Maybe Kind -> m Con -> [m DerivClause]
+newtypeD :: Quote m => m Cxt -> Name -> [TyVarBndr BndrVis] -> Maybe Kind -> m Con -> [m DerivClause]
-> m Dec
newtypeD ctxt tc tvs ksig con derivs =
do
@@ -213,14 +216,14 @@ newtypeD ctxt tc tvs ksig con derivs =
derivs1 <- sequenceA derivs
return (NewtypeD ctxt1 tc tvs ksig con1 derivs1)
-typeDataD :: Quote m => Name -> [TyVarBndr ()] -> Maybe Kind -> [m Con]
+typeDataD :: Quote m => Name -> [TyVarBndr BndrVis] -> Maybe Kind -> [m Con]
-> m Dec
typeDataD tc tvs ksig cons =
do
cons1 <- sequenceA cons
return (TypeDataD tc tvs ksig cons1)
-classD :: Quote m => m Cxt -> Name -> [TyVarBndr ()] -> [FunDep] -> [m Dec] -> m Dec
+classD :: Quote m => m Cxt -> Name -> [TyVarBndr BndrVis] -> [FunDep] -> [m Dec] -> m Dec
classD ctxt cls tvs fds decs =
do
decs1 <- sequenceA decs
@@ -255,16 +258,16 @@ newtypeInstD ctxt tc tys ksig con derivs =
derivs1 <- sequenceA derivs
return (NewtypeInstD ctxt1 Nothing ty1 ksig con1 derivs1)
-dataFamilyD :: Quote m => Name -> [TyVarBndr ()] -> Maybe Kind -> m Dec
+dataFamilyD :: Quote m => Name -> [TyVarBndr BndrVis] -> Maybe Kind -> m Dec
dataFamilyD tc tvs kind
= pure $ DataFamilyD tc tvs kind
-openTypeFamilyD :: Quote m => Name -> [TyVarBndr ()] -> FamilyResultSig
+openTypeFamilyD :: Quote m => Name -> [TyVarBndr BndrVis] -> FamilyResultSig
-> Maybe InjectivityAnn -> m Dec
openTypeFamilyD tc tvs res inj
= pure $ OpenTypeFamilyD (TypeFamilyHead tc tvs res inj)
-closedTypeFamilyD :: Quote m => Name -> [TyVarBndr ()] -> FamilyResultSig
+closedTypeFamilyD :: Quote m => Name -> [TyVarBndr BndrVis] -> FamilyResultSig
-> Maybe InjectivityAnn -> [m TySynEqn] -> m Dec
closedTypeFamilyD tc tvs result injectivity eqns =
do eqns1 <- sequenceA eqns
@@ -298,11 +301,23 @@ sigT t k
-------------------------------------------------------------------------------
-- * Kind
-plainTV :: Name -> TyVarBndr ()
-plainTV n = PlainTV n ()
+class DefaultBndrFlag flag where
+ defaultBndrFlag :: flag
-kindedTV :: Name -> Kind -> TyVarBndr ()
-kindedTV n k = KindedTV n () k
+instance DefaultBndrFlag () where
+ defaultBndrFlag = ()
+
+instance DefaultBndrFlag Specificity where
+ defaultBndrFlag = SpecifiedSpec
+
+instance DefaultBndrFlag BndrVis where
+ defaultBndrFlag = BndrReq
+
+plainTV :: DefaultBndrFlag flag => Name -> TyVarBndr flag
+plainTV n = PlainTV n defaultBndrFlag
+
+kindedTV :: DefaultBndrFlag flag => Name -> Kind -> TyVarBndr flag
+kindedTV n k = KindedTV n defaultBndrFlag k
starK :: Kind
starK = StarT
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
index 35bca47d25..b066061944 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
@@ -79,6 +79,7 @@ type InjectivityAnn = TH.InjectivityAnn
type TyVarBndrUnit = TyVarBndr ()
type TyVarBndrSpec = TyVarBndr Specificity
+type TyVarBndrVis = TyVarBndr BndrVis
----------------------------------------------------------
-- * Lowercase pattern syntax functions
@@ -412,14 +413,14 @@ funD nm cs =
; pure (FunD nm cs1)
}
-tySynD :: Quote m => Name -> [m (TyVarBndr ())] -> m Type -> m Dec
+tySynD :: Quote m => Name -> [m (TyVarBndr BndrVis)] -> m Type -> m Dec
tySynD tc tvs rhs =
do { tvs1 <- sequenceA tvs
; rhs1 <- rhs
; pure (TySynD tc tvs1 rhs1)
}
-dataD :: Quote m => m Cxt -> Name -> [m (TyVarBndr ())] -> Maybe (m Kind) -> [m Con]
+dataD :: Quote m => m Cxt -> Name -> [m (TyVarBndr BndrVis)] -> Maybe (m Kind) -> [m Con]
-> [m DerivClause] -> m Dec
dataD ctxt tc tvs ksig cons derivs =
do
@@ -430,7 +431,7 @@ dataD ctxt tc tvs ksig cons derivs =
derivs1 <- sequenceA derivs
pure (DataD ctxt1 tc tvs1 ksig1 cons1 derivs1)
-newtypeD :: Quote m => m Cxt -> Name -> [m (TyVarBndr ())] -> Maybe (m Kind) -> m Con
+newtypeD :: Quote m => m Cxt -> Name -> [m (TyVarBndr BndrVis)] -> Maybe (m Kind) -> m Con
-> [m DerivClause] -> m Dec
newtypeD ctxt tc tvs ksig con derivs =
do
@@ -441,7 +442,7 @@ newtypeD ctxt tc tvs ksig con derivs =
derivs1 <- sequenceA derivs
pure (NewtypeD ctxt1 tc tvs1 ksig1 con1 derivs1)
-typeDataD :: Quote m => Name -> [m (TyVarBndr ())] -> Maybe (m Kind) -> [m Con]
+typeDataD :: Quote m => Name -> [m (TyVarBndr BndrVis)] -> Maybe (m Kind) -> [m Con]
-> m Dec
typeDataD tc tvs ksig cons =
do
@@ -450,7 +451,7 @@ typeDataD tc tvs ksig cons =
cons1 <- sequenceA cons
pure (TypeDataD tc tvs1 ksig1 cons1)
-classD :: Quote m => m Cxt -> Name -> [m (TyVarBndr ())] -> [FunDep] -> [m Dec] -> m Dec
+classD :: Quote m => m Cxt -> Name -> [m (TyVarBndr BndrVis)] -> [FunDep] -> [m Dec] -> m Dec
classD ctxt cls tvs fds decs =
do
tvs1 <- sequenceA tvs
@@ -571,20 +572,20 @@ tySynInstD eqn =
eqn1 <- eqn
pure (TySynInstD eqn1)
-dataFamilyD :: Quote m => Name -> [m (TyVarBndr ())] -> Maybe (m Kind) -> m Dec
+dataFamilyD :: Quote m => Name -> [m (TyVarBndr BndrVis)] -> Maybe (m Kind) -> m Dec
dataFamilyD tc tvs kind =
do tvs' <- sequenceA tvs
kind' <- sequenceA kind
pure $ DataFamilyD tc tvs' kind'
-openTypeFamilyD :: Quote m => Name -> [m (TyVarBndr ())] -> m FamilyResultSig
+openTypeFamilyD :: Quote m => Name -> [m (TyVarBndr BndrVis)] -> m FamilyResultSig
-> Maybe InjectivityAnn -> m Dec
openTypeFamilyD tc tvs res inj =
do tvs' <- sequenceA tvs
res' <- res
pure $ OpenTypeFamilyD (TypeFamilyHead tc tvs' res' inj)
-closedTypeFamilyD :: Quote m => Name -> [m (TyVarBndr ())] -> m FamilyResultSig
+closedTypeFamilyD :: Quote m => Name -> [m (TyVarBndr BndrVis)] -> m FamilyResultSig
-> Maybe InjectivityAnn -> [m TySynEqn] -> m Dec
closedTypeFamilyD tc tvs result injectivity eqns =
do tvs1 <- sequenceA tvs
@@ -879,18 +880,30 @@ plainTV n = pure $ PlainTV n ()
plainInvisTV :: Quote m => Name -> Specificity -> m (TyVarBndr Specificity)
plainInvisTV n s = pure $ PlainTV n s
+plainBndrTV :: Quote m => Name -> BndrVis -> m (TyVarBndr BndrVis)
+plainBndrTV n v = pure $ PlainTV n v
+
kindedTV :: Quote m => Name -> m Kind -> m (TyVarBndr ())
kindedTV n = fmap (KindedTV n ())
kindedInvisTV :: Quote m => Name -> Specificity -> m Kind -> m (TyVarBndr Specificity)
kindedInvisTV n s = fmap (KindedTV n s)
+kindedBndrTV :: Quote m => Name -> BndrVis -> m Kind -> m (TyVarBndr BndrVis)
+kindedBndrTV n v = fmap (KindedTV n v)
+
specifiedSpec :: Specificity
specifiedSpec = SpecifiedSpec
inferredSpec :: Specificity
inferredSpec = InferredSpec
+bndrReq :: BndrVis
+bndrReq = BndrReq
+
+bndrInvis :: BndrVis
+bndrInvis = BndrInvis
+
varK :: Name -> Kind
varK = VarT
@@ -1091,7 +1104,7 @@ funD_doc nm cs mfun_doc arg_docs = do
Nothing -> funD nm cs
-- | Variant of 'dataD' that attaches Haddock documentation.
-dataD_doc :: Q Cxt -> Name -> [Q (TyVarBndr ())] -> Maybe (Q Kind)
+dataD_doc :: Q Cxt -> Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind)
-> [(Q Con, Maybe String, [Maybe String])]
-- ^ List of constructors, documentation for the constructor, and
-- documentation for the arguments
@@ -1105,7 +1118,7 @@ dataD_doc ctxt tc tvs ksig cons_with_docs derivs mdoc = do
maybe dec (flip withDecDoc dec) mdoc
-- | Variant of 'newtypeD' that attaches Haddock documentation.
-newtypeD_doc :: Q Cxt -> Name -> [Q (TyVarBndr ())] -> Maybe (Q Kind)
+newtypeD_doc :: Q Cxt -> Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind)
-> (Q Con, Maybe String, [Maybe String])
-- ^ The constructor, documentation for the constructor, and
-- documentation for the arguments
@@ -1119,7 +1132,7 @@ newtypeD_doc ctxt tc tvs ksig con_with_docs@(con, _, _) derivs mdoc = do
maybe dec (flip withDecDoc dec) mdoc
-- | Variant of 'typeDataD' that attaches Haddock documentation.
-typeDataD_doc :: Name -> [Q (TyVarBndr ())] -> Maybe (Q Kind)
+typeDataD_doc :: Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind)
-> [(Q Con, Maybe String, [Maybe String])]
-- ^ List of constructors, documentation for the constructor, and
-- documentation for the arguments
diff --git a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
index cedb974976..33fbcf8427 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
@@ -947,6 +947,14 @@ instance PprFlag Specificity where
pprTyVarBndr (KindedTV nm SpecifiedSpec k) = parens (ppr nm <+> dcolon <+> ppr k)
pprTyVarBndr (KindedTV nm InferredSpec k) = braces (ppr nm <+> dcolon <+> ppr k)
+instance PprFlag BndrVis where
+ pprTyVarBndr (PlainTV nm vis) = pprBndrVis vis (ppr nm)
+ pprTyVarBndr (KindedTV nm vis k) = pprBndrVis vis (parens (ppr nm <+> dcolon <+> ppr k))
+
+pprBndrVis :: BndrVis -> Doc -> Doc
+pprBndrVis BndrReq d = d
+pprBndrVis BndrInvis d = char '@' <> d
+
instance PprFlag flag => Ppr (TyVarBndr flag) where
ppr bndr = pprTyVarBndr bndr
diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
index 0304eb130b..af1ae4f8ab 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
@@ -3,7 +3,8 @@
RankNTypes, RoleAnnotations, ScopedTypeVariables,
MagicHash, KindSignatures, PolyKinds, TypeApplications, DataKinds,
GADTs, UnboxedTuples, UnboxedSums, TypeOperators,
- Trustworthy, DeriveFunctor, BangPatterns, RecordWildCards, ImplicitParams #-}
+ Trustworthy, DeriveFunctor, DeriveTraversable,
+ BangPatterns, RecordWildCards, ImplicitParams #-}
{-# OPTIONS_GHC -fno-warn-inline-rule-shadowing #-}
@@ -2392,22 +2393,22 @@ data Range = FromR Exp | FromThenR Exp Exp
data Dec
= FunD Name [Clause] -- ^ @{ f p1 p2 = b where decs }@
| ValD Pat Body [Dec] -- ^ @{ p = b where decs }@
- | DataD Cxt Name [TyVarBndr ()]
+ | DataD Cxt Name [TyVarBndr BndrVis]
(Maybe Kind) -- Kind signature (allowed only for GADTs)
[Con] [DerivClause]
-- ^ @{ data Cxt x => T x = A x | B (T x)
-- deriving (Z,W)
-- deriving stock Eq }@
- | NewtypeD Cxt Name [TyVarBndr ()]
+ | NewtypeD Cxt Name [TyVarBndr BndrVis]
(Maybe Kind) -- Kind signature
Con [DerivClause] -- ^ @{ newtype Cxt x => T x = A (B x)
-- deriving (Z,W Q)
-- deriving stock Eq }@
- | TypeDataD Name [TyVarBndr ()]
+ | TypeDataD Name [TyVarBndr BndrVis]
(Maybe Kind) -- Kind signature (allowed only for GADTs)
[Con] -- ^ @{ type data T x = A x | B (T x) }@
- | TySynD Name [TyVarBndr ()] Type -- ^ @{ type T x = (x,x) }@
- | ClassD Cxt Name [TyVarBndr ()]
+ | TySynD Name [TyVarBndr BndrVis] Type -- ^ @{ type T x = (x,x) }@
+ | ClassD Cxt Name [TyVarBndr BndrVis]
[FunDep] [Dec] -- ^ @{ class Eq a => Ord a where ds }@
| InstanceD (Maybe Overlap) Cxt Type [Dec]
-- ^ @{ instance {\-\# OVERLAPS \#-\}
@@ -2424,7 +2425,7 @@ data Dec
| PragmaD Pragma -- ^ @{ {\-\# INLINE [1] foo \#-\} }@
-- | data families (may also appear in [Dec] of 'ClassD' and 'InstanceD')
- | DataFamilyD Name [TyVarBndr ()]
+ | DataFamilyD Name [TyVarBndr BndrVis]
(Maybe Kind)
-- ^ @{ data family T a b c :: * }@
@@ -2548,7 +2549,7 @@ type PatSynType = Type
-- @TypeFamilyHead@ is defined to be the elements of the declaration
-- between @type family@ and @where@.
data TypeFamilyHead =
- TypeFamilyHead Name [TyVarBndr ()] FamilyResultSig (Maybe InjectivityAnn)
+ TypeFamilyHead Name [TyVarBndr BndrVis] FamilyResultSig (Maybe InjectivityAnn)
deriving( Show, Eq, Ord, Data, Generic )
-- | One equation of a type family instance or closed type family. The
@@ -2804,9 +2805,19 @@ data Specificity = SpecifiedSpec -- ^ @a@
| InferredSpec -- ^ @{a}@
deriving( Show, Eq, Ord, Data, Generic )
+-- | The @flag@ type parameter is instantiated to one of the following types:
+--
+-- * 'Specificity' (examples: 'ForallC', 'ForallT')
+-- * 'BndrVis' (examples: 'DataD', 'ClassD', etc.)
+-- * '()', a catch-all type for other forms of binders, including 'ForallVisT', 'DataInstD', 'RuleP', and 'TyVarSig'
+--
data TyVarBndr flag = PlainTV Name flag -- ^ @a@
| KindedTV Name flag Kind -- ^ @(a :: k)@
- deriving( Show, Eq, Ord, Data, Generic, Functor )
+ deriving( Show, Eq, Ord, Data, Generic, Functor, Foldable, Traversable )
+
+data BndrVis = BndrReq -- ^ @a@
+ | BndrInvis -- ^ @\@a@
+ deriving( Show, Eq, Ord, Data, Generic )
-- | Type family result signature
data FamilyResultSig = NoSig -- ^ no signature
diff --git a/libraries/template-haskell/changelog.md b/libraries/template-haskell/changelog.md
index bf63b6e689..90810b27f8 100644
--- a/libraries/template-haskell/changelog.md
+++ b/libraries/template-haskell/changelog.md
@@ -1,5 +1,14 @@
# Changelog for [`template-haskell` package](http://hackage.haskell.org/package/template-haskell)
+## 2.21.0.0
+
+ * Add `BndrVis` to support invisible binders
+ in type declarations (GHC Proposal #425).
+
+ * The binder flag type in `plainTV` and `kindedTV` is generalized from `()`
+ to any data type with a `DefaultBndrFlag` instance, including `()`,
+ `Specificity`, and `BndrVis`.
+
## 2.20.0.0
* The `Ppr.pprInfixT` function has gained a `Precedence` argument.
diff --git a/testsuite/tests/dependent/should_compile/T16344b.hs b/testsuite/tests/dependent/should_compile/T16344b.hs
index b89304f3b8..1b11c48708 100644
--- a/testsuite/tests/dependent/should_compile/T16344b.hs
+++ b/testsuite/tests/dependent/should_compile/T16344b.hs
@@ -5,6 +5,6 @@ module T16344 where
import Data.Kind
-- This one is accepted, even though it is polymorphic-recursive.
--- See Note [No polymorphic recursion] in GHC.Tc.Gen.HsType
+-- See Note [No polymorphic recursion in type decls] in GHC.Tc.TyCl
data T3 ka (a::ka) = forall b. MkT3 (T3 Type b)
diff --git a/testsuite/tests/dependent/should_fail/T16344a.hs b/testsuite/tests/dependent/should_fail/T16344a.hs
index 989352eb3d..fa75ed9618 100644
--- a/testsuite/tests/dependent/should_fail/T16344a.hs
+++ b/testsuite/tests/dependent/should_fail/T16344a.hs
@@ -6,6 +6,6 @@ import Data.Kind
-- This one is rejected, but in the typechecking phase
-- which is a bit nasty.
--- See Note [No polymorphic recursion] in GHC.Tc.Gen.HsType
+-- See Note [No polymorphic recursion in type decls] in GHC.Tc.TyCl
data T2 ka (a::ka) = MkT2 (T2 Type a)
diff --git a/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr b/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
index 484a56ecc0..8712e4e43c 100644
--- a/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
+++ b/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
@@ -76,7 +76,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:5:10 })
(Unqual
@@ -213,7 +213,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:9:10 })
(Unqual
@@ -348,7 +348,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:13:10 })
(Unqual
@@ -486,7 +486,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:17:10 })
(Unqual
@@ -684,7 +684,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:22:10 })
(Unqual
@@ -722,7 +722,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:22:28 })
(Unqual
@@ -961,7 +961,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:28:10 })
(Unqual
@@ -999,7 +999,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:28:28 })
(Unqual
@@ -1238,7 +1238,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:34:10 })
(Unqual
@@ -1276,7 +1276,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:34:28 })
(Unqual
@@ -1515,7 +1515,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:40:10 })
(Unqual
@@ -1553,7 +1553,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:40:28 })
(Unqual
@@ -1792,7 +1792,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:46:10 })
(Unqual
@@ -1830,7 +1830,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:46:28 })
(Unqual
@@ -2069,7 +2069,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:52:11 })
(Unqual
@@ -2107,7 +2107,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:52:30 })
(Unqual
diff --git a/testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr b/testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
index 1efed5e02e..d6f5038cf5 100644
--- a/testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
+++ b/testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
@@ -296,7 +296,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:21:11 })
(Unqual
diff --git a/testsuite/tests/indexed-types/should_fail/T9160.hs b/testsuite/tests/indexed-types/should_fail/T9160.hs
index cefa18d6f3..fb3a3ba336 100644
--- a/testsuite/tests/indexed-types/should_fail/T9160.hs
+++ b/testsuite/tests/indexed-types/should_fail/T9160.hs
@@ -7,7 +7,7 @@ $( do { cls_nm <- newName "C"
; a_nm <- newName "a"
; k_nm <- newName "k"
; f_nm <- newName "F"
- ; return [ClassD [] cls_nm [KindedTV a_nm () (VarT k_nm)] []
+ ; return [ClassD [] cls_nm [KindedTV a_nm BndrReq (VarT k_nm)] []
[OpenTypeFamilyD
(TypeFamilyHead f_nm [] (KindSig (VarT k_nm)) Nothing)]]})
diff --git a/testsuite/tests/parser/should_compile/DumpParsedAst.stderr b/testsuite/tests/parser/should_compile/DumpParsedAst.stderr
index 677988f0df..588d35efba 100644
--- a/testsuite/tests/parser/should_compile/DumpParsedAst.stderr
+++ b/testsuite/tests/parser/should_compile/DumpParsedAst.stderr
@@ -399,7 +399,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpParsedAst.hs:10:30 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpParsedAst.hs:10:21-22 })
(Unqual
@@ -491,7 +491,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpParsedAst.hs:15:8 })
(Unqual
@@ -508,7 +508,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpParsedAst.hs:15:17 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpParsedAst.hs:15:11 })
(Unqual
@@ -803,7 +803,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpParsedAst.hs:17:23 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpParsedAst.hs:17:17 })
(Unqual
@@ -835,7 +835,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpParsedAst.hs:17:40 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpParsedAst.hs:17:26 })
(Unqual
diff --git a/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr b/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
index e297ee8b84..31f8d36bb3 100644
--- a/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
+++ b/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
@@ -306,7 +306,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpRenamedAst.hs:12:30 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:12:21-22 })
{Name: as})
@@ -754,7 +754,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:22:8 })
{Name: f})))
@@ -770,7 +770,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpRenamedAst.hs:22:17 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:22:11 })
{Name: a})
@@ -965,7 +965,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpRenamedAst.hs:24:23 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:24:17 })
{Name: a})
@@ -989,7 +989,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpRenamedAst.hs:24:40 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:24:26 })
{Name: f})
@@ -1075,7 +1075,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:27:9 })
{Name: a})))])
@@ -1105,7 +1105,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:28:10 })
{Name: a})))
@@ -1119,7 +1119,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:28:12 })
{Name: b})))])
diff --git a/testsuite/tests/parser/should_compile/DumpSemis.stderr b/testsuite/tests/parser/should_compile/DumpSemis.stderr
index 4e283a73fe..72edeebe9c 100644
--- a/testsuite/tests/parser/should_compile/DumpSemis.stderr
+++ b/testsuite/tests/parser/should_compile/DumpSemis.stderr
@@ -1079,7 +1079,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { DumpSemis.hs:28:38 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpSemis.hs:28:24-28 })
(Unqual
diff --git a/testsuite/tests/parser/should_compile/KindSigs.stderr b/testsuite/tests/parser/should_compile/KindSigs.stderr
index df228cb912..60712f7b3b 100644
--- a/testsuite/tests/parser/should_compile/KindSigs.stderr
+++ b/testsuite/tests/parser/should_compile/KindSigs.stderr
@@ -177,7 +177,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { KindSigs.hs:11:17 })
(Unqual
@@ -226,7 +226,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { KindSigs.hs:15:10 })
(Unqual
@@ -412,7 +412,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { KindSigs.hs:16:11 })
(Unqual
@@ -1163,7 +1163,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { KindSigs.hs:28:12 })
(Unqual
@@ -1513,3 +1513,5 @@
{OccName: True}))))))]
(EmptyLocalBinds
(NoExtField)))))])))))]))
+
+
diff --git a/testsuite/tests/parser/should_compile/T15323.stderr b/testsuite/tests/parser/should_compile/T15323.stderr
index a3bc49d34f..176bab97a2 100644
--- a/testsuite/tests/parser/should_compile/T15323.stderr
+++ b/testsuite/tests/parser/should_compile/T15323.stderr
@@ -71,7 +71,7 @@
[]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T15323.hs:5:19 })
(Unqual
diff --git a/testsuite/tests/parser/should_compile/T20452.stderr b/testsuite/tests/parser/should_compile/T20452.stderr
index f05cef65b8..92260a5df4 100644
--- a/testsuite/tests/parser/should_compile/T20452.stderr
+++ b/testsuite/tests/parser/should_compile/T20452.stderr
@@ -73,7 +73,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:5:21 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:5:15 })
(Unqual
@@ -163,7 +163,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:6:22 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:6:15 })
(Unqual
@@ -265,7 +265,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:8:26 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:8:16-18 })
(Unqual
@@ -297,7 +297,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:8:45 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:8:31-34 })
(Unqual
@@ -329,7 +329,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:8:75 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:8:50-52 })
(Unqual
@@ -461,7 +461,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:9:27 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:9:16-18 })
(Unqual
@@ -495,7 +495,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:9:46 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:9:31-34 })
(Unqual
@@ -529,7 +529,7 @@
,(AddEpAnn AnnCloseP (EpaSpan { T20452.hs:9:76 }))]
(EpaComments
[]))
- (())
+ (HsBndrRequired)
(L
(SrcSpanAnn (EpAnnNotUsed) { T20452.hs:9:50-52 })
(Unqual
diff --git a/testsuite/tests/polykinds/T7022a.hs b/testsuite/tests/polykinds/T7022a.hs
index ee71b806c1..62643cba4b 100644
--- a/testsuite/tests/polykinds/T7022a.hs
+++ b/testsuite/tests/polykinds/T7022a.hs
@@ -9,5 +9,5 @@ makeSList :: Q [Dec]
makeSList = do
a <- newName "a"
k <- newName "k"
- return [TySynD (mkName "SList") [KindedTV a () (AppT ListT (VarT k))]
+ return [TySynD (mkName "SList") [KindedTV a BndrReq (AppT ListT (VarT k))]
(AppT (ConT (mkName "Sing")) (VarT a))]
diff --git a/testsuite/tests/th/ClosedFam2TH.hs b/testsuite/tests/th/ClosedFam2TH.hs
index 43ccf216f8..8786e24aa6 100644
--- a/testsuite/tests/th/ClosedFam2TH.hs
+++ b/testsuite/tests/th/ClosedFam2TH.hs
@@ -8,8 +8,8 @@ import Language.Haskell.TH
$( return [ ClosedTypeFamilyD
(TypeFamilyHead
(mkName "Equals")
- [ KindedTV (mkName "a") () (VarT (mkName "k"))
- , KindedTV (mkName "b") () (VarT (mkName "k")) ]
+ [ KindedTV (mkName "a") BndrReq (VarT (mkName "k"))
+ , KindedTV (mkName "b") BndrReq (VarT (mkName "k")) ]
( TyVarSig (KindedTV (mkName "r") () (VarT (mkName "k"))))
Nothing)
[ TySynEqn Nothing
@@ -30,7 +30,7 @@ b = False
$( return [ ClosedTypeFamilyD
(TypeFamilyHead
(mkName "Foo")
- [ KindedTV (mkName "a") () (VarT (mkName "k"))]
+ [ KindedTV (mkName "a") BndrReq (VarT (mkName "k"))]
(KindSig StarT ) Nothing )
[ TySynEqn Nothing
(AppT (AppKindT (ConT (mkName "Foo")) StarT)
diff --git a/testsuite/tests/th/T10828.hs b/testsuite/tests/th/T10828.hs
index ffb4525f6a..99bc28a777 100644
--- a/testsuite/tests/th/T10828.hs
+++ b/testsuite/tests/th/T10828.hs
@@ -31,7 +31,7 @@ $( do { decl <- [d| data family D a :: Type -> Type
$( return
[ DataD [] (mkName "T")
- [ PlainTV (mkName "a") () ]
+ [ PlainTV (mkName "a") BndrReq ]
(Just StarT)
[ GadtC [(mkName "MkT")]
[ ( Bang NoSourceUnpackedness NoSourceStrictness
diff --git a/testsuite/tests/th/T10828a.hs b/testsuite/tests/th/T10828a.hs
index d66547bad7..85866e5a77 100644
--- a/testsuite/tests/th/T10828a.hs
+++ b/testsuite/tests/th/T10828a.hs
@@ -8,7 +8,7 @@ import System.IO
-- attempting to place a kind signature on a H98 data type
$( return
[ DataD [] (mkName "T")
- [ PlainTV (mkName "a") () ]
+ [ PlainTV (mkName "a") BndrReq ]
(Just StarT)
[ NormalC (mkName "MkT")
[ ( Bang NoSourceUnpackedness NoSourceStrictness
diff --git a/testsuite/tests/th/T10828b.hs b/testsuite/tests/th/T10828b.hs
index 03706d6b7c..9dd12d9a06 100644
--- a/testsuite/tests/th/T10828b.hs
+++ b/testsuite/tests/th/T10828b.hs
@@ -8,7 +8,7 @@ import System.IO
-- attempting to mix GADT and normal constructors
$( return
[ DataD [] (mkName "T")
- [ PlainTV (mkName "a") () ]
+ [ PlainTV (mkName "a") BndrReq ]
(Just StarT)
[ NormalC
(mkName "MkT")
diff --git a/testsuite/tests/th/T11345.hs b/testsuite/tests/th/T11345.hs
index 2288cdad15..913671e3e0 100644
--- a/testsuite/tests/th/T11345.hs
+++ b/testsuite/tests/th/T11345.hs
@@ -15,7 +15,7 @@ $(do gadtName <- newName "GADT2"
prefixName <- newName "Prefix2"
infixName <- newName ":****:"
a <- newName "a"
- return [ DataD [] gadtName [KindedTV a () StarT] Nothing
+ return [ DataD [] gadtName [KindedTV a BndrReq StarT] Nothing
[ GadtC [prefixName]
[ (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int)
, (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int)
diff --git a/testsuite/tests/th/T12503.hs b/testsuite/tests/th/T12503.hs
index d1e3f27a93..f811763ce2 100644
--- a/testsuite/tests/th/T12503.hs
+++ b/testsuite/tests/th/T12503.hs
@@ -9,7 +9,7 @@ import Language.Haskell.TH
data T1 k
class C1 a
-$(do TyConI (DataD [] tName [ KindedTV kName () kKind] _ _ _)
+$(do TyConI (DataD [] tName [KindedTV kName BndrReq kKind] _ _ _)
<- reify ''T1
d <- instanceD (cxt [])
(conT ''C1 `appT`
diff --git a/testsuite/tests/th/T13098.hs b/testsuite/tests/th/T13098.hs
index e6a541cc55..6679d21238 100644
--- a/testsuite/tests/th/T13098.hs
+++ b/testsuite/tests/th/T13098.hs
@@ -6,7 +6,7 @@ module T13098 where
import Language.Haskell.TH
-$( sequence [ dataD (cxt []) (mkName "T") [PlainTV (mkName "a") ()]
+$( sequence [ dataD (cxt []) (mkName "T") [PlainTV (mkName "a") BndrReq]
Nothing [normalC (mkName "T") []] []
, pragCompleteD [mkName "T"] Nothing ] )
diff --git a/testsuite/tests/th/T6018th.hs b/testsuite/tests/th/T6018th.hs
index 4fa0eb3716..a75989806e 100644
--- a/testsuite/tests/th/T6018th.hs
+++ b/testsuite/tests/th/T6018th.hs
@@ -14,7 +14,7 @@ import Language.Haskell.TH
$( return
[ OpenTypeFamilyD (TypeFamilyHead
(mkName "F")
- [ PlainTV (mkName "a") (), PlainTV (mkName "b") (), PlainTV (mkName "c") () ]
+ [ PlainTV (mkName "a") BndrReq, PlainTV (mkName "b") BndrReq, PlainTV (mkName "c") BndrReq ]
(TyVarSig (KindedTV (mkName "result") () (VarT (mkName "k"))))
(Just $ InjectivityAnn (mkName "result")
[(mkName "a"), (mkName "b"), (mkName "c") ]))
@@ -41,7 +41,7 @@ $( return
$( return
[ OpenTypeFamilyD (TypeFamilyHead
(mkName "J")
- [ PlainTV (mkName "a") (), KindedTV (mkName "b") () (VarT (mkName "k")) ]
+ [ PlainTV (mkName "a") BndrReq, KindedTV (mkName "b") BndrReq (VarT (mkName "k")) ]
(TyVarSig (PlainTV (mkName "r") ()))
(Just $ InjectivityAnn (mkName "r") [mkName "a"]))
, TySynInstD
@@ -60,8 +60,8 @@ $( return
$( return
[ ClosedTypeFamilyD (TypeFamilyHead
(mkName "I")
- [ KindedTV (mkName "a") () StarT, KindedTV (mkName "b") () StarT
- , KindedTV (mkName "c") () StarT ]
+ [ KindedTV (mkName "a") BndrReq StarT, KindedTV (mkName "b") BndrReq StarT
+ , KindedTV (mkName "c") BndrReq StarT ]
(TyVarSig (PlainTV (mkName "r") ()))
(Just $ InjectivityAnn (mkName "r") [(mkName "a"), (mkName "b")]))
@@ -98,7 +98,7 @@ $( do { decl@([ClosedTypeFamilyD (TypeFamilyHead _ _ _ (Just inj)) _]) <-
$( return
[ OpenTypeFamilyD (TypeFamilyHead
(mkName "H")
- [ PlainTV (mkName "a") (), PlainTV (mkName "b") (), PlainTV (mkName "c") () ]
+ [ PlainTV (mkName "a") BndrReq, PlainTV (mkName "b") BndrReq, PlainTV (mkName "c") BndrReq ]
(TyVarSig (PlainTV (mkName "r") ()))
(Just $ InjectivityAnn (mkName "r")
[(mkName "a"), (mkName "b") ]))
diff --git a/testsuite/tests/th/T7667.hs b/testsuite/tests/th/T7667.hs
index eef6fd2cb0..e2730a3587 100644
--- a/testsuite/tests/th/T7667.hs
+++ b/testsuite/tests/th/T7667.hs
@@ -4,5 +4,5 @@ module T7667 where
import Language.Haskell.TH
-$( return [ TySynD (mkName "+") [PlainTV (mkName "a") (), PlainTV (mkName "b") ()]
+$( return [ TySynD (mkName "+") [PlainTV (mkName "a") BndrReq, PlainTV (mkName "b") BndrReq]
(AppT (AppT (ConT ''Either) (VarT $ mkName "a")) (VarT $ mkName "b")) ] )
diff --git a/testsuite/tests/th/T8499.hs b/testsuite/tests/th/T8499.hs
index d9278b4113..fcc70c73b2 100644
--- a/testsuite/tests/th/T8499.hs
+++ b/testsuite/tests/th/T8499.hs
@@ -8,5 +8,5 @@ import Language.Haskell.TH
$( do TyConI (DataD _ _ [KindedTV tvb_a _ _] _ _ _) <- reify ''Maybe
my_a <- newName "a"
return [TySynD (mkName "SMaybe")
- [KindedTV my_a () (AppT (ConT ''Maybe) (VarT tvb_a))]
+ [KindedTV my_a BndrReq (AppT (ConT ''Maybe) (VarT tvb_a))]
(TupleT 0)] )
diff --git a/testsuite/tests/th/TH_RichKinds2.hs b/testsuite/tests/th/TH_RichKinds2.hs
index 00387c7b4c..6be859bda8 100644
--- a/testsuite/tests/th/TH_RichKinds2.hs
+++ b/testsuite/tests/th/TH_RichKinds2.hs
@@ -14,10 +14,10 @@ import Data.List (splitAt, span, elemIndex)
import Language.Haskell.TH
$(return [OpenTypeFamilyD (TypeFamilyHead
- (mkName "Map") [KindedTV (mkName "f") ()
+ (mkName "Map") [KindedTV (mkName "f") BndrReq
(AppT (AppT ArrowT (VarT (mkName "k1")))
(VarT (mkName "k2"))),
- KindedTV (mkName "l") ()
+ KindedTV (mkName "l") BndrReq
(AppT ListT
(VarT (mkName "k1")))]
(KindSig (AppT ListT (VarT (mkName "k2")))) Nothing)])
diff --git a/testsuite/tests/th/TH_Roles1.hs b/testsuite/tests/th/TH_Roles1.hs
index 6ac6128885..83db2d7a80 100644
--- a/testsuite/tests/th/TH_Roles1.hs
+++ b/testsuite/tests/th/TH_Roles1.hs
@@ -4,6 +4,6 @@ module TH_Roles1 where
import Language.Haskell.TH
-$( return [ DataD [] (mkName "T") [PlainTV (mkName "a") ()] Nothing [] []
+$( return [ DataD [] (mkName "T") [PlainTV (mkName "a") BndrReq] Nothing [] []
, RoleAnnotD (mkName "T") [RepresentationalR] ] )
diff --git a/testsuite/tests/th/TH_Roles2.hs b/testsuite/tests/th/TH_Roles2.hs
index e6a0df0c52..71b9f47c37 100644
--- a/testsuite/tests/th/TH_Roles2.hs
+++ b/testsuite/tests/th/TH_Roles2.hs
@@ -4,7 +4,7 @@ module TH_Roles2 where
import Language.Haskell.TH
-$( return [ DataD [] (mkName "T") [KindedTV (mkName "a") () (VarT (mkName "k"))]
+$( return [ DataD [] (mkName "T") [KindedTV (mkName "a") BndrReq (VarT (mkName "k"))]
Nothing [] []
, RoleAnnotD (mkName "T") [RepresentationalR] ] )
diff --git a/testsuite/tests/th/TH_reifyDecl1.stderr b/testsuite/tests/th/TH_reifyDecl1.stderr
index 2c1ee67d88..7bf28179b2 100644
--- a/testsuite/tests/th/TH_reifyDecl1.stderr
+++ b/testsuite/tests/th/TH_reifyDecl1.stderr
@@ -1,6 +1,9 @@
-data TH_reifyDecl1.T = TH_reifyDecl1.A | TH_reifyDecl1.B
+data TH_reifyDecl1.T
+ = TH_reifyDecl1.A
+ | TH_reifyDecl1.B
data TH_reifyDecl1.R (a_0 :: *)
- = TH_reifyDecl1.C a_0 | TH_reifyDecl1.D
+ = TH_reifyDecl1.C a_0
+ | TH_reifyDecl1.D
data TH_reifyDecl1.List (a_0 :: *)
= TH_reifyDecl1.Nil
| TH_reifyDecl1.Cons a_0 (TH_reifyDecl1.List a_0)
diff --git a/testsuite/tests/typecheck/should_compile/T22560a.hs b/testsuite/tests/typecheck/should_compile/T22560a.hs
new file mode 100644
index 0000000000..3bf71bda67
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T22560a.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module T22560a where
+
+import Data.Kind
+import Data.Proxy
+
+-- Invisible binders in type declarations with standalone kind signatures:
+--
+-- 1. data
+-- 2. newtype
+-- 3. type
+-- 4. class
+-- 5. type family
+-- 6. data family
+--
+-- Properties that we test:
+--
+-- a) the @-binder syntax is accepted in type declaration headers
+-- b) the bound variable is in scope in subsequent binders and on the RHS
+-- c) the name of the variable in the standalone kind signature and in the
+-- type declaration header need not coincide (we use k/j)
+
+type D :: forall k. k -> Type
+data D @j (a :: j) = MkD (Proxy j) (Proxy a)
+
+type N :: forall k. k -> Type
+newtype N @j (a :: j) = MkN (Proxy a -> Proxy j)
+
+type S :: forall k. k -> Type
+type S @j (a :: j) = Proxy a -> Proxy j
+
+type C :: forall k. k -> Constraint
+class C @j (a :: j) where
+ f :: Proxy a -> Proxy j
+
+type F :: forall k. k -> k
+type family F @j (a :: j) where
+ F a = a \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_compile/T22560b.hs b/testsuite/tests/typecheck/should_compile/T22560b.hs
new file mode 100644
index 0000000000..dbfb1189eb
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T22560b.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE DataKinds #-}
+
+module T22560b where
+
+import Data.Kind
+
+data P a b = MkP
+
+type C :: forall i. (i -> i -> i) -> Constraint
+class C @i a where
+ p :: P a i
+
+p' :: forall i (a :: i -> i -> i). C a => P a i
+p' = p
+
+type T1 :: forall k. Maybe k
+type T1 @a = Nothing :: Maybe a
+
+type T2 :: forall k. Maybe (Maybe k)
+type T2 @a = Just (Nothing :: Maybe a) \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_compile/T22560c.hs b/testsuite/tests/typecheck/should_compile/T22560c.hs
new file mode 100644
index 0000000000..3398e207a0
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T22560c.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DataKinds #-}
+
+module T22560c where
+
+import Data.Kind
+import Data.Proxy
+
+-- Associated type and data families with @-binders
+type C :: forall k. k -> Constraint
+class C @j (a :: j) where
+ type F @j a
+ data D @j a
+ f :: Proxy a -> F @j a
+ g :: Proxy a -> D @j a
+
+-- Instance with an @-binder in F, D
+instance C True where
+ type F @Bool True = ()
+ data D @Bool True = MkTrue
+ f _ = ()
+ g _ = MkTrue
+
+-- Instance without an @-binder in F, D
+instance C False where
+ type F False = ()
+ data D False = MkFalse
+ f _ = ()
+ g _ = MkFalse \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_compile/T22560d.hs b/testsuite/tests/typecheck/should_compile/T22560d.hs
new file mode 100644
index 0000000000..eef8e74806
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T22560d.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE CUSKs #-}
+
+module T22560d where
+
+import Data.Kind
+import Data.Proxy
+
+-- type B :: forall k. k -> forall j. j -> Type
+data B @(k :: Type) (a :: k) @(j :: Type) (b :: j)
+
+-- type D :: forall k. k -> Type
+data D @(k :: Type) (a :: k) = MkD (Proxy k) (Proxy a)
+
+-- type N :: forall k. k -> Type
+newtype N @(k :: Type) (a :: k) = MkN (Proxy a -> Proxy k)
+
+-- type S :: forall k. k -> Type
+type S @(k :: Type) (a :: k) = Proxy a -> Proxy k :: Type
+
+-- type C :: forall k. k -> Constraint
+class C @(k :: Type) (a :: k) where
+ f :: Proxy a -> Proxy k
+
+-- type F :: forall k. k -> k
+type family F @(k :: Type) (a :: k) :: k where
+ F a = a
+
+-- type U :: forall k (a :: k). Type
+type U @(a :: k) = Int :: Type
+
+-- type Z :: forall k -> forall (a :: k). Type
+type Z (k :: Type) @(a :: k) = Proxy a :: Type \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_compile/T22560d.script b/testsuite/tests/typecheck/should_compile/T22560d.script
new file mode 100644
index 0000000000..e5c67edafb
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T22560d.script
@@ -0,0 +1,10 @@
+:load T22560d.hs
+:set -fprint-explicit-foralls -XNoStarIsType
+:kind B
+:kind D
+:kind N
+:kind S
+:kind C
+:kind F
+:kind U
+:kind Z \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_compile/T22560d.stdout b/testsuite/tests/typecheck/should_compile/T22560d.stdout
new file mode 100644
index 0000000000..cb08cfc9e1
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T22560d.stdout
@@ -0,0 +1,8 @@
+B :: forall k. k -> forall j. j -> Type
+D :: forall k. k -> Type
+N :: forall k. k -> Type
+S :: forall k. k -> Type
+C :: forall k. k -> Constraint
+F :: forall k. k -> k
+U :: forall k (a :: k). Type
+Z :: forall k -> forall (a :: k). Type
diff --git a/testsuite/tests/typecheck/should_compile/T22560e.hs b/testsuite/tests/typecheck/should_compile/T22560e.hs
new file mode 100644
index 0000000000..0b97632b9e
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T22560e.hs
@@ -0,0 +1,9 @@
+module T22560e where
+
+import Data.Kind
+import Data.Proxy
+
+type X = forall k. k -> Type
+
+type Y :: X
+type Y @k (a :: k) = Proxy a \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T
index 07d39cebd3..09b0951047 100644
--- a/testsuite/tests/typecheck/should_compile/all.T
+++ b/testsuite/tests/typecheck/should_compile/all.T
@@ -857,3 +857,8 @@ test('T22647', normal, compile, [''])
test('T19577', normal, compile, [''])
test('T22383', normal, compile, [''])
test('T21501', normal, compile, [''])
+test('T22560a', normal, compile, [''])
+test('T22560b', normal, compile, [''])
+test('T22560c', normal, compile, [''])
+test('T22560d', extra_files(['T22560d.hs']), ghci_script, ['T22560d.script'])
+test('T22560e', normal, compile, [''])
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_a.hs b/testsuite/tests/typecheck/should_fail/T22560_fail_a.hs
new file mode 100644
index 0000000000..e30a2f8391
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_a.hs
@@ -0,0 +1,7 @@
+module T22560_fail_a where
+
+import Data.Kind (Type)
+
+-- NB: the inferred forall is always skipped
+type P :: forall {k}. k -> Type
+data P @k a = MkP k \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_a.stderr b/testsuite/tests/typecheck/should_fail/T22560_fail_a.stderr
new file mode 100644
index 0000000000..7b929d8104
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_a.stderr
@@ -0,0 +1,8 @@
+
+T22560_fail_a.hs:7:1: error: [GHC-57916]
+ • Invalid invisible type variable binder: @k
+ There is no matching forall-bound variable
+ in the standalone kind signature for ‘P’.
+ NB. Only ‘forall a.’ -quantification matches invisible binders,
+ whereas ‘forall {a}.’ and ‘forall a ->’ do not.
+ • In the data type declaration for ‘P’
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_b.hs b/testsuite/tests/typecheck/should_fail/T22560_fail_b.hs
new file mode 100644
index 0000000000..8d824c9996
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_b.hs
@@ -0,0 +1,6 @@
+module T22560_fail_b where
+
+import Data.Kind (Type)
+
+type P :: forall a -> Type
+data P @a = MkP \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_b.stderr b/testsuite/tests/typecheck/should_fail/T22560_fail_b.stderr
new file mode 100644
index 0000000000..9693cac827
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_b.stderr
@@ -0,0 +1,8 @@
+
+T22560_fail_b.hs:6:1: error: [GHC-57916]
+ • Invalid invisible type variable binder: @a
+ There is no matching forall-bound variable
+ in the standalone kind signature for ‘P’.
+ NB. Only ‘forall a.’ -quantification matches invisible binders,
+ whereas ‘forall {a}.’ and ‘forall a ->’ do not.
+ • In the data type declaration for ‘P’
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_c.hs b/testsuite/tests/typecheck/should_fail/T22560_fail_c.hs
new file mode 100644
index 0000000000..1d111c7162
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_c.hs
@@ -0,0 +1,6 @@
+module T22560_fail_c where
+
+import Data.Kind
+
+type Dup :: forall k j. k -> Type
+data Dup @k @k (a :: k) \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_c.stderr b/testsuite/tests/typecheck/should_fail/T22560_fail_c.stderr
new file mode 100644
index 0000000000..115c70cc5a
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_c.stderr
@@ -0,0 +1,5 @@
+
+T22560_fail_c.hs:6:11: error:
+ Conflicting definitions for ‘k’
+ Bound at: T22560_fail_c.hs:6:11
+ T22560_fail_c.hs:6:14
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_d.hs b/testsuite/tests/typecheck/should_fail/T22560_fail_d.hs
new file mode 100644
index 0000000000..65fc4282d2
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_d.hs
@@ -0,0 +1,5 @@
+module T22560_fail_d where
+
+import Data.Kind
+
+data T @k (a :: k) -- No CUSK, no SAKS \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_d.stderr b/testsuite/tests/typecheck/should_fail/T22560_fail_d.stderr
new file mode 100644
index 0000000000..b59036c29e
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_d.stderr
@@ -0,0 +1,8 @@
+
+T22560_fail_d.hs:5:1: error: [GHC-92337]
+ • Invalid invisible type variable binder: @k
+ Either a standalone kind signature (SAKS)
+ or a complete user-supplied kind (CUSK, legacy feature)
+ is required to use invisible binders.
+ • In the data type declaration for ‘T’
+ Suggested fix: Add a standalone kind signature for ‘T’
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_ext.hs b/testsuite/tests/typecheck/should_fail/T22560_fail_ext.hs
new file mode 100644
index 0000000000..f301767a98
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_ext.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE NoTypeAbstractions #-}
+
+module T22560_fail_ext where
+
+import Data.Kind
+
+data T @k (a :: k) @(j :: Type) (b :: j) \ No newline at end of file
diff --git a/testsuite/tests/typecheck/should_fail/T22560_fail_ext.stderr b/testsuite/tests/typecheck/should_fail/T22560_fail_ext.stderr
new file mode 100644
index 0000000000..890c356d4e
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T22560_fail_ext.stderr
@@ -0,0 +1,8 @@
+
+T22560_fail_ext.hs:7:1: error: [GHC-58589]
+ Illegal invisible type variable binder: @(j :: Type)
+ Suggested fix: Perhaps you intended to use TypeAbstractions
+
+T22560_fail_ext.hs:7:1: error: [GHC-58589]
+ Illegal invisible type variable binder: @k
+ Suggested fix: Perhaps you intended to use TypeAbstractions
diff --git a/testsuite/tests/typecheck/should_fail/all.T b/testsuite/tests/typecheck/should_fail/all.T
index a7e9f6a678..c0ba90e673 100644
--- a/testsuite/tests/typecheck/should_fail/all.T
+++ b/testsuite/tests/typecheck/should_fail/all.T
@@ -667,3 +667,8 @@ test('T22570', normal, compile_fail, [''])
test('T22645', normal, compile_fail, [''])
test('T20666', normal, compile_fail, [''])
test('T20666a', normal, compile_fail, [''])
+test('T22560_fail_a', normal, compile_fail, [''])
+test('T22560_fail_b', normal, compile_fail, [''])
+test('T22560_fail_c', normal, compile_fail, [''])
+test('T22560_fail_d', normal, compile_fail, [''])
+test('T22560_fail_ext', normal, compile_fail, [''])
diff --git a/utils/check-exact/ExactPrint.hs b/utils/check-exact/ExactPrint.hs
index a569b803d4..0dfca9ec1a 100644
--- a/utils/check-exact/ExactPrint.hs
+++ b/utils/check-exact/ExactPrint.hs
@@ -3756,6 +3756,16 @@ instance ExactPrintTVFlag Specificity where
SpecifiedSpec -> (AnnOpenP, AnnCloseP)
InferredSpec -> (AnnOpenC, AnnCloseC)
+instance ExactPrintTVFlag (HsBndrVis GhcPs) where
+ exactTVDelimiters an0 bvis thing_inside = do
+ case bvis of
+ HsBndrRequired -> return ()
+ HsBndrInvisible at -> markToken at >> return ()
+ an1 <- markEpAnnAllL an0 lid AnnOpenP
+ r <- thing_inside
+ an2 <- markEpAnnAllL an1 lid AnnCloseP
+ return (an2, r)
+
instance ExactPrintTVFlag flag => ExactPrint (HsTyVarBndr flag GhcPs) where
getAnnotationEntry (UserTyVar an _ _) = fromAnn an
getAnnotationEntry (KindedTyVar an _ _ _) = fromAnn an
diff --git a/utils/haddock b/utils/haddock
-Subproject 519a95998b09a2c9c7a42c3a0cf2ca0c4358bb4
+Subproject 4f66a44a10fca90834c27a2afdcf3b5b494af86