Commit 72c7fe9a authored by Ryan Scott's avatar Ryan Scott Committed by Marge Bot
Browse files

Make GADT constructors adhere to the forall-or-nothing rule properly

Issue #18191 revealed that the types of GADT constructors don't quite
adhere to the `forall`-or-nothing rule. This patch serves to clean up
this sad state of affairs somewhat. The main change is not in the
code itself, but in the documentation, as this patch introduces two
sections to the GHC User's Guide:

* A "Formal syntax for GADTs" section that presents a BNF-style
  grammar for what is and isn't allowed in GADT constructor types.
  This mostly exists to codify GHC's existing behavior, but it also
  imposes a new restriction that addresses #18191: the outermost
  `forall` and/or context in a GADT constructor is not allowed to be
  surrounded by parentheses. Doing so would make these
  `forall`s/contexts nested, and GADTs do not support nested
  `forall`s/contexts at present.

* A "`forall`-or-nothing rule" section that describes exactly what
  the `forall`-or-nothing rule is all about. Surprisingly, there was
  no mention of this anywhere in the User's Guide up until now!

To adhere the new specification in the "Formal syntax for GADTs"
section of the User's Guide, the following code changes were made:

* A new function, `GHC.Hs.Type.splitLHsGADTPrefixTy`, was introduced.
  This is very much like `splitLHsSigmaTy`, except that it avoids
  splitting apart any parentheses, which can be syntactically
  significant for GADT types. See
  `Note [No nested foralls or contexts in GADT constructors]` in
  `GHC.Hs.Type`.

* `ConDeclGADTPrefixPs`, an extension constructor for `XConDecl`, was
  introduced so that `GHC.Parser.PostProcess.mkGadtDecl` can return
  it when given a prefix GADT constructor. Unlike `ConDeclGADT`,
  `ConDeclGADTPrefixPs` does not split the GADT type into its argument
  and result types, as this cannot be done until after the type is
  renamed (see `Note [GADT abstract syntax]` in `GHC.Hs.Decls` for why
  this is the case).

* `GHC.Renamer.Module.rnConDecl` now has an additional case for
  `ConDeclGADTPrefixPs` that (1) splits apart the full `LHsType` into
  its `forall`s, context, argument types, and result type, and
  (2) checks for nested `forall`s/contexts. Step (2) used to be
  performed the typechecker (in `GHC.Tc.TyCl.badDataConTyCon`) rather
  than the renamer, but now the relevant code from the typechecker
  can simply be deleted.

  One nice side effect of this change is that we are able to give a
  more accurate error message for GADT constructors that use visible
  dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`),
  which improves the stderr in the `T16326_Fail6` test case.

Fixes #18191. Bumps the Haddock submodule.
parent 9b607671
......@@ -5,6 +5,7 @@
{-# LANGUAGE DeriveDataTypeable, DeriveFunctor, DeriveFoldable,
DeriveTraversable #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
......@@ -70,7 +71,7 @@ module GHC.Hs.Decls (
ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..),
CImportSpec(..),
-- ** Data-constructor declarations
ConDecl(..), LConDecl,
ConDecl(..), LConDecl, ConDeclGADTPrefixPs(..),
HsConDeclDetails, hsConDeclArgTys, hsConDeclTheta,
getConNames, getConArgs,
-- ** Document comments
......@@ -109,6 +110,7 @@ import GHC.Core.Coercion
import GHC.Types.ForeignCall
import GHC.Hs.Extension
import GHC.Types.Name
import GHC.Types.Name.Reader
import GHC.Types.Name.Set
-- others:
......@@ -1422,54 +1424,144 @@ type instance XConDeclGADT GhcRn = [Name] -- Implicitly bound type variables
type instance XConDeclGADT GhcTc = NoExtField
type instance XConDeclH98 (GhcPass _) = NoExtField
type instance XXConDecl (GhcPass _) = NoExtCon
type instance XXConDecl GhcPs = ConDeclGADTPrefixPs
type instance XXConDecl GhcRn = NoExtCon
type instance XXConDecl GhcTc = NoExtCon
-- | Stores the types of prefix GADT constructors in the parser. This is used
-- in lieu of ConDeclGADT, which requires knowing the specific argument and
-- result types, as this is difficult to determine in general in the parser.
-- See @Note [GADT abstract syntax]@.
data ConDeclGADTPrefixPs = ConDeclGADTPrefixPs
{ con_gp_names :: [Located RdrName]
-- ^ The GADT constructor declaration's names.
, con_gp_ty :: LHsSigType GhcPs
-- ^ The type after the @::@.
, con_gp_doc :: Maybe LHsDocString
-- ^ A possible Haddock comment.
}
{- Note [GADT abstract syntax]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There's a wrinkle in ConDeclGADT
* For record syntax, it's all uniform. Given:
data T a where
K :: forall a. Ord a => { x :: [a], ... } -> T a
we make the a ConDeclGADT for K with
con_qvars = {a}
con_mb_cxt = Just [Ord a]
con_args = RecCon <the record fields>
con_res_ty = T a
We need the RecCon before the reanmer, so we can find the record field
binders in GHC.Hs.Utils.hsConDeclsBinders.
* However for a GADT constr declaration which is not a record, it can
be hard parse until we know operator fixities. Consider for example
C :: a :*: b -> a :*: b -> a :+: b
Initially this type will parse as
a :*: (b -> (a :*: (b -> (a :+: b))))
so it's hard to split up the arguments until we've done the precedence
resolution (in the renamer).
So: - In the parser (GHC.Parser.PostProcess.mkGadtDecl), we put the whole constr
type into the res_ty for a ConDeclGADT for now, and use
PrefixCon []
con_args = PrefixCon []
con_res_ty = a :*: (b -> (a :*: (b -> (a :+: b))))
- In the renamer (GHC.Rename.Module.rnConDecl), we unravel it after
operator fixities are sorted. So we generate. So we end
up with
con_args = PrefixCon [ a :*: b, a :*: b ]
con_res_ty = a :+: b
There are two broad ways to classify GADT constructors:
* Record-syntax constructors. For example:
data T a where
K :: forall a. Ord a => { x :: [a], ... } -> T a
* Prefix constructors, which do not use record syntax. For example:
data T a where
K :: forall a. Ord a => [a] -> ... -> T a
Initially, both forms of GADT constructors are initially parsed as a single
LHsType. However, GADTs have a certain structure, requiring distinct argument
and result types, as well as imposing restrictions on where `forall`s and
contexts can be (see "Wrinkle: No nested foralls or contexts" below). As a
result, it is convenient to split up the LHsType into its individual
components, which are stored in the ConDeclGADT constructor of ConDecl.
Where should this splitting occur? For GADT constructors with record syntax,
we split in the parser (in GHC.Parser.PostProcess.mkGadtDecl). We must do this
splitting before the renamer, as we need the record field names for use in
GHC.Hs.Utils.hsConDeclsBinders.
For prefix GADT constructors, however, the situation is more complicated. It
can be difficult to split a prefix GADT type until we know type operator
fixities. Consider this, for example:
C :: a :*: b -> a :*: b -> a :+: b
Initially, the type of C will parse as:
a :*: (b -> (a :*: (b -> (a :+: b))))
So it's hard to split up the arguments until we've done the precedence
resolution (in the renamer). (Unlike prefix GADT types, record GADT types
do not have this problem because of their uniform syntax.)
As a result, we deliberately avoid splitting prefix GADT types in the parser.
Instead, we store the entire LHsType in ConDeclGADTPrefixPs, a GHC-specific
extension constructor to ConDecl. Later, in the renamer
(in GHC.Rename.Module.rnConDecl), we resolve the fixities of all type operators
in the LHsType, which facilitates splitting it into argument and result types
accurately. We finish renaming a ConDeclGADTPrefixPs by putting the split
components into a ConDeclGADT. This is why ConDeclGADTPrefixPs has the suffix
-Ps, as it is only used by the parser.
Note that the existence of ConDeclGADTPrefixPs does not imply that ConDeclGADT
goes completely unused by the parser. Other consumers of GHC's abstract syntax
are still free to use ConDeclGADT. Indeed, both Haddock and Template Haskell
construct values of type `ConDecl GhcPs` by way of ConDeclGADT, as neither of
them have the same difficulties with operator precedence that GHC's parser
does. As an example, see GHC.ThToHs.cvtConstr, which converts Template Haskell
syntax into GHC syntax.
-----
-- Wrinkle: No nested foralls or contexts
-----
GADT constructors provide some freedom to change the order of foralls in their
types (see Note [DataCon user type variable binders] in GHC.Core.DataCon), but
this freedom is still limited. GADTs still require that all quantification
occurs "prenex". That is, any explicitly quantified type variables must occur
at the front of the GADT type, followed by any contexts, followed by the body of
the GADT type, in precisely that order. For instance:
data T where
MkT1 :: forall a b. (Eq a, Eq b) => a -> b -> T
-- OK
MkT2 :: forall a. Eq a => forall b. a -> b -> T
-- Rejected, `forall b` is nested
MkT3 :: forall a b. Eq a => Eq b => a -> b -> T
-- Rejected, `Eq b` is nested
MkT4 :: Int -> forall a. a -> T
-- Rejected, `forall a` is nested
MkT5 :: forall a. Int -> Eq a => a -> T
-- Rejected, `Eq a` is nested
MkT6 :: (forall a. a -> T)
-- Rejected, `forall a` is nested due to the surrounding parentheses
MkT7 :: (Eq a => a -> t)
-- Rejected, `Eq a` is nested due to the surrounding parentheses
For the full details, see the "Formal syntax for GADTs" section of the GHC
User's Guide. GHC enforces that GADT constructors do not have nested `forall`s
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
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.
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.
-}
-- | Haskell data Constructor Declaration Details
type HsConDeclDetails pass
= HsConDetails (LBangType pass) (Located [LConDeclField pass])
getConNames :: ConDecl (GhcPass p) -> [Located (IdP (GhcPass p))]
getConNames :: ConDecl GhcRn -> [Located Name]
getConNames ConDeclH98 {con_name = name} = [name]
getConNames ConDeclGADT {con_names = names} = names
getConArgs :: ConDecl pass -> HsConDeclDetails pass
getConArgs :: ConDecl GhcRn -> HsConDeclDetails GhcRn
getConArgs d = con_args d
hsConDeclArgTys :: HsConDeclDetails pass -> [LBangType pass]
......@@ -1518,16 +1610,30 @@ instance Outputable NewOrData where
ppr NewType = text "newtype"
ppr DataType = text "data"
pp_condecls :: (OutputableBndrId p) => [LConDecl (GhcPass p)] -> SDoc
pp_condecls cs@(L _ ConDeclGADT{} : _) -- In GADT syntax
pp_condecls :: forall p. OutputableBndrId p => [LConDecl (GhcPass p)] -> SDoc
pp_condecls cs
| gadt_syntax -- In GADT syntax
= hang (text "where") 2 (vcat (map ppr cs))
pp_condecls cs -- In H98 syntax
| otherwise -- In H98 syntax
= equals <+> sep (punctuate (text " |") (map ppr cs))
where
gadt_syntax = case cs of
[] -> False
(L _ ConDeclH98{} : _) -> False
(L _ ConDeclGADT{} : _) -> True
(L _ (XConDecl x) : _) ->
case ghcPass @p of
GhcPs | ConDeclGADTPrefixPs{} <- x
-> True
#if __GLASGOW_HASKELL__ < 811
GhcRn -> noExtCon x
GhcTc -> noExtCon x
#endif
instance (OutputableBndrId p) => Outputable (ConDecl (GhcPass p)) where
ppr = pprConDecl
pprConDecl :: (OutputableBndrId p) => ConDecl (GhcPass p) -> SDoc
pprConDecl :: forall p. OutputableBndrId p => ConDecl (GhcPass p) -> SDoc
pprConDecl (ConDeclH98 { con_name = L _ con
, con_ex_tvs = ex_tvs
, con_mb_cxt = mcxt
......@@ -1558,6 +1664,16 @@ pprConDecl (ConDeclGADT { con_names = cons, con_qvars = qvars
ppr_arrow_chain (a:as) = sep (a : map (arrow <+>) as)
ppr_arrow_chain [] = empty
pprConDecl (XConDecl x) =
case ghcPass @p of
GhcPs | ConDeclGADTPrefixPs { con_gp_names = cons, con_gp_ty = ty
, con_gp_doc = doc } <- x
-> ppr_mbDoc doc <+> ppr_con_names cons <+> dcolon <+> ppr ty
#if __GLASGOW_HASKELL__ < 811
GhcRn -> noExtCon x
GhcTc -> noExtCon x
#endif
ppr_con_names :: (OutputableBndr a) => [Located a] -> SDoc
ppr_con_names = pprWithCommas (pprPrefixOcc . unLoc)
......
......@@ -166,6 +166,8 @@ deriving instance Data (ConDecl GhcPs)
deriving instance Data (ConDecl GhcRn)
deriving instance Data (ConDecl GhcTc)
deriving instance Data ConDeclGADTPrefixPs
-- deriving instance DataIdLR p p => Data (TyFamInstDecl p)
deriving instance Data (TyFamInstDecl GhcPs)
deriving instance Data (TyFamInstDecl GhcRn)
......
......@@ -58,7 +58,8 @@ module GHC.Hs.Type (
hsLTyVarName, hsLTyVarNames, hsLTyVarLocName, hsExplicitLTyVarNames,
splitLHsInstDeclTy, getLHsInstDeclHead, getLHsInstDeclClass_maybe,
splitLHsPatSynTy,
splitLHsForAllTyInvis, splitLHsQualTy, splitLHsSigmaTyInvis,
splitLHsForAllTyInvis, splitLHsQualTy,
splitLHsSigmaTyInvis, splitLHsGADTPrefixTy,
splitHsFunType, hsTyGetAppHead_maybe,
mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy,
ignoreParens, hsSigType, hsSigWcType, hsPatSigType,
......@@ -1348,6 +1349,43 @@ splitLHsSigmaTyInvis ty
, (ctxt, ty2) <- splitLHsQualTy ty1
= (tvs, ctxt, ty2)
-- | Decompose a prefix GADT type into its constituent parts.
-- Returns @(mb_tvbs, mb_ctxt, body)@, where:
--
-- * @mb_tvbs@ are @Just@ the leading @forall@s, if they are provided.
-- Otherwise, they are @Nothing@.
--
-- * @mb_ctxt@ is @Just@ the context, if it is provided.
-- Otherwise, it is @Nothing@.
--
-- * @body@ is the body of the type after the optional @forall@s and context.
--
-- 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.
splitLHsGADTPrefixTy ::
LHsType pass
-> (Maybe [LHsTyVarBndr Specificity pass], Maybe (LHsContext pass), LHsType pass)
splitLHsGADTPrefixTy ty
| (mb_tvbs, rho) <- split_forall ty
, (mb_ctxt, tau) <- split_ctxt rho
= (mb_tvbs, mb_ctxt, tau)
where
-- NB: We do not use splitLHsForAllTyInvis below, since that looks through
-- parentheses...
split_forall (L _ (HsForAllTy { hst_fvf = ForallInvis, hst_bndrs = bndrs
, hst_body = rho }))
= (Just bndrs, rho)
split_forall sigma
= (Nothing, sigma)
-- ...similarly, we do not use splitLHsQualTy below, since that also looks
-- through parentheses.
split_ctxt (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau }))
= (Just cxt, tau)
split_ctxt tau
= (Nothing, tau)
-- | Decompose a type of the form @forall <tvs>. body@ into its constituent
-- parts. Only splits type variable binders that
-- were quantified invisibly (e.g., @forall a.@, with a dot).
......
......@@ -1242,7 +1242,8 @@ hsTyClForeignBinders tycl_decls foreign_decls
getSelectorNames (ns, fs) = map unLoc ns ++ map (extFieldOcc . unLoc) fs
-------------------
hsLTyClDeclBinders :: Located (TyClDecl (GhcPass p))
hsLTyClDeclBinders :: IsPass p
=> Located (TyClDecl (GhcPass p))
-> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)])
-- ^ Returns all the /binding/ names of the decl. The first one is
-- guaranteed to be the name of the decl. The first component
......@@ -1304,7 +1305,8 @@ getPatSynBinds binds
, L _ (PatSynBind _ psb) <- bagToList lbinds ]
-------------------
hsLInstDeclBinders :: LInstDecl (GhcPass p)
hsLInstDeclBinders :: IsPass p
=> LInstDecl (GhcPass p)
-> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)])
hsLInstDeclBinders (L _ (ClsInstD
{ cid_inst = ClsInstDecl
......@@ -1316,7 +1318,8 @@ hsLInstDeclBinders (L _ (TyFamInstD {})) = mempty
-------------------
-- | the 'SrcLoc' returned are for the whole declarations, not just the names
hsDataFamInstBinders :: DataFamInstDecl (GhcPass p)
hsDataFamInstBinders :: IsPass p
=> DataFamInstDecl (GhcPass p)
-> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)])
hsDataFamInstBinders (DataFamInstDecl { dfid_eqn = HsIB { hsib_body =
FamEqn { feqn_rhs = defn }}})
......@@ -1325,7 +1328,8 @@ hsDataFamInstBinders (DataFamInstDecl { dfid_eqn = HsIB { hsib_body =
-------------------
-- | the 'SrcLoc' returned are for the whole declarations, not just the names
hsDataDefnBinders :: HsDataDefn (GhcPass p)
hsDataDefnBinders :: IsPass p
=> HsDataDefn (GhcPass p)
-> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)])
hsDataDefnBinders (HsDataDefn { dd_cons = cons })
= hsConDeclsBinders cons
......@@ -1335,7 +1339,8 @@ hsDataDefnBinders (HsDataDefn { dd_cons = cons })
type Seen p = [LFieldOcc (GhcPass p)] -> [LFieldOcc (GhcPass p)]
-- Filters out ones that have already been seen
hsConDeclsBinders :: [LConDecl (GhcPass p)]
hsConDeclsBinders :: forall p. IsPass p
=> [LConDecl (GhcPass p)]
-> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)])
-- See hsLTyClDeclBinders for what this does
-- The function is boringly complicated because of the records
......@@ -1365,6 +1370,16 @@ hsConDeclsBinders cons
(remSeen', flds) = get_flds remSeen args
(ns, fs) = go remSeen' rs
XConDecl x -> case ghcPass @p of
GhcPs | ConDeclGADTPrefixPs { con_gp_names = names } <- x
-> (map (L loc . unLoc) names ++ ns, fs)
#if __GLASGOW_HASKELL__ < 811
GhcRn -> noExtCon x
GhcTc -> noExtCon x
#endif
where
(ns, fs) = go remSeen rs
get_flds :: Seen p -> HsConDeclDetails (GhcPass p)
-> (Seen p, [LFieldOcc (GhcPass p)])
get_flds remSeen (RecCon flds)
......
......@@ -2250,9 +2250,8 @@ gadt_constr :: { LConDecl GhcPs }
-- see Note [Difference in parsing GADT and data constructors]
-- Returns a list because of: C,D :: ty
: con_list '::' sigtypedoc
{% let (gadt,anns) = mkGadtDecl (unLoc $1) $3
in ams (sLL $1 $> gadt)
(mu AnnDcolon $2:anns) }
{% ams (sLL $1 $> (mkGadtDecl (unLoc $1) $3))
[mu AnnDcolon $2] }
{- Note [Difference in parsing GADT and data constructors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -685,43 +685,35 @@ mkConDeclH98 name mb_forall mb_cxt args
, con_args = args
, con_doc = Nothing }
-- | Construct a GADT-style data constructor from the constructor names and
-- their type. This will return different AST forms for record syntax
-- constructors and prefix constructors, as the latter must be handled
-- specially in the renamer. See @Note [GADT abstract syntax]@ in
-- "GHC.Hs.Decls" for the full story.
mkGadtDecl :: [Located RdrName]
-> LHsType GhcPs -- Always a HsForAllTy
-> (ConDecl GhcPs, [AddAnn])
-> LHsType GhcPs
-> ConDecl GhcPs
mkGadtDecl names ty
= (ConDeclGADT { con_g_ext = noExtField
, con_names = names
, con_forall = L l $ isLHsForAllTy ty'
, con_qvars = tvs
, con_mb_cxt = mcxt
, con_args = args
, con_res_ty = res_ty
, con_doc = Nothing }
, anns1 ++ anns2)
| Just (mtvs, mcxt, args, res_ty) <- mb_record_gadt ty
= ConDeclGADT { con_g_ext = noExtField
, con_names = names
, con_forall = L (getLoc ty) $ isJust mtvs
, con_qvars = fromMaybe [] mtvs
, con_mb_cxt = mcxt
, con_args = args
, con_res_ty = res_ty
, con_doc = Nothing }
| otherwise
= XConDecl $ ConDeclGADTPrefixPs { con_gp_names = names
, con_gp_ty = mkLHsSigType ty
, con_gp_doc = Nothing }
where
(ty'@(L l _),anns1) = peel_parens ty []
(tvs, rho) = splitLHsForAllTyInvis ty'
(mcxt, tau, anns2) = split_rho rho []
split_rho (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau })) ann
= (Just cxt, tau, ann)
split_rho (L l (HsParTy _ ty)) ann
= split_rho ty (ann++mkParensApiAnn l)
split_rho tau ann
= (Nothing, tau, ann)
(args, res_ty) = split_tau tau
-- See Note [GADT abstract syntax] in GHC.Hs.Decls
split_tau (L _ (HsFunTy _ (L loc (HsRecTy _ rf)) res_ty))
= (RecCon (L loc rf), res_ty)
split_tau tau
= (PrefixCon [], tau)
peel_parens (L l (HsParTy _ ty)) ann = peel_parens ty
(ann++mkParensApiAnn l)
peel_parens ty ann = (ty, ann)
mb_record_gadt ty
| (mtvs, mcxt, body_ty) <- splitLHsGADTPrefixTy ty
, L _ (HsFunTy _ (L loc (HsRecTy _ rf)) res_ty) <- body_ty
= Just (mtvs, mcxt, RecCon (L loc rf), res_ty)
| otherwise
= Nothing
setRdrNameSpace :: RdrName -> NameSpace -> RdrName
-- ^ This rather gruesome function is used mainly by the parser.
......
......@@ -12,24 +12,28 @@ import Control.Monad
-- -----------------------------------------------------------------------------
-- Adding documentation to record fields (used in parsing).
addFieldDoc :: LConDeclField a -> Maybe LHsDocString -> LConDeclField a
addFieldDoc :: LConDeclField GhcPs -> Maybe LHsDocString -> LConDeclField GhcPs
addFieldDoc (L l fld) doc
= L l (fld { cd_fld_doc = cd_fld_doc fld `mplus` doc })
addFieldDocs :: [LConDeclField a] -> Maybe LHsDocString -> [LConDeclField a]
addFieldDocs :: [LConDeclField GhcPs] -> Maybe LHsDocString -> [LConDeclField GhcPs]
addFieldDocs [] _ = []
addFieldDocs (x:xs) doc = addFieldDoc x doc : xs
addConDoc :: LConDecl a -> Maybe LHsDocString -> LConDecl a
addConDoc :: LConDecl GhcPs -> Maybe LHsDocString -> LConDecl GhcPs
addConDoc decl Nothing = decl
addConDoc (L p c) doc = L p ( c { con_doc = con_doc c `mplus` doc } )
addConDoc (L p c) doc = L p $ case c of
ConDeclH98 { con_doc = old_doc } -> c { con_doc = old_doc `mplus` doc }
ConDeclGADT { con_doc = old_doc } -> c { con_doc = old_doc `mplus` doc }
XConDecl x@(ConDeclGADTPrefixPs { con_gp_doc = old_doc }) ->
XConDecl (x { con_gp_doc = old_doc `mplus` doc })
addConDocs :: [LConDecl a] -> Maybe LHsDocString -> [LConDecl a]
addConDocs :: [LConDecl GhcPs] -> Maybe LHsDocString -> [LConDecl GhcPs]
addConDocs [] _ = []
addConDocs [x] doc = [addConDoc x doc]
addConDocs (x:xs) doc = x : addConDocs xs doc
addConDocFirst :: [LConDecl a] -> Maybe LHsDocString -> [LConDecl a]
addConDocFirst :: [LConDecl GhcPs] -> Maybe LHsDocString -> [LConDecl GhcPs]
addConDocFirst [] _ = []
addConDocFirst (x:xs) doc = addConDoc x doc : xs
......@@ -1746,8 +1746,9 @@ rnDataDefn doc (HsDataDefn { dd_ND = new_or_data, dd_cType = cType
}
where
h98_style = case condecls of -- Note [Stupid theta]
(L _ (ConDeclGADT {})) : _ -> False
_ -> True
(L _ (ConDeclGADT {})) : _ -> False
(L _ (XConDecl (ConDeclGADTPrefixPs {}))) : _ -> False
_ -> True
rn_derivs (L loc ds)
= do { deriv_strats_ok <- xoptM LangExt.DerivingStrategies
......@@ -2084,7 +2085,7 @@ rnConDecl decl@(ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs
do { (new_context, fvs1) <- rnMbContext ctxt mcxt
; (new_args, fvs2) <- rnConDeclDetails (unLoc new_name) ctxt args
; let all_fvs = fvs1 `plusFV` fvs2
; traceRn "rnConDecl" (ppr name <+> vcat
; traceRn "rnConDecl (ConDeclH98)" (ppr name <+> vcat
[ text "ex_tvs:" <+> ppr ex_tvs
, text "new_ex_dqtvs':" <+> ppr new_ex_tvs ])
......@@ -2127,22 +2128,68 @@ rnConDecl decl@(ConDeclGADT { con_names = names
; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty
; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3
(args', res_ty')
= case args of
InfixCon {} -> pprPanic "rnConDecl" (ppr names)
RecCon {} -> (new_args, new_res_ty)
PrefixCon as | (arg_tys, final_res_ty) <- splitHsFunType new_res_ty
-> ASSERT( null as )
-- See Note [GADT abstract syntax] in GHC.Hs.Decls
(PrefixCon arg_tys, final_res_ty)
; traceRn "rnConDecl2" (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs)
; traceRn "rnConDecl (ConDeclGADT)"
(ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs)
; return (decl { con_g_ext = implicit_tkvs, con_names = new_names
, con_qvars = explicit_tkvs, con_mb_cxt = new_cxt
, con_args = args', con_res_ty = res_ty'
, con_args = new_args, con_res_ty = new_res_ty
, con_doc = mb_doc' },
all_fvs) } }
-- This case is only used for prefix GADT constructors generated by GHC's
-- parser, where we do not know the argument types until type operator
-- precedence has been resolved. See Note [GADT abstract syntax] in
-- GHC.Hs.Decls for the full story.
rnConDecl (XConDecl (ConDeclGADTPrefixPs { con_gp_names = names, con_gp_ty = ty
, con_gp_doc = mb_doc }))
= do { mapM_ (addLocM checkConName) names
; new_names <- mapM lookupLocatedTopBndrRn names
; mb_doc' <- rnMbLHsDoc mb_doc
; let ctxt = ConDeclCtx new_names
; (ty', fvs) <- rnHsSigType ctxt TypeLevel Nothing ty
-- Now that operator precedence has been resolved, we can split the
-- GADT type into its individual components below.
; let HsIB { hsib_ext = implicit_tkvs, hsib_body = body } = ty'
(mb_explicit_tkvs, mb_cxt, tau) = splitLHsGADTPrefixTy body
lhas_forall = L (getLoc body) $ isJust mb_explicit_tkvs
explicit_tkvs = fromMaybe [] mb_explicit_tkvs
(arg_tys, res_ty) = splitHsFunType tau
arg_details = PrefixCon arg_tys
-- NB: The only possibility here is PrefixCon. RecCon is handled
-- separately, through ConDeclGADT, from the parser onwards.
-- 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.
; case res_ty of
L l (HsForAllTy { hst_fvf = fvf })
| ForallVis <- fvf
-> setSrcSpan l $ addErr $ withHsDocContext ctxt $ vcat
[ text "Illegal visible, dependent quantification" <+>
text "in the type of a term"
, text "(GHC does not yet support this)" ]
| ForallInvis <- fvf
-> nested_foralls_contexts_err l ctxt
L l (HsQualTy {})
-> nested_foralls_contexts_err l ctxt
_ -> pure ()
; traceRn "rnConDecl (ConDeclGADTPrefixPs)"
(ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs)
; pure (ConDeclGADT { con_g_ext = implicit_tkvs, con_names = new_names
, con_forall = lhas_forall, con_qvars = explicit_tkvs
, con_mb_cxt = mb_cxt, con_args = arg_details
, con_res_ty = res_ty, con_doc = mb_doc' },
fvs) }
where
nested_foralls_contexts_err :: SrcSpan -> HsDocContext -> RnM ()
nested_foralls_contexts_err l ctxt =