summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2021-05-04 20:09:31 -0400
committerRyan Scott <ryan.gl.scott@gmail.com>2022-04-02 07:11:30 -0400
commitff8d81265090dc89e067a08028d9c598f72529ab (patch)
tree1e3393647bd970d9fa515529cadcce35aceff16b
parentd85c7dcb7c457efc23b20ac8f4e4ae88bae5b050 (diff)
downloadhaskell-wip/T18389-task-zero.tar.gz
Introduce and use ConGadtSigBody (preparatory refactor for #18389)wip/T18389-task-zero
This patch removes the `con_g_args :: HsConDeclGADTDetails pass` and `con_res_ty :: LHsType pass` fields of `ConDeclGADT` in favor of a unified `con_body :: ConGadtSigBody pass` field. There are two major differences between `HsConDeclGADTDetails` and `ConGadtSigBody`: 1. `HsConDeclGADTDetails` only contains the argument type, while `ConGadtSigBody` contains both the argument and result types. 2. The `PrefixConGADT` constructor of `ConGadtSigBody` now uses a new `PrefixConGadtSigBody` data type. `PrefixConGadtSigBody` closely mirrors the structure of `HsType`, but with minor, data constructor–specific tweaks. This will become vital in a future patch which implements nested `forall`s and contexts in prefix GADT constructor types (see #18389). Besides the refactoring in the GHC API (and some minor changes in GHC AST–related test cases) this does not introduce any user-visible changes in behavior.
-rw-r--r--compiler/GHC/Hs/Decls.hs26
-rw-r--r--compiler/GHC/Hs/Instances.hs13
-rw-r--r--compiler/GHC/Hs/Type.hs40
-rw-r--r--compiler/GHC/Hs/Utils.hs8
-rw-r--r--compiler/GHC/HsToCore/Docs.hs17
-rw-r--r--compiler/GHC/HsToCore/Quote.hs43
-rw-r--r--compiler/GHC/Iface/Ext/Ast.hs40
-rw-r--r--compiler/GHC/Parser/PostProcess.hs17
-rw-r--r--compiler/GHC/Parser/PostProcess/Haddock.hs28
-rw-r--r--compiler/GHC/Rename/HsType.hs29
-rw-r--r--compiler/GHC/Rename/Module.hs66
-rw-r--r--compiler/GHC/Rename/Names.hs2
-rw-r--r--compiler/GHC/Rename/Utils.hs2
-rw-r--r--compiler/GHC/Tc/TyCl.hs187
-rw-r--r--compiler/GHC/ThToHs.hs15
-rw-r--r--compiler/Language/Haskell/Syntax/Decls.hs85
-rw-r--r--compiler/Language/Haskell/Syntax/Type.hs6
-rw-r--r--testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr360
-rw-r--r--testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr64
-rw-r--r--testsuite/tests/indexed-types/should_compile/T14111b.hs23
-rw-r--r--testsuite/tests/indexed-types/should_compile/all.T1
-rw-r--r--testsuite/tests/parser/should_compile/DumpRenamedAst.stderr70
-rw-r--r--testsuite/tests/parser/should_compile/T15323.stderr62
-rw-r--r--testsuite/tests/printer/T18791.stderr36
-rw-r--r--utils/check-exact/ExactPrint.hs19
m---------utils/haddock0
26 files changed, 736 insertions, 523 deletions
diff --git a/compiler/GHC/Hs/Decls.hs b/compiler/GHC/Hs/Decls.hs
index 568783bdb5..a61b6f1514 100644
--- a/compiler/GHC/Hs/Decls.hs
+++ b/compiler/GHC/Hs/Decls.hs
@@ -76,7 +76,9 @@ module GHC.Hs.Decls (
CImportSpec(..),
-- ** Data-constructor declarations
ConDecl(..), LConDecl,
- HsConDeclH98Details, HsConDeclGADTDetails(..), hsConDeclTheta,
+ HsConDeclH98Details,
+ ConGadtSigBody(..), PrefixConGadtSigBody(..),
+ anonPrefixConGadtSigArgs, prefixConGadtSigRes, hsConDeclTheta,
getConNames, getRecConArgs_maybe,
-- ** Document comments
DocDecl(..), LDocDecl, docDeclDoc,
@@ -624,9 +626,9 @@ getRecConArgs_maybe (ConDeclH98{con_args = args}) = case args of
PrefixCon{} -> Nothing
RecCon flds -> Just flds
InfixCon{} -> Nothing
-getRecConArgs_maybe (ConDeclGADT{con_g_args = args}) = case args of
- PrefixConGADT{} -> Nothing
- RecConGADT flds _ -> Just flds
+getRecConArgs_maybe (ConDeclGADT{con_body = body}) = case body of
+ PrefixConGADT{} -> Nothing
+ RecConGADT flds _ _ -> Just flds
hsConDeclTheta :: Maybe (LHsContext (GhcPass p)) -> [LHsType (GhcPass p)]
hsConDeclTheta Nothing = []
@@ -701,14 +703,20 @@ pprConDecl (ConDeclH98 { con_name = L _ con
<+> pprConDeclFields (unLoc fields)
pprConDecl (ConDeclGADT { con_names = cons, con_bndrs = L _ outer_bndrs
- , con_mb_cxt = mcxt, con_g_args = args
- , con_res_ty = res_ty, con_doc = doc })
+ , con_mb_cxt = mcxt, con_body = body, con_doc = doc })
= pprMaybeWithDoc doc $ ppr_con_names cons <+> dcolon
<+> (sep [pprHsOuterSigTyVarBndrs outer_bndrs <+> pprLHsContext mcxt,
- sep (ppr_args args ++ [ppr res_ty]) ])
+ ppr_body body ])
where
- ppr_args (PrefixConGADT args) = map (\(HsScaled arr t) -> ppr t <+> ppr_arr arr) args
- ppr_args (RecConGADT fields _) = [pprConDeclFields (unLoc fields) <+> arrow]
+ ppr_body (PrefixConGADT args) = ppr_prefix_body args
+ ppr_body (RecConGADT fields _ res_ty) =
+ sep [ pprConDeclFields (unLoc fields)
+ , arrow <+> ppr res_ty ]
+
+ ppr_prefix_body (PCGSRes res_ty) = ppr res_ty
+ ppr_prefix_body (PCGSAnonArg (HsScaled arr arg) body') =
+ sep [ ppr arg
+ , ppr_arr arr <+> ppr_prefix_body body' ]
-- Display linear arrows as unrestricted with -XNoLinearTypes
-- (cf. dataConDisplayType in Note [Displaying linear fields] in GHC.Core.DataCon)
diff --git a/compiler/GHC/Hs/Instances.hs b/compiler/GHC/Hs/Instances.hs
index 987e47f047..780ece9ae8 100644
--- a/compiler/GHC/Hs/Instances.hs
+++ b/compiler/GHC/Hs/Instances.hs
@@ -181,10 +181,15 @@ deriving instance Data (ConDecl GhcPs)
deriving instance Data (ConDecl GhcRn)
deriving instance Data (ConDecl GhcTc)
--- deriving instance DataIdLR p p => Data (HsConDeclGADTDetails p)
-deriving instance Data (HsConDeclGADTDetails GhcPs)
-deriving instance Data (HsConDeclGADTDetails GhcRn)
-deriving instance Data (HsConDeclGADTDetails GhcTc)
+-- deriving instance DataIdLR p p => Data (ConGadtSigBody p)
+deriving instance Data (ConGadtSigBody GhcPs)
+deriving instance Data (ConGadtSigBody GhcRn)
+deriving instance Data (ConGadtSigBody GhcTc)
+
+-- deriving instance DataIdLR p p => Data (PrefixConGadtSigBody p)
+deriving instance Data (PrefixConGadtSigBody GhcPs)
+deriving instance Data (PrefixConGadtSigBody GhcRn)
+deriving instance Data (PrefixConGadtSigBody GhcTc)
-- deriving instance DataIdLR p p => Data (TyFamInstDecl p)
deriving instance Data (TyFamInstDecl GhcPs)
diff --git a/compiler/GHC/Hs/Type.hs b/compiler/GHC/Hs/Type.hs
index 208d7777f7..73bc26642d 100644
--- a/compiler/GHC/Hs/Type.hs
+++ b/compiler/GHC/Hs/Type.hs
@@ -74,7 +74,7 @@ module GHC.Hs.Type (
splitLHsPatSynTy,
splitLHsForAllTyInvis, splitLHsForAllTyInvis_KP, splitLHsQualTy,
splitLHsSigmaTyInvis, splitLHsGadtTy,
- splitHsFunType, hsTyGetAppHead_maybe,
+ splitLHsPrefixGadtSigBody, hsTyGetAppHead_maybe,
mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy,
ignoreParens, hsSigWcType, hsPatSigType,
hsTyKindSig,
@@ -89,6 +89,7 @@ module GHC.Hs.Type (
import GHC.Prelude
+import Language.Haskell.Syntax.Decls
import Language.Haskell.Syntax.Type
import {-# SOURCE #-} GHC.Hs.Expr ( pprSplice )
@@ -477,32 +478,41 @@ mkHsAppKindTy ext ty k
-}
---------------------------------
--- splitHsFunType decomposes a type (t1 -> t2 ... -> tn)
--- Breaks up any parens in the result type:
--- splitHsFunType (a -> (b -> c)) = ([a,b], c)
--- It returns API Annotations for any parens removed
-splitHsFunType ::
+-- | Decomposes the body of prefix GADT constructor type into its argument
+-- and result types, breaking up parentheses as necessary in the process.
+-- (See also 'splitLHsGadtTy', which decomposes the top-level @forall@s and
+-- context of a GADT constructor type.)
+-- For example:
+--
+-- @
+-- 'splitLHsPrefixGadtSigBody' (a -> (b -> T c)) =
+-- 'PCGSAnonArg' a ('PCGSAnonArg' b ('PCGSRes' (T c)))
+-- @
+--
+-- It returns exact print annotations for any parentheses removed, as well as
+-- for any associated comments.
+splitLHsPrefixGadtSigBody ::
LHsType (GhcPass p)
-> ( [AddEpAnn], EpAnnComments -- The locations of any parens and
- -- comments discarded
- , [HsScaled (GhcPass p) (LHsType (GhcPass p))], LHsType (GhcPass p))
-splitHsFunType ty = go ty
+ -- comments discarded
+ , PrefixConGadtSigBody (GhcPass p) )
+splitLHsPrefixGadtSigBody ty = go ty
where
go (L l (HsParTy an ty))
= let
- (anns, cs, args, res) = splitHsFunType ty
+ (anns, cs, body) = go ty
anns' = anns ++ annParen2AddEpAnn an
cs' = cs S.<> epAnnComments (ann l) S.<> epAnnComments an
- in (anns', cs', args, res)
+ in (anns', cs', body)
go (L ll (HsFunTy (EpAnn _ _ cs) mult x y))
- | (anns, csy, args, res) <- splitHsFunType y
- = (anns, csy S.<> epAnnComments (ann ll), HsScaled mult x':args, res)
+ | (anns, csy, body) <- go y
+ = (anns, csy S.<> epAnnComments (ann ll), PCGSAnonArg (HsScaled mult x') body)
where
L l t = x
x' = L (addCommentsToSrcAnn l cs) t
- go other = ([], emptyComments, [], other)
+ go res_ty = ([], emptyComments, PCGSRes res_ty)
-- | Retrieve the name of the \"head\" of a nested type application.
-- This is somewhat like @GHC.Tc.Gen.HsType.splitHsAppTys@, but a little more
@@ -597,7 +607,7 @@ splitLHsSigmaTyInvis ty
--
-- This function is careful not to look through parentheses.
-- See @Note [GADT abstract syntax] (Wrinkle: No nested foralls or contexts)@
--- "GHC.Hs.Decls" for why this is important.
+-- "Language.Haskell.Syntax.Decls" for why this is important.
splitLHsGadtTy ::
LHsSigType GhcPs
-> (HsOuterSigTyVarBndrs GhcPs, Maybe (LHsContext GhcPs), LHsType GhcPs)
diff --git a/compiler/GHC/Hs/Utils.hs b/compiler/GHC/Hs/Utils.hs
index ef5ad6e494..e945b3bc6e 100644
--- a/compiler/GHC/Hs/Utils.hs
+++ b/compiler/GHC/Hs/Utils.hs
@@ -1465,10 +1465,10 @@ hsConDeclsBinders cons
in case unLoc r of
-- remove only the first occurrence of any seen field in order to
-- avoid circumventing detection of duplicate fields (#9156)
- ConDeclGADT { con_names = names, con_g_args = args }
+ ConDeclGADT { con_names = names, con_body = body }
-> (map (L loc . unLoc) names ++ ns, flds ++ fs)
where
- (remSeen', flds) = get_flds_gadt remSeen args
+ (remSeen', flds) = get_flds_gadt remSeen body
(ns, fs) = go remSeen' rs
ConDeclH98 { con_name = name, con_args = args }
@@ -1482,9 +1482,9 @@ hsConDeclsBinders cons
get_flds_h98 remSeen (RecCon flds) = get_flds remSeen flds
get_flds_h98 remSeen _ = (remSeen, [])
- get_flds_gadt :: Seen p -> HsConDeclGADTDetails (GhcPass p)
+ get_flds_gadt :: Seen p -> ConGadtSigBody (GhcPass p)
-> (Seen p, [LFieldOcc (GhcPass p)])
- get_flds_gadt remSeen (RecConGADT flds _) = get_flds remSeen flds
+ get_flds_gadt remSeen (RecConGADT flds _ _) = get_flds remSeen flds
get_flds_gadt remSeen _ = (remSeen, [])
get_flds :: Seen p -> LocatedL [LConDeclField (GhcPass p)]
diff --git a/compiler/GHC/HsToCore/Docs.hs b/compiler/GHC/HsToCore/Docs.hs
index c4839ae449..372f444cf3 100644
--- a/compiler/GHC/HsToCore/Docs.hs
+++ b/compiler/GHC/HsToCore/Docs.hs
@@ -399,8 +399,8 @@ subordinates env instMap decl = case decl of
conArgDocs :: ConDecl GhcRn -> IntMap (HsDoc GhcRn)
conArgDocs (ConDeclH98{con_args = args}) =
h98ConArgDocs args
-conArgDocs (ConDeclGADT{con_g_args = args, con_res_ty = res_ty}) =
- gadtConArgDocs args (unLoc res_ty)
+conArgDocs (ConDeclGADT{con_body = body}) =
+ gadtConSigBodyDocs body
h98ConArgDocs :: HsConDeclH98Details GhcRn -> IntMap (HsDoc GhcRn)
h98ConArgDocs con_args = case con_args of
@@ -409,10 +409,15 @@ h98ConArgDocs con_args = case con_args of
, unLoc (hsScaledThing arg2) ]
RecCon _ -> IM.empty
-gadtConArgDocs :: HsConDeclGADTDetails GhcRn -> HsType GhcRn -> IntMap (HsDoc GhcRn)
-gadtConArgDocs con_args res_ty = case con_args of
- PrefixConGADT args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args ++ [res_ty]
- RecConGADT _ _ -> con_arg_docs 1 [res_ty]
+gadtConSigBodyDocs :: ConGadtSigBody GhcRn -> IntMap (HsDoc GhcRn)
+gadtConSigBodyDocs body = case body of
+ PrefixConGADT body' -> con_arg_docs 0 $ prefix_gadt_con_sig_body_tys body'
+ RecConGADT _ _ res_ty -> con_arg_docs 1 [unLoc res_ty]
+ where
+ prefix_gadt_con_sig_body_tys :: PrefixConGadtSigBody GhcRn -> [HsType GhcRn]
+ prefix_gadt_con_sig_body_tys (PCGSRes res_ty) = [unLoc res_ty]
+ prefix_gadt_con_sig_body_tys (PCGSAnonArg arg body') =
+ unLoc (hsScaledThing arg):prefix_gadt_con_sig_body_tys body'
con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn)
con_arg_docs n = IM.fromList . catMaybes . zipWith f [n..]
diff --git a/compiler/GHC/HsToCore/Quote.hs b/compiler/GHC/HsToCore/Quote.hs
index dfa634b399..d57fba4ef9 100644
--- a/compiler/GHC/HsToCore/Quote.hs
+++ b/compiler/GHC/HsToCore/Quote.hs
@@ -890,18 +890,17 @@ repC (L _ (ConDeclH98 { con_name = con
repC (L _ (ConDeclGADT { con_names = cons
, con_bndrs = L _ outer_bndrs
, con_mb_cxt = mcxt
- , con_g_args = args
- , con_res_ty = res_ty }))
+ , con_body = body }))
| null_outer_imp_tvs && null_outer_exp_tvs
-- No implicit or explicit variables
, Nothing <- mcxt -- No context
-- ==> no need for a forall
- = repGadtDataCons cons args res_ty
+ = repGadtDataCons cons body
| otherwise
= addHsOuterSigTyVarBinds outer_bndrs $ \ outer_bndrs' ->
-- See Note [Don't quantify implicit type variables in quotes]
- do { c' <- repGadtDataCons cons args res_ty
+ do { c' <- repGadtDataCons cons body
; ctxt' <- repMbContext mcxt
; if null_outer_exp_tvs && isNothing mcxt
then return c'
@@ -2685,22 +2684,40 @@ repH98DataCon con details
rep2 recCName [unC con', unC arg_vtys]
repGadtDataCons :: [LocatedN Name]
- -> HsConDeclGADTDetails GhcRn
- -> LHsType GhcRn
+ -> ConGadtSigBody GhcRn
-> MetaM (Core (M TH.Con))
-repGadtDataCons cons details res_ty
+repGadtDataCons cons body
= do cons' <- mapM lookupLOcc cons -- See Note [Binders and occurrences]
- case details of
- PrefixConGADT ps -> do
- arg_tys <- repPrefixConArgs ps
- res_ty' <- repLTy res_ty
- rep2 gadtCName [ unC (nonEmptyCoreList cons'), unC arg_tys, unC res_ty']
- RecConGADT ips _ -> do
+ case body of
+ PrefixConGADT prefix_body ->
+ repPrefixGadtDataCons cons' prefix_body
+ RecConGADT ips _ res_ty -> do
arg_vtys <- repRecConArgs ips
res_ty' <- repLTy res_ty
rep2 recGadtCName [unC (nonEmptyCoreList cons'), unC arg_vtys,
unC res_ty']
+repPrefixGadtDataCons :: [Core TH.Name]
+ -> PrefixConGadtSigBody GhcRn
+ -> MetaM (Core (M TH.Con))
+repPrefixGadtDataCons cons prefix_body = do
+ (arg_tys, core_arg_tys, core_res_ty) <- go prefix_body
+ verifyLinearFields arg_tys
+ core_arg_tys' <- coreListM bangTypeTyConName core_arg_tys
+ rep2 gadtCName [ unC (nonEmptyCoreList cons), unC core_arg_tys', unC core_res_ty]
+ where
+ go :: PrefixConGadtSigBody GhcRn
+ -> MetaM ( [HsScaled GhcRn (LHsType GhcRn)]
+ , [Core (M TH.BangType)]
+ , Core (M TH.Type) )
+ go (PCGSRes res_ty) = do
+ core_res_ty <- repLTy res_ty
+ pure ([], [], core_res_ty)
+ go (PCGSAnonArg arg_ty body) = do
+ core_arg_ty <- repBangTy (hsScaledThing arg_ty)
+ (arg_tys, core_arg_tys, core_res_ty) <- go body
+ pure (arg_ty:arg_tys, core_arg_ty:core_arg_tys, core_res_ty)
+
-- TH currently only supports linear constructors.
-- We also accept the (->) arrow when -XLinearTypes is off, because this
-- denotes a linear field.
diff --git a/compiler/GHC/Iface/Ext/Ast.hs b/compiler/GHC/Iface/Ext/Ast.hs
index 19f198e2c3..5fa5d0f281 100644
--- a/compiler/GHC/Iface/Ext/Ast.hs
+++ b/compiler/GHC/Iface/Ext/Ast.hs
@@ -1381,9 +1381,19 @@ instance (ToHie tyarg, ToHie arg, ToHie rec) => ToHie (HsConDetails tyarg arg re
toHie (RecCon rec) = toHie rec
toHie (InfixCon a b) = concatM [ toHie a, toHie b]
-instance ToHie (HsConDeclGADTDetails GhcRn) where
- toHie (PrefixConGADT args) = toHie args
- toHie (RecConGADT rec _) = toHie rec
+instance ToHie (ConGadtSigBody GhcRn) where
+ toHie (PrefixConGADT body) = toHie body
+ toHie (RecConGADT flds _ res_ty) = concatM
+ [ toHie flds
+ , toHie res_ty
+ ]
+
+instance ToHie (PrefixConGadtSigBody GhcRn) where
+ toHie (PCGSRes res_ty) = toHie res_ty
+ toHie (PCGSAnonArg arg_ty body) = concatM
+ [ toHie arg_ty
+ , toHie body
+ ]
instance HiePass p => ToHie (LocatedAn NoEpAnns (HsCmdTop (GhcPass p))) where
toHie (L span top) = concatM $ makeNodeA top span : case top of
@@ -1599,8 +1609,7 @@ instance ToHie a => ToHie (HsScaled GhcRn a) where
instance ToHie (LocatedA (ConDecl GhcRn)) where
toHie (L span decl) = concatM $ makeNode decl (locA span) : case decl of
ConDeclGADT { con_names = names, con_bndrs = L outer_bndrs_loc outer_bndrs
- , con_mb_cxt = ctx, con_g_args = args, con_res_ty = typ
- , con_doc = doc} ->
+ , con_mb_cxt = ctx, con_body = body, con_doc = doc } ->
[ toHie $ map (C (Decl ConDec $ getRealSpanA span)) names
, case outer_bndrs of
HsOuterImplicit{hso_ximplicit = imp_vars} ->
@@ -1609,18 +1618,23 @@ instance ToHie (LocatedA (ConDecl GhcRn)) where
HsOuterExplicit{hso_bndrs = exp_bndrs} ->
toHie $ tvScopes resScope NoScope exp_bndrs
, toHie ctx
- , toHie args
- , toHie typ
+ , toHie body
, toHie doc
]
where
- rhsScope = combineScopes argsScope tyScope
ctxScope = maybe NoScope mkLScopeA ctx
- argsScope = case args of
- PrefixConGADT xs -> scaled_args_scope xs
- RecConGADT x _ -> mkLScopeA x
- tyScope = mkLScopeA typ
+ rhsScope = case body of
+ PrefixConGADT prefix_body ->
+ prefix_con_gadt_sig_body_scope prefix_body
+ RecConGADT flds _ res_ty ->
+ combineScopes (mkLScopeA flds) (mkLScopeA res_ty)
resScope = ResolvedScopes [ctxScope, rhsScope]
+
+ prefix_con_gadt_sig_body_scope :: PrefixConGadtSigBody GhcRn -> Scope
+ prefix_con_gadt_sig_body_scope (PCGSRes res_ty) = mkLScopeA res_ty
+ prefix_con_gadt_sig_body_scope (PCGSAnonArg arg_ty body') =
+ combineScopes (mkLScopeA $ hsScaledThing arg_ty)
+ (prefix_con_gadt_sig_body_scope body')
ConDeclH98 { con_name = name, con_ex_tvs = qvars
, con_mb_cxt = ctx, con_args = dets
, con_doc = doc} ->
@@ -1637,7 +1651,7 @@ instance ToHie (LocatedA (ConDecl GhcRn)) where
PrefixCon _ xs -> scaled_args_scope xs
InfixCon a b -> scaled_args_scope [a, b]
RecCon x -> mkLScopeA x
- where scaled_args_scope :: [HsScaled GhcRn (LHsType GhcRn)] -> Scope
+ scaled_args_scope :: [HsScaled GhcRn (LHsType GhcRn)] -> Scope
scaled_args_scope = foldr combineScopes NoScope . map (mkLScopeA . hsScaledThing)
instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where
diff --git a/compiler/GHC/Parser/PostProcess.hs b/compiler/GHC/Parser/PostProcess.hs
index 568f5df5e6..74a44fa384 100644
--- a/compiler/GHC/Parser/PostProcess.hs
+++ b/compiler/GHC/Parser/PostProcess.hs
@@ -720,7 +720,8 @@ mkConDeclH98 ann name mb_forall mb_cxt args
-- * This splits up the constructor type into its quantified type variables (if
-- provided), context (if provided), argument types, and result type, and
-- records whether this is a prefix or record GADT constructor. See
--- Note [GADT abstract syntax] in "GHC.Hs.Decls" for more details.
+-- @Note [GADT abstract syntax]@ in "Language.Haskell.Syntax.Decls" for more
+-- details.
mkGadtDecl :: SrcSpan
-> [LocatedN RdrName]
-> LHsSigType GhcPs
@@ -730,7 +731,7 @@ mkGadtDecl loc names ty annsIn = do
cs <- getCommentsFor loc
let l = noAnnSrcSpan loc
- (args, res_ty, annsa, csa) <-
+ (body, annsa, csa) <-
case body_ty of
L ll (HsFunTy af hsArr (L loc' (HsRecTy an rf)) res_ty) -> do
let an' = addCommentsToEpAnn (locA loc') an (comments af)
@@ -740,22 +741,20 @@ mkGadtDecl loc names ty annsIn = do
(PsErrIllegalGadtRecordMultiplicity hsArr)
return noHsUniTok
- return ( RecConGADT (L (SrcSpanAnn an' (locA loc')) rf) arr, res_ty
+ return ( RecConGADT (L (SrcSpanAnn an' (locA loc')) rf) arr res_ty
, [], epAnnComments (ann ll))
_ -> do
- let (anns, cs, arg_types, res_type) = splitHsFunType body_ty
- return (PrefixConGADT arg_types, res_type, anns, cs)
+ let (anns, cs, prefix_body) = splitLHsPrefixGadtSigBody body_ty
+ return (PrefixConGADT prefix_body, anns, cs)
- let an = case outer_bndrs of
- _ -> EpAnn (spanAsAnchor loc) (annsIn ++ annsa) (cs Semi.<> csa)
+ let an = EpAnn (spanAsAnchor loc) (annsIn ++ annsa) (cs Semi.<> csa)
pure $ L l ConDeclGADT
{ con_g_ext = an
, con_names = names
, con_bndrs = L (getLoc ty) outer_bndrs
, con_mb_cxt = mcxt
- , con_g_args = args
- , con_res_ty = res_ty
+ , con_body = body
, con_doc = Nothing }
where
(outer_bndrs, mcxt, body_ty) = splitLHsGadtTy ty
diff --git a/compiler/GHC/Parser/PostProcess/Haddock.hs b/compiler/GHC/Parser/PostProcess/Haddock.hs
index 271d9db30f..2ce0dd5274 100644
--- a/compiler/GHC/Parser/PostProcess/Haddock.hs
+++ b/compiler/GHC/Parser/PostProcess/Haddock.hs
@@ -696,22 +696,14 @@ instance HasHaddock (LocatedA (ConDecl GhcPs)) where
addHaddock (L l_con_decl con_decl) =
extendHdkA (locA l_con_decl) $
case con_decl of
- ConDeclGADT { con_g_ext, con_names, con_bndrs, con_mb_cxt, con_g_args, con_res_ty } -> do
+ ConDeclGADT { con_g_ext, con_names, con_bndrs, con_mb_cxt, con_body } -> do
-- discardHasInnerDocs is ok because we don't need this info for GADTs.
con_doc' <- discardHasInnerDocs $ getConDoc (getLocA (head con_names))
- con_g_args' <-
- case con_g_args of
- PrefixConGADT ts -> PrefixConGADT <$> addHaddock ts
- RecConGADT (L l_rec flds) arr -> do
- -- discardHasInnerDocs is ok because we don't need this info for GADTs.
- flds' <- traverse (discardHasInnerDocs . addHaddockConDeclField) flds
- pure $ RecConGADT (L l_rec flds') arr
- con_res_ty' <- addHaddock con_res_ty
+ con_body' <- addHaddock con_body
pure $ L l_con_decl $
ConDeclGADT { con_g_ext, con_names, con_bndrs, con_mb_cxt,
con_doc = lexLHsDocString <$> con_doc',
- con_g_args = con_g_args',
- con_res_ty = con_res_ty' }
+ con_body = con_body' }
ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_args } ->
addConTrailingDoc (srcSpanEnd $ locA l_con_decl) $
case con_args of
@@ -738,6 +730,20 @@ instance HasHaddock (LocatedA (ConDecl GhcPs)) where
con_doc = lexLHsDocString <$> con_doc',
con_args = RecCon (L l_rec flds') }
+instance HasHaddock (ConGadtSigBody GhcPs) where
+ addHaddock (PrefixConGADT body) = PrefixConGADT <$> addHaddock body
+ addHaddock (RecConGADT (L l_rec flds) arr res_ty) = do
+ -- discardHasInnerDocs is ok because we don't need this info for GADTs.
+ flds' <- traverse (discardHasInnerDocs . addHaddockConDeclField) flds
+ res_ty' <- addHaddock res_ty
+ pure $ RecConGADT (L l_rec flds') arr res_ty'
+
+instance HasHaddock (PrefixConGadtSigBody GhcPs) where
+ addHaddock (PCGSAnonArg arg_ty body) =
+ PCGSAnonArg <$> addHaddock arg_ty <*> addHaddock body
+ addHaddock (PCGSRes res_ty) =
+ PCGSRes <$> addHaddock res_ty
+
-- Keep track of documentation comments on the data constructor or any of its
-- fields.
--
diff --git a/compiler/GHC/Rename/HsType.hs b/compiler/GHC/Rename/HsType.hs
index bbcd5244af..5d1da01b37 100644
--- a/compiler/GHC/Rename/HsType.hs
+++ b/compiler/GHC/Rename/HsType.hs
@@ -35,7 +35,7 @@ module GHC.Rename.HsType (
FreeKiTyVars, filterInScopeM,
extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars,
extractHsTysRdrTyVars, extractRdrKindSigVars,
- extractConDeclGADTDetailsTyVars, extractDataDefnKindVars,
+ extractConGadtSigBodyTyVars, extractDataDefnKindVars,
extractHsOuterTvBndrs, extractHsTyArgRdrKiTyVars,
nubL, nubN
) where
@@ -1903,14 +1903,21 @@ extractRdrKindSigVars (L _ resultSig) = case resultSig of
TyVarSig _ (L _ (KindedTyVar _ _ _ k)) -> extractHsTyRdrTyVars k
_ -> []
--- | Extracts free type and kind variables from an argument in a GADT
--- constructor, returning variable occurrences in left-to-right order.
--- See @Note [Ordering of implicit variables]@.
-extractConDeclGADTDetailsTyVars ::
- HsConDeclGADTDetails GhcPs -> FreeKiTyVars -> FreeKiTyVars
-extractConDeclGADTDetailsTyVars con_args = case con_args of
- PrefixConGADT args -> extract_scaled_ltys args
- RecConGADT (L _ flds) _ -> extract_ltys $ map (cd_fld_type . unLoc) $ flds
+-- | Extracts free type and kind variables from the argument and result types
+-- in a GADT constructor, returning variable occurrences in left-to-right
+-- order. See @Note [Ordering of implicit variables]@.
+extractConGadtSigBodyTyVars :: ConGadtSigBody GhcPs -> FreeKiTyVars
+extractConGadtSigBodyTyVars body = case body of
+ PrefixConGADT body' -> extract_prefix_con_gadt_sig_body body'
+ RecConGADT (L _ flds) _ res -> extract_ltys (map (cd_fld_type . unLoc) flds) $
+ extractHsTyRdrTyVars res
+
+extract_prefix_con_gadt_sig_body :: PrefixConGadtSigBody GhcPs -> FreeKiTyVars
+extract_prefix_con_gadt_sig_body prefix_body = go prefix_body []
+ where
+ go :: PrefixConGadtSigBody GhcPs -> FreeKiTyVars -> FreeKiTyVars
+ go (PCGSRes res_ty) acc = extract_lty res_ty acc
+ go (PCGSAnonArg arg body) acc = extract_scaled_lty arg (go body acc)
-- | Get type/kind variables mentioned in the kind signature, preserving
-- left-to-right order:
@@ -1926,10 +1933,6 @@ extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig })
extract_lctxt :: LHsContext GhcPs -> FreeKiTyVars -> FreeKiTyVars
extract_lctxt ctxt = extract_ltys (unLoc ctxt)
-extract_scaled_ltys :: [HsScaled GhcPs (LHsType GhcPs)]
- -> FreeKiTyVars -> FreeKiTyVars
-extract_scaled_ltys args acc = foldr extract_scaled_lty acc args
-
extract_scaled_lty :: HsScaled GhcPs (LHsType GhcPs)
-> FreeKiTyVars -> FreeKiTyVars
extract_scaled_lty (HsScaled m ty) acc = extract_lty ty $ extract_hs_arrow m acc
diff --git a/compiler/GHC/Rename/Module.hs b/compiler/GHC/Rename/Module.hs
index 29937ea5f0..6b152bcb57 100644
--- a/compiler/GHC/Rename/Module.hs
+++ b/compiler/GHC/Rename/Module.hs
@@ -2352,8 +2352,7 @@ rnConDecl decl@(ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs
rnConDecl (ConDeclGADT { con_names = names
, con_bndrs = L l outer_bndrs
, con_mb_cxt = mcxt
- , con_g_args = args
- , con_res_ty = res_ty
+ , con_body = body
, con_doc = mb_doc })
= do { mapM_ (addLocMA checkConName) names
; new_names <- mapM (lookupLocatedTopConstructorRnN) names
@@ -2366,31 +2365,22 @@ rnConDecl (ConDeclGADT { con_names = names
implicit_bndrs =
extractHsOuterTvBndrs outer_bndrs $
extractHsTysRdrTyVars (hsConDeclTheta mcxt) $
- extractConDeclGADTDetailsTyVars args $
- extractHsTysRdrTyVars [res_ty] []
+ extractConGadtSigBodyTyVars body
; let ctxt = ConDeclCtx new_names
; bindHsOuterTyVarBndrs ctxt Nothing implicit_bndrs outer_bndrs $ \outer_bndrs' ->
do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt
- ; (new_args, fvs2) <- rnConDeclGADTDetails (unLoc (head new_names)) ctxt args
- ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty
+ ; (new_body, fvs2) <- rnConGadtSigBody (unLoc (head new_names)) ctxt body
- -- Ensure that there are no nested `forall`s or contexts, per
- -- Note [GADT abstract syntax] (Wrinkle: No nested foralls or contexts)
- -- in GHC.Hs.Type.
- ; addNoNestedForallsContextsErr ctxt
- (text "GADT constructor type signature") new_res_ty
-
- ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3
+ ; let all_fvs = fvs1 `plusFV` fvs2
; traceRn "rnConDecl (ConDeclGADT)"
(ppr names $$ ppr outer_bndrs')
; new_mb_doc <- traverse rnLHsDoc mb_doc
; return (ConDeclGADT { con_g_ext = noAnn, con_names = new_names
, con_bndrs = L l outer_bndrs', con_mb_cxt = new_cxt
- , con_g_args = new_args, con_res_ty = new_res_ty
- , con_doc = new_mb_doc },
+ , con_body = new_body, con_doc = new_mb_doc },
all_fvs) } }
rnMbContext :: HsDocContext -> Maybe (LHsContext GhcPs)
@@ -2415,17 +2405,32 @@ rnConDeclH98Details con doc (RecCon flds)
= do { (new_flds, fvs) <- rnRecConDeclFields con doc flds
; return (RecCon new_flds, fvs) }
-rnConDeclGADTDetails ::
+rnConGadtSigBody ::
Name
-> HsDocContext
- -> HsConDeclGADTDetails GhcPs
- -> RnM (HsConDeclGADTDetails GhcRn, FreeVars)
-rnConDeclGADTDetails _ doc (PrefixConGADT tys)
- = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys
- ; return (PrefixConGADT new_tys, fvs) }
-rnConDeclGADTDetails con doc (RecConGADT flds arr)
- = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds
- ; return (RecConGADT new_flds arr, fvs) }
+ -> ConGadtSigBody GhcPs
+ -> RnM (ConGadtSigBody GhcRn, FreeVars)
+rnConGadtSigBody _ doc (PrefixConGADT body)
+ = do { (new_body, fvs) <- rnPrefixConGadtSigBody doc body
+ ; return (PrefixConGADT new_body, fvs) }
+rnConGadtSigBody con doc (RecConGADT flds arr res_ty)
+ = do { (new_flds, fvs1) <- rnRecConDeclFields con doc flds
+ ; (new_res_ty, fvs2) <- rnGADTResultTy doc res_ty
+ ; return (RecConGADT new_flds arr new_res_ty, fvs1 `plusFV` fvs2) }
+
+rnPrefixConGadtSigBody ::
+ HsDocContext
+ -> PrefixConGadtSigBody GhcPs
+ -> RnM (PrefixConGadtSigBody GhcRn, FreeVars)
+rnPrefixConGadtSigBody doc = go
+ where
+ go (PCGSRes res_ty) = do
+ (new_res_ty, fvs) <- rnGADTResultTy doc res_ty
+ pure (PCGSRes new_res_ty, fvs)
+ go (PCGSAnonArg arg_ty body) = do
+ (new_arg_ty, fvs1) <- rnScaledLHsType doc arg_ty
+ (new_body, fvs2) <- go body
+ pure (PCGSAnonArg new_arg_ty new_body, fvs1 `plusFV` fvs2)
rnRecConDeclFields ::
Name
@@ -2439,6 +2444,19 @@ rnRecConDeclFields con doc (L l fields)
-- since that is done by GHC.Rename.Names.extendGlobalRdrEnvRn
; pure (L l new_fields, fvs) }
+rnGADTResultTy ::
+ HsDocContext
+ -> LHsType GhcPs
+ -> RnM (LHsType GhcRn, FreeVars)
+rnGADTResultTy doc res_ty
+ = do { (new_res_ty, fvs) <- rnLHsType doc res_ty
+ -- Ensure that there are no nested `forall`s or contexts, per
+ -- Note [GADT abstract syntax] (Wrinkle: No nested foralls or contexts)
+ -- in Language.Haskell.Syntax.Decls.
+ ; addNoNestedForallsContextsErr doc
+ (text "GADT constructor type signature") new_res_ty
+ ; pure (new_res_ty, fvs) }
+
-------------------------------------------------
-- | Brings pattern synonym names and also pattern synonym selectors
diff --git a/compiler/GHC/Rename/Names.hs b/compiler/GHC/Rename/Names.hs
index 3a4cb78820..7b473a532e 100644
--- a/compiler/GHC/Rename/Names.hs
+++ b/compiler/GHC/Rename/Names.hs
@@ -978,7 +978,7 @@ getLocalNonValBinders fixity_env
= [( find_con_name rdr
, concatMap find_con_decl_flds (unLoc cdflds) )]
find_con_flds (L _ (ConDeclGADT { con_names = rdrs
- , con_g_args = RecConGADT flds _ }))
+ , con_body = RecConGADT flds _ _ }))
= [ ( find_con_name rdr
, concatMap find_con_decl_flds (unLoc flds))
| L _ rdr <- rdrs ]
diff --git a/compiler/GHC/Rename/Utils.hs b/compiler/GHC/Rename/Utils.hs
index 597af3d778..796853ae82 100644
--- a/compiler/GHC/Rename/Utils.hs
+++ b/compiler/GHC/Rename/Utils.hs
@@ -278,7 +278,7 @@ Note [No nested foralls or contexts in instance types] in GHC.Hs.Type).
--
-- * In GADT constructor types (in 'rnConDecl').
-- See @Note [GADT abstract syntax] (Wrinkle: No nested foralls or contexts)@
--- in "GHC.Hs.Type".
+-- in "Language.Haskell.Syntax.Decls".
--
-- * In instance declaration types (in 'rnClsIntDecl' and 'rnSrcDerivDecl' in
-- "GHC.Rename.Module" and 'renameSig' in "GHC.Rename.Bind").
diff --git a/compiler/GHC/Tc/TyCl.hs b/compiler/GHC/Tc/TyCl.hs
index 302f93e691..5f4312d093 100644
--- a/compiler/GHC/Tc/TyCl.hs
+++ b/compiler/GHC/Tc/TyCl.hs
@@ -99,6 +99,7 @@ import GHC.Utils.Constants (debugIsOn)
import GHC.Utils.Misc
import Control.Monad
+import Data.Foldable
import Data.Functor.Identity
import Data.List ( partition)
import Data.List.NonEmpty ( NonEmpty(..) )
@@ -1604,16 +1605,22 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc
-------------------
--- Kind-check the types of the arguments to a data constructor.
+-- Kind-check the type of an argument to a data constructor.
-- This includes doing kind unification if the type is a newtype.
-- See Note [Implementation of UnliftedNewtypes] for why we need
--- the first two arguments.
+-- the first argument.
+kcConArgTy :: ContextKind -> HsScaled GhcRn (LHsType GhcRn) -> TcM ()
+kcConArgTy exp_kind (HsScaled mult ty) = do
+ { _ <- tcCheckLHsType (getBangType ty) exp_kind
+ ; void $ tcMult mult
+ -- See Note [Implementation of UnliftedNewtypes], STEP 2
+ }
+
+-- Kind-check the types of the arguments to a data constructor.
kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM ()
kcConArgTys new_or_data res_kind arg_tys = do
{ let exp_kind = getArgExpKind new_or_data res_kind
- ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsType (getBangType ty) exp_kind
- tcMult mult)
- -- See Note [Implementation of UnliftedNewtypes], STEP 2
+ ; traverse_ (kcConArgTy exp_kind) arg_tys
}
-- Kind-check the types of arguments to a Haskell98 data constructor.
@@ -1624,12 +1631,28 @@ kcConH98Args new_or_data res_kind con_args = case con_args of
RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $
map (hsLinear . cd_fld_type . unLoc) flds
--- Kind-check the types of arguments to a GADT data constructor.
-kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM ()
-kcConGADTArgs new_or_data res_kind con_args = case con_args of
- PrefixConGADT tys -> kcConArgTys new_or_data res_kind tys
- RecConGADT (L _ flds) _ -> kcConArgTys new_or_data res_kind $
- map (hsLinear . cd_fld_type . unLoc) flds
+-- Kind-check the types of the arguments and result in a GADT data constructor.
+kcConGadtSigBody :: NewOrData -> Kind -> ConGadtSigBody GhcRn -> TcM ()
+kcConGadtSigBody new_or_data res_kind body = case body of
+ PrefixConGADT prefix_body ->
+ kcPrefixConGadtSigBody new_or_data res_kind prefix_body
+ RecConGADT (L _ flds) _ res_ty -> do
+ _ <- tcCheckLHsType res_ty (TheKind res_kind)
+ kcConArgTys new_or_data res_kind $ map (hsLinear . cd_fld_type . unLoc) flds
+
+-- Kind-check the types of the arguments and result in a prefix GADT data constructor.
+kcPrefixConGadtSigBody :: NewOrData -> Kind -> PrefixConGadtSigBody GhcRn -> TcM ()
+kcPrefixConGadtSigBody new_or_data res_kind = go
+ where
+ exp_kind :: ContextKind
+ exp_kind = getArgExpKind new_or_data res_kind
+
+ go :: PrefixConGadtSigBody GhcRn -> TcM ()
+ go (PCGSRes res_ty) =
+ void $ tcCheckLHsType res_ty (TheKind res_kind)
+ go (PCGSAnonArg arg_ty body) = do
+ go body
+ kcConArgTy exp_kind arg_ty
kcConDecls :: NewOrData
-> TcKind -- The result kind signature
@@ -1668,7 +1691,7 @@ kcConDecl new_or_data
_tc_res_kind -- Not used in GADT case (and doesn't make sense)
(ConDeclGADT
{ con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt
- , con_g_args = args, con_res_ty = res_ty })
+ , con_body = body })
= -- See Note [kcConDecls: kind-checking data type decls]
addErrCtxt (dataConCtxt names) $
discardResult $
@@ -1676,10 +1699,9 @@ kcConDecl new_or_data
bindOuterSigTKBndrs_Tv outer_bndrs $
-- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs]
do { _ <- tcHsContext cxt
- ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty)
+ ; traceTc "kcConDecl:GADT {" (ppr names)
; con_res_kind <- newOpenTypeKind
- ; _ <- tcCheckLHsType res_ty (TheKind con_res_kind)
- ; kcConGADTArgs new_or_data con_res_kind args
+ ; kcConGadtSigBody new_or_data con_res_kind body
; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind)
; return () }
@@ -2174,7 +2196,7 @@ newtype instance Foo 'Red = FooRedC Int#
Note that, in the GADT case, we might have a kind signature with arrows
(newtype XYZ a b :: Type -> Type where ...). We want only the final
-component of the kind for checking in kcConDecl, so we call etaExpanAlgTyCon
+component of the kind for checking in kcConDecl, so we call etaExpandAlgTyCon
in kcTyClDecl.
STEP 3: Type-checking (desugaring), as done by tcTyClDecl. The key function
@@ -3480,8 +3502,7 @@ tcConDecl new_or_data dd_info rep_tycon tc_bndrs _res_kind tag_map
-- we get the res_kind by typechecking the result type.
(ConDeclGADT { con_names = names
, con_bndrs = L _ outer_hs_bndrs
- , con_mb_cxt = cxt, con_g_args = hs_args
- , con_res_ty = hs_res_ty })
+ , con_mb_cxt = cxt, con_body = body })
= addErrCtxt (dataConCtxt names) $
do { traceTc "tcConDecl 1 gadt" (ppr names)
; let (L _ name : _) = names
@@ -3490,26 +3511,8 @@ tcConDecl new_or_data dd_info rep_tycon tc_bndrs _res_kind tag_map
<- pushLevelAndSolveEqualitiesX "tcConDecl:GADT" $
tcOuterTKBndrs skol_info outer_hs_bndrs $
do { ctxt <- tcHsContext cxt
- ; (res_ty, res_kind) <- tcInferLHsTypeKind hs_res_ty
- -- See Note [GADT return kinds]
-
- -- For data instances (only), ensure that the return type,
- -- res_ty, is a substitution instance of the header.
- -- See Note [GADT return types]
- ; case dd_info of
- DDataType -> return ()
- DDataInstance hdr_ty ->
- do { (subst, _meta_tvs) <- newMetaTyVars (binderVars tc_bndrs)
- ; let head_shape = substTy subst hdr_ty
- ; discardResult $
- popErrCtxt $ -- Drop dataConCtxt
- addErrCtxt (dataConResCtxt names) $
- unifyType Nothing res_ty head_shape }
-
- -- See Note [Datatype return kinds]
- ; let exp_kind = getArgExpKind new_or_data res_kind
- ; btys <- tcConGADTArgs exp_kind hs_args
-
+ ; (btys, res_ty) <-
+ tcConGadtSigBody names new_or_data dd_info tc_bndrs body
; let (arg_tys, stricts) = unzip btys
; field_lbls <- lookupConstructorFields name
; return (ctxt, arg_tys, res_ty, field_lbls, stricts)
@@ -3550,7 +3553,7 @@ tcConDecl new_or_data dd_info rep_tycon tc_bndrs _res_kind tag_map
; dflags <- getDynFlags
; let
buildOneDataCon (L _ name) = do
- { is_infix <- tcConIsInfixGADT name hs_args
+ { is_infix <- tcConIsInfixGADT name body
; rep_nm <- newTyConRepName name
; let bang_opts = SrcBangOpts (initBangOpts dflags)
@@ -3663,14 +3666,14 @@ tcConIsInfixH98 _ details
PrefixCon{} -> return False
tcConIsInfixGADT :: Name
- -> HsConDeclGADTDetails GhcRn
- -> TcM Bool
-tcConIsInfixGADT con details
- = case details of
+ -> ConGadtSigBody GhcRn
+ -> TcM Bool
+tcConIsInfixGADT con body
+ = case body of
RecConGADT{} -> return False
- PrefixConGADT arg_tys -- See Note [Infix GADT constructors]
+ PrefixConGADT prefix_body -- See Note [Infix GADT constructors]
| isSymOcc (getOccName con)
- , [_ty1,_ty2] <- map hsScaledThing arg_tys
+ , [_ty1,_ty2] <- map hsScaledThing $ anonPrefixConGadtSigArgs prefix_body
-> do { fix_env <- getFixityEnv
; return (con `elemNameEnv` fix_env) }
| otherwise -> return False
@@ -3689,15 +3692,68 @@ tcConH98Args exp_kind (InfixCon bty1 bty2)
tcConH98Args exp_kind (RecCon fields)
= tcRecConDeclFields exp_kind fields
-tcConGADTArgs :: ContextKind -- expected kind of arguments
- -- always OpenKind for datatypes, but unlifted newtypes
- -- might have a specific kind
- -> HsConDeclGADTDetails GhcRn
- -> TcM [(Scaled TcType, HsSrcBang)]
-tcConGADTArgs exp_kind (PrefixConGADT btys)
- = mapM (tcConArg exp_kind) btys
-tcConGADTArgs exp_kind (RecConGADT fields _)
- = tcRecConDeclFields exp_kind fields
+tcConGadtSigBody :: [LocatedN Name]
+ -> NewOrData
+ -> DataDeclInfo
+ -> [TcTyConBinder]
+ -> ConGadtSigBody GhcRn
+ -> TcM ([(Scaled TcType, HsSrcBang)], TcType)
+tcConGadtSigBody names new_or_data dd_info tc_bndrs body =
+ case body of
+ PrefixConGADT btys ->
+ tcPrefixConGadtSigBody names new_or_data dd_info tc_bndrs btys
+ RecConGADT fields _ res_ty -> do
+ -- See Note [GADT return kinds]
+ (tc_res_ty, tc_res_kind) <- tcConGadtResTy names dd_info tc_bndrs res_ty
+ -- See Note [Datatype return kinds]
+ let exp_kind = getArgExpKind new_or_data tc_res_kind
+ tc_arg_tys <- tcRecConDeclFields exp_kind fields
+ pure (tc_arg_tys, tc_res_ty)
+
+tcPrefixConGadtSigBody :: [LocatedN Name]
+ -> NewOrData
+ -> DataDeclInfo
+ -> [TcTyConBinder]
+ -> PrefixConGadtSigBody GhcRn
+ -> TcM ([(Scaled TcType, HsSrcBang)], TcType)
+tcPrefixConGadtSigBody names new_or_data dd_info tc_bndrs prefix_body = do
+ (tc_arg_tys, tc_res_ty, _) <- go prefix_body
+ pure (tc_arg_tys, tc_res_ty)
+ where
+ go :: PrefixConGadtSigBody GhcRn
+ -> TcM ([(Scaled TcType, HsSrcBang)], TcType, TcKind)
+ go (PCGSRes res_ty) = do
+ (tc_res_ty, tc_res_kind) <- tcConGadtResTy names dd_info tc_bndrs res_ty
+ pure ([], tc_res_ty, tc_res_kind)
+ go (PCGSAnonArg arg_ty body) = do
+ (tc_arg_tys, tc_res_ty, tc_res_kind) <- go body
+ -- See Note [Datatype return kinds]
+ let exp_kind = getArgExpKind new_or_data tc_res_kind
+ tc_arg_ty <- tcConArg exp_kind arg_ty
+ pure (tc_arg_ty:tc_arg_tys, tc_res_ty, tc_res_kind)
+
+tcConGadtResTy :: [LocatedN Name]
+ -> DataDeclInfo
+ -> [TcTyConBinder]
+ -> LHsType GhcRn -> TcM (TcType, TcKind)
+tcConGadtResTy names dd_info tc_bndrs res_ty = do
+ -- See Note [GADT return kinds]
+ res@(tc_res_ty, _tc_res_kind) <- tcInferLHsTypeKind res_ty
+
+ -- For data instances (only), ensure that the return type,
+ -- res_ty, is a substitution instance of the header.
+ -- See Note [GADT return types]
+ case dd_info of
+ DDataType -> return ()
+ DDataInstance hdr_ty ->
+ do { (subst, _meta_tvs) <- newMetaTyVars (binderVars tc_bndrs)
+ ; let head_shape = substTy subst hdr_ty
+ ; discardResult $
+ popErrCtxt $ -- Drop dataConCtxt
+ addErrCtxt (dataConResCtxt names) $
+ unifyType Nothing tc_res_ty head_shape }
+
+ pure res
tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes,
-- but might be an unlifted type with UnliftedNewtypes
@@ -3712,15 +3768,22 @@ tcConArg exp_kind (HsScaled w bty)
tcRecConDeclFields :: ContextKind
-> LocatedL [LConDeclField GhcRn]
-> TcM [(Scaled TcType, HsSrcBang)]
-tcRecConDeclFields exp_kind fields
- = mapM (tcConArg exp_kind) btys
+tcRecConDeclFields exp_kind (L _ fields)
+ = concatMapM tc_field fields
where
- -- We need a one-to-one mapping from field_names to btys
- combined = map (\(L _ f) -> (cd_fld_names f,hsLinear (cd_fld_type f)))
- (unLoc fields)
- explode (ns,ty) = zip ns (repeat ty)
- exploded = concatMap explode combined
- (_,btys) = unzip exploded
+ -- We need to ensure that each distinct field name gets its own type.
+ -- For example, if we have:
+ --
+ -- data T = MkT { a,b,c :: Int }
+ --
+ -- Then we should return /three/ Int types, not just one! At the same
+ -- time, we don't want to kind-check Int three separate times, as that
+ -- would be redundant. Therefore, we kind-check Int once and 'replicate'
+ -- it so that we return three occurrences of it.
+ tc_field :: LConDeclField GhcRn -> TcM [(Scaled TcType, HsSrcBang)]
+ tc_field (L _ f) = do
+ bty' <- tcConArg exp_kind $ hsLinear $ cd_fld_type f
+ pure $ replicate (length (cd_fld_names f)) bty'
tcDataConMult :: HsArrow GhcRn -> TcM Mult
tcDataConMult arr@(HsUnrestrictedArrow _) = do
diff --git a/compiler/GHC/ThToHs.hs b/compiler/GHC/ThToHs.hs
index 7644109ae0..765afc86aa 100644
--- a/compiler/GHC/ThToHs.hs
+++ b/compiler/GHC/ThToHs.hs
@@ -684,7 +684,11 @@ cvtConstr (GadtC c strtys ty)
= do { c' <- mapM cNameN c
; args <- mapM cvt_arg strtys
; ty' <- cvtType ty
- ; mk_gadt_decl c' (PrefixConGADT $ map hsLinear args) ty'}
+ ; mk_gadt_decl c' $ PrefixConGADT $ mk_prefix_body args ty' }
+ where
+ mk_prefix_body :: [LHsType GhcPs] -> LHsType GhcPs -> PrefixConGadtSigBody GhcPs
+ mk_prefix_body args res = foldr (\arg body -> PCGSAnonArg (hsLinear arg) body)
+ (PCGSRes res) args
cvtConstr (RecGadtC [] _varstrtys _ty)
= failWith (text "RecGadtC must have at least one constructor name")
@@ -694,19 +698,18 @@ cvtConstr (RecGadtC c varstrtys ty)
; ty' <- cvtType ty
; rec_flds <- mapM cvt_id_arg varstrtys
; lrec_flds <- returnLA rec_flds
- ; mk_gadt_decl c' (RecConGADT lrec_flds noHsUniTok) ty' }
+ ; mk_gadt_decl c' $ RecConGADT lrec_flds noHsUniTok ty' }
-mk_gadt_decl :: [LocatedN RdrName] -> HsConDeclGADTDetails GhcPs -> LHsType GhcPs
+mk_gadt_decl :: [LocatedN RdrName] -> ConGadtSigBody GhcPs
-> CvtM (LConDecl GhcPs)
-mk_gadt_decl names args res_ty
+mk_gadt_decl names body
= do bndrs <- returnLA mkHsOuterImplicit
returnLA $ ConDeclGADT
{ con_g_ext = noAnn
, con_names = names
, con_bndrs = bndrs
, con_mb_cxt = Nothing
- , con_g_args = args
- , con_res_ty = res_ty
+ , con_body = body
, con_doc = Nothing }
cvtSrcUnpackedness :: TH.SourceUnpackedness -> SrcUnpackedness
diff --git a/compiler/Language/Haskell/Syntax/Decls.hs b/compiler/Language/Haskell/Syntax/Decls.hs
index baeef95b17..3ed3e5a4b0 100644
--- a/compiler/Language/Haskell/Syntax/Decls.hs
+++ b/compiler/Language/Haskell/Syntax/Decls.hs
@@ -73,7 +73,9 @@ module Language.Haskell.Syntax.Decls (
CImportSpec(..),
-- ** Data-constructor declarations
ConDecl(..), LConDecl,
- HsConDeclH98Details, HsConDeclGADTDetails(..),
+ HsConDeclH98Details,
+ ConGadtSigBody(..), PrefixConGadtSigBody(..),
+ anonPrefixConGadtSigArgs, prefixConGadtSigRes,
-- ** Document comments
DocDecl(..), LDocDecl, docDeclDoc,
-- ** Deprecations
@@ -1062,8 +1064,7 @@ data ConDecl pass
-- implicit. The 'XRec' is used to anchor exact print
-- annotations, AnnForall and AnnDot.
, con_mb_cxt :: Maybe (LHsContext pass) -- ^ User-written context (if any)
- , con_g_args :: HsConDeclGADTDetails pass -- ^ Arguments; never infix
- , con_res_ty :: LHsType pass -- ^ Result type
+ , con_body :: ConGadtSigBody pass -- ^ The argument and result types
, con_doc :: Maybe (LHsDoc pass) -- ^ A possible Haddock
-- comment.
@@ -1108,17 +1109,17 @@ There are two broad ways to classify GADT constructors:
data T a where
K :: forall a. Ord a => [a] -> ... -> T a
-This distinction is recorded in the `con_args :: HsConDetails pass`, which
-tracks if we're dealing with a RecCon or PrefixCon. It is easy to distinguish
-the two in the AST since record GADT constructors use HsRecTy. This distinction
-is made in GHC.Parser.PostProcess.mkGadtDecl.
+This distinction is recorded in the `con_body :: ConGadtSigBody pass` field,
+which tracks if we're dealing with a RecConGADT or PrefixConGADT. It is easy to
+distinguish the two in the AST since record GADT constructors use HsRecTy. This
+distinction is made in GHC.Parser.PostProcess.mkGadtDecl.
It is worth elaborating a bit more on the process of splitting the argument
types of a GADT constructor, since there are some non-obvious details involved.
While splitting the argument types of a record GADT constructor is easy (they
are stored in an HsRecTy), splitting the arguments of a prefix GADT constructor
is trickier. The basic idea is that we must split along the outermost function
-arrows ((->) and (%1 ->)) in the type, which GHC.Hs.Type.splitHsFunType
+arrows ((->) and (%1 ->)) in the type, which GHC.Hs.Type.splitLHsPrefixGadtSigBody
accomplishes. But what about type operators? Consider:
C :: a :*: b -> a :*: b -> a :+: b
@@ -1182,24 +1183,18 @@ or contexts in two parts:
1. GHC, in the process of splitting apart a GADT's type,
extracts out the leading `forall` and context (if they are provided). To
accomplish this splitting, the renamer uses the
- GHC.Hs.Type.splitLHsGADTPrefixTy function, which is careful not to remove
+ GHC.Hs.Type.splitLHsGadtTy function, which is careful not to remove
parentheses surrounding the leading `forall` or context (as these
parentheses can be syntactically significant). If the third result returned
- by splitLHsGADTPrefixTy contains any `forall`s or contexts, then they must
- be nested, so they will be rejected.
+ by splitLHsGadtTy contains any `forall`s or contexts, then they must
+ be nested, so they will be rejected later in the renamer.
Note that this step applies to both prefix and record GADTs alike, as they
- both have syntax which permits `forall`s and contexts. The difference is
- where this step happens:
-
- * For prefix GADTs, this happens in the renamer (in rnConDecl), as we cannot
- split until after the type operator fixities have been resolved.
- * For record GADTs, this happens in the parser (in mkGadtDecl).
-2. If the GADT type is prefix, the renamer (in the ConDeclGADTPrefixPs case of
- rnConDecl) will then check for nested `forall`s/contexts in the body of a
- prefix GADT type, after it has determined what all of the argument types are.
- This step is necessary to catch examples like MkT4 above, where the nested
- quantification occurs after a visible argument type.
+ both have syntax which permits `forall`s and contexts.
+2. The renamer (in GHC.Rename.Module.rnGADTResultTy) will then check for nested
+ `forall`s/contexts in the body of a GADT constructor type. This step is
+ necessary to catch examples like MkT4 above, where the nested quantification
+ occurs after a visible argument type.
-}
-- | The arguments in a Haskell98-style data constructor.
@@ -1208,15 +1203,43 @@ type HsConDeclH98Details pass
-- The Void argument to HsConDetails here is a reflection of the fact that
-- type applications are not allowed in data constructor declarations.
--- | The arguments in a GADT constructor. Unlike Haskell98-style constructors,
--- GADT constructors cannot be declared with infix syntax. As a result, we do
--- not use 'HsConDetails' here, as 'InfixCon' would be an unrepresentable
--- state. (There is a notion of infix GADT constructors for the purposes of
--- derived Show instances—see Note [Infix GADT constructors] in
--- GHC.Tc.TyCl—but that is an orthogonal concern.)
-data HsConDeclGADTDetails pass
- = PrefixConGADT [HsScaled pass (LBangType pass)]
- | RecConGADT (XRec pass [LConDeclField pass]) (LHsUniToken "->" "→" pass)
+-- | The argument and result types in a GADT constructor.
+-- See @Note [GADT abstract syntax]@.
+--
+-- Unlike Haskell98-style constructors, GADT constructors cannot be declared
+-- with infix syntax. As a result, we do not use 'HsConDetails' here, as
+-- 'InfixCon' would be an unrepresentable state. (There is a notion of infix
+-- GADT constructors for the purposes of derived 'Show' instances—see
+-- @Note [Infix GADT constructors]@ in "GHC.Tc.TyCl"—but that is an
+-- orthogonal concern.)
+data ConGadtSigBody pass
+ = PrefixConGADT (PrefixConGadtSigBody pass)
+ | RecConGADT (XRec pass [LConDeclField pass]) (LHsUniToken "->" "→" pass) (LHsType pass)
+
+-- | The argument and result types in a prefix GADT constructor. This closely
+-- resembles the structure of 'HsType', but with data constructor–specific
+-- tweaks. See @Note [GADT abstract syntax]@.
+data PrefixConGadtSigBody pass
+ -- | The result type.
+ = PCGSRes (LHsType pass)
+ -- | An argument followed by a function arrow (e.g., @MkT :: !Int -> ...@).
+ -- This is much like 'HsFunTy', except that 'PCGSAnonArg' uses an
+ -- 'LBangType' instead of an 'LHsType' to represent the argument.
+ | PCGSAnonArg (HsScaled pass (LBangType pass))
+ (PrefixConGadtSigBody pass)
+
+-- | Retrieve the visible, non-dependent arguments in a prefix GADT
+-- constructor type. Note that this takes O(/n/) time, where /n/ is the number
+-- of arguments.
+anonPrefixConGadtSigArgs :: PrefixConGadtSigBody pass -> [HsScaled pass (LBangType pass)]
+anonPrefixConGadtSigArgs (PCGSAnonArg arg body) = arg : anonPrefixConGadtSigArgs body
+anonPrefixConGadtSigArgs PCGSRes{} = []
+
+-- | Retrieve the result type in a prefix GADT constructor type. Note that this
+-- takes O(/n/) time, where /n/ is the number of arguments.
+prefixConGadtSigRes :: PrefixConGadtSigBody pass -> LHsType pass
+prefixConGadtSigRes (PCGSAnonArg _ body) = prefixConGadtSigRes body
+prefixConGadtSigRes (PCGSRes res_ty) = res_ty
instance Outputable NewOrData where
ppr NewType = text "newtype"
diff --git a/compiler/Language/Haskell/Syntax/Type.hs b/compiler/Language/Haskell/Syntax/Type.hs
index 0c84e9faa6..b85483dc18 100644
--- a/compiler/Language/Haskell/Syntax/Type.hs
+++ b/compiler/Language/Haskell/Syntax/Type.hs
@@ -1067,9 +1067,9 @@ data ConDeclField pass -- Record fields have Haddock docs on them
-- (see 'HsPatSynDetails' in "GHC.Hs.Binds").
--
-- One notable exception is the arguments in a GADT constructor, which uses
--- a separate data type entirely (see 'HsConDeclGADTDetails' in
--- "GHC.Hs.Decls"). This is because GADT constructors cannot be declared with
--- infix syntax, unlike the concepts above (#18844).
+-- a separate data type entirely (see 'ConGadtSigBody' in
+-- "Language.Haskell.Syntax.Decls"). This is because GADT constructors cannot
+-- be declared with infix syntax, unlike the concepts above (#18844).
data HsConDetails tyarg arg rec
= PrefixCon [tyarg] [arg] -- C @t1 @t2 p1 p2 p3
| RecCon rec -- C { x = p1, y = p2 }
diff --git a/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr b/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
index 781d006b54..e8dd84df3f 100644
--- a/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
+++ b/testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
@@ -857,41 +857,41 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:13-18 })
- (HsAppTy
- (NoExtField)
+ (PCGSRes
(L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:13-14 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:25:13-14 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:13-18 })
+ (HsAppTy
+ (NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:13-14 })
- (Unqual
- {OccName: D5}))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:16-18 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:25:16-18 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:25:13-14 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:13-14 })
+ (Unqual
+ {OccName: D5}))))
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:16-18 })
- (Unqual
- {OccName: Int}))))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:25:16-18 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:25:16-18 })
+ (Unqual
+ {OccName: Int}))))))))
(Nothing)))]
[]))))]
(Nothing)))))
@@ -1119,41 +1119,41 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:13-18 })
- (HsAppTy
- (NoExtField)
+ (PCGSRes
(L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:13-14 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:31:13-14 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:13-18 })
+ (HsAppTy
+ (NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:13-14 })
- (Unqual
- {OccName: D6}))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:16-18 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:31:16-18 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:31:13-14 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:13-14 })
+ (Unqual
+ {OccName: D6}))))
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:16-18 })
- (Unqual
- {OccName: Int}))))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:31:16-18 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:31:16-18 })
+ (Unqual
+ {OccName: Int}))))))))
(Nothing)))]
[]))))]
(Nothing)))))
@@ -1381,41 +1381,41 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:13-18 })
- (HsAppTy
- (NoExtField)
+ (PCGSRes
(L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:13-14 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:37:13-14 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:13-18 })
+ (HsAppTy
+ (NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:13-14 })
- (Unqual
- {OccName: D7}))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:16-18 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:37:16-18 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:37:13-14 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:13-14 })
+ (Unqual
+ {OccName: D7}))))
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:16-18 })
- (Unqual
- {OccName: Int}))))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:37:16-18 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:37:16-18 })
+ (Unqual
+ {OccName: Int}))))))))
(Nothing)))]
[]))))]
(Nothing)))))
@@ -1643,41 +1643,41 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:13-18 })
- (HsAppTy
- (NoExtField)
+ (PCGSRes
(L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:13-14 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:43:13-14 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:13-18 })
+ (HsAppTy
+ (NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:13-14 })
- (Unqual
- {OccName: D8}))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:16-18 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:43:16-18 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:43:13-14 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:13-14 })
+ (Unqual
+ {OccName: D8}))))
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:16-18 })
- (Unqual
- {OccName: Int}))))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:43:16-18 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:43:16-18 })
+ (Unqual
+ {OccName: Int}))))))))
(Nothing)))]
[]))))]
(Nothing)))))
@@ -1905,41 +1905,41 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:13-18 })
- (HsAppTy
- (NoExtField)
+ (PCGSRes
(L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:13-14 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:49:13-14 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:13-18 })
+ (HsAppTy
+ (NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:13-14 })
- (Unqual
- {OccName: D9}))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:16-18 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:49:16-18 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:49:13-14 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:13-14 })
+ (Unqual
+ {OccName: D9}))))
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:16-18 })
- (Unqual
- {OccName: Int}))))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:49:16-18 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:49:16-18 })
+ (Unqual
+ {OccName: Int}))))))))
(Nothing)))]
[]))))]
(Nothing)))))
@@ -2167,41 +2167,41 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:14-20 })
- (HsAppTy
- (NoExtField)
+ (PCGSRes
(L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:14-16 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:55:14-16 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:14-20 })
+ (HsAppTy
+ (NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:14-16 })
- (Unqual
- {OccName: D10}))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:18-20 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544.hs:55:18-20 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:55:14-16 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:14-16 })
+ (Unqual
+ {OccName: D10}))))
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:18-20 })
- (Unqual
- {OccName: Int}))))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544.hs:55:18-20 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544.hs:55:18-20 })
+ (Unqual
+ {OccName: Int}))))))))
(Nothing)))]
[]))))]
(Nothing)))))
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 63fe2c10d5..549f04a660 100644
--- a/testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
+++ b/testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
@@ -88,22 +88,22 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:16:18-20 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544_kw.hs:16:18-20 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (PCGSRes
(L
(SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:16:18-20 })
- (Unqual
- {OccName: Foo}))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544_kw.hs:16:18-20 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:16:18-20 })
+ (Unqual
+ {OccName: Foo}))))))
(Just
(L
{ T17544_kw.hs:15:10-35 }
@@ -172,7 +172,8 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [(HsScaled
+ (PCGSAnonArg
+ (HsScaled
(HsUnrestrictedArrow
(L
(TokenLoc
@@ -199,22 +200,23 @@
(EpaComments
[]))
(HsBoxedOrConstraintTuple)
- [])))])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:19:24-26 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T17544_kw.hs:19:24-26 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:19:24-26 })
- (Unqual
- {OccName: Bar}))))
+ [])))
+ (PCGSRes
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:19:24-26 })
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T17544_kw.hs:19:24-26 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T17544_kw.hs:19:24-26 })
+ (Unqual
+ {OccName: Bar})))))))
(Just
(L
{ T17544_kw.hs:18:13-38 }
diff --git a/testsuite/tests/indexed-types/should_compile/T14111b.hs b/testsuite/tests/indexed-types/should_compile/T14111b.hs
new file mode 100644
index 0000000000..179597f48f
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_compile/T14111b.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE MagicHash, UnboxedSums, NoImplicitPrelude #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE TypeInType #-}
+{-# LANGUAGE GADTs ,ExplicitNamespaces#-}
+{-# LANGUAGE UnboxedTuples #-}
+
+module T14111b where
+
+import GHC.Exts
+import GHC.Types
+import Prelude (undefined)
+import Data.Kind
+import Data.Void
+
+data family Maybe(x :: TYPE (r :: RuntimeRep))
+
+data instance Maybe (a :: Type ) where
+ MaybeSum :: { unMaybeSum :: (# a | (# #) #) } -> Maybe a
+
+data instance Maybe (x :: TYPE ('BoxedRep 'Unlifted)) where
+ MaybeSumU :: { unMaybeSumU :: (# x | (# #) #) } -> Maybe x
diff --git a/testsuite/tests/indexed-types/should_compile/all.T b/testsuite/tests/indexed-types/should_compile/all.T
index 3549a37f70..666e0acaf0 100644
--- a/testsuite/tests/indexed-types/should_compile/all.T
+++ b/testsuite/tests/indexed-types/should_compile/all.T
@@ -302,6 +302,7 @@ test('GivenLoop', normal, compile, [''])
test('T18875', normal, compile, [''])
test('T8707', normal, compile, ['-O'])
test('T14111', normal, compile, ['-O'])
+test('T14111b', normal, compile, ['-O'])
test('T19336', normal, compile, ['-O'])
test('T11715b', normal, ghci_script, ['T11715b.script'])
test('T4254', normal, compile, [''])
diff --git a/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr b/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
index cfaa1b102e..8006bde050 100644
--- a/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
+++ b/testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
@@ -591,7 +591,8 @@
,{Name: g}]))
(Nothing)
(PrefixConGADT
- [(HsScaled
+ (PCGSAnonArg
+ (HsScaled
(HsUnrestrictedArrow
(L
(TokenLoc
@@ -682,39 +683,40 @@
(NotPromoted)
(L
(SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:32-33 })
- {Name: xx}))))))))))))])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-45 })
- (HsAppTy
- (NoExtField)
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-43 })
- (HsAppTy
- (NoExtField)
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-41 })
- (HsTyVar
- (EpAnnNotUsed)
- (NotPromoted)
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-41 })
- {Name: DumpRenamedAst.Nat})))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:43 })
- (HsTyVar
- (EpAnnNotUsed)
- (NotPromoted)
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:43 })
- {Name: f})))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:45 })
- (HsTyVar
- (EpAnnNotUsed)
- (NotPromoted)
- (L
- (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:45 })
- {Name: g})))))
+ {Name: xx}))))))))))))
+ (PCGSRes
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-45 })
+ (HsAppTy
+ (NoExtField)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-43 })
+ (HsAppTy
+ (NoExtField)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-41 })
+ (HsTyVar
+ (EpAnnNotUsed)
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:39-41 })
+ {Name: DumpRenamedAst.Nat})))
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:43 })
+ (HsTyVar
+ (EpAnnNotUsed)
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:43 })
+ {Name: f})))))
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:45 })
+ (HsTyVar
+ (EpAnnNotUsed)
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { DumpRenamedAst.hs:20:45 })
+ {Name: g}))))))))
(Nothing)))]
[])))))])
,(TyClGroup
diff --git a/testsuite/tests/parser/should_compile/T15323.stderr b/testsuite/tests/parser/should_compile/T15323.stderr
index 0a2f60dd59..177eaf5ed8 100644
--- a/testsuite/tests/parser/should_compile/T15323.stderr
+++ b/testsuite/tests/parser/should_compile/T15323.stderr
@@ -186,42 +186,44 @@
(Unqual
{OccName: v}))))))))]))
(PrefixConGADT
- [])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:41-54 })
- (HsAppTy
- (NoExtField)
+ (PCGSRes
(L
- (SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:41-52 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T15323.hs:6:41-52 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:41-54 })
+ (HsAppTy
+ (NoExtField)
(L
(SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:41-52 })
- (Unqual
- {OccName: MaybeDefault}))))
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:54 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T15323.hs:6:54 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T15323.hs:6:41-52 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:41-52 })
+ (Unqual
+ {OccName: MaybeDefault}))))
(L
(SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:54 })
- (Unqual
- {OccName: v}))))))
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T15323.hs:6:54 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T15323.hs:6:54 })
+ (Unqual
+ {OccName: v}))))))))
(Nothing)))]
[]))))]
(Nothing)
(Nothing)))
+
+
diff --git a/testsuite/tests/printer/T18791.stderr b/testsuite/tests/printer/T18791.stderr
index 65fe422f4a..85ce986517 100644
--- a/testsuite/tests/printer/T18791.stderr
+++ b/testsuite/tests/printer/T18791.stderr
@@ -88,7 +88,8 @@
(NoExtField)))
(Nothing)
(PrefixConGADT
- [(HsScaled
+ (PCGSAnonArg
+ (HsScaled
(HsUnrestrictedArrow
(L
(TokenLoc
@@ -115,22 +116,23 @@
(L
(SrcSpanAnn (EpAnnNotUsed) { T18791.hs:5:10-12 })
(Unqual
- {OccName: Int})))))])
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T18791.hs:5:17 })
- (HsTyVar
- (EpAnn
- (Anchor
- { T18791.hs:5:17 }
- (UnchangedAnchor))
- []
- (EpaComments
- []))
- (NotPromoted)
- (L
- (SrcSpanAnn (EpAnnNotUsed) { T18791.hs:5:17 })
- (Unqual
- {OccName: T}))))
+ {OccName: Int})))))
+ (PCGSRes
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T18791.hs:5:17 })
+ (HsTyVar
+ (EpAnn
+ (Anchor
+ { T18791.hs:5:17 }
+ (UnchangedAnchor))
+ []
+ (EpaComments
+ []))
+ (NotPromoted)
+ (L
+ (SrcSpanAnn (EpAnnNotUsed) { T18791.hs:5:17 })
+ (Unqual
+ {OccName: T})))))))
(Nothing)))]
[]))))]
(Nothing)
diff --git a/utils/check-exact/ExactPrint.hs b/utils/check-exact/ExactPrint.hs
index 3d493cfd22..0e81894017 100644
--- a/utils/check-exact/ExactPrint.hs
+++ b/utils/check-exact/ExactPrint.hs
@@ -3224,8 +3224,8 @@ instance ExactPrint (ConDecl GhcPs) where
exact (ConDeclGADT { con_g_ext = an
, con_names = cons
, con_bndrs = bndrs
- , con_mb_cxt = mcxt, con_g_args = args
- , con_res_ty = res_ty, con_doc = doc }) = do
+ , con_mb_cxt = mcxt
+ , con_body = body, con_doc = doc }) = do
mapM_ markAnnotated doc
mapM_ markAnnotated cons
markEpAnn an AnnDcolon
@@ -3237,13 +3237,14 @@ instance ExactPrint (ConDecl GhcPs) where
mapM_ markAnnotated mcxt
when (isJust mcxt) $ markEpAnn an AnnDarrow
-- mapM_ markAnnotated args
- case args of
- PrefixConGADT args' -> mapM_ markAnnotated args'
- RecConGADT fields arr -> do
+ case body of
+ PrefixConGADT body' ->
+ exact_prefix_con_gadt_sig_body body'
+ RecConGADT fields arr res_ty -> do
markAnnotated fields
markUniToken arr
+ markAnnotated res_ty
-- mapM_ markAnnotated (unLoc fields)
- markAnnotated res_ty
-- markAST _ (GHC.ConDeclGADT _ lns (GHC.L l forall) qvars mbCxt args typ _) = do
-- setContext (Set.singleton PrefixOp) $ markListIntercalate lns
-- mark GHC.AnnDcolon
@@ -3254,6 +3255,12 @@ instance ExactPrint (ConDecl GhcPs) where
-- markLocated typ
-- markManyOptional GHC.AnnCloseP
-- markTrailingSemi
+ where
+ exact_prefix_con_gadt_sig_body (PCGSRes res_ty) =
+ markAnnotated res_ty
+ exact_prefix_con_gadt_sig_body (PCGSAnonArg arg_ty body') = do
+ markAnnotated arg_ty
+ exact_prefix_con_gadt_sig_body body'
-- pprConDecl (ConDeclGADT { con_names = cons, con_qvars = qvars
-- , con_mb_cxt = mcxt, con_args = args
diff --git a/utils/haddock b/utils/haddock
-Subproject 58237d76c96325f25627bfd7cdad5b93364d29a
+Subproject d1aa841631b018c00b65e7a129c7e103cc8df6a