f03b2730
by Vladislav Zavialov at 2026-11-01T13:14:36+01:00
Curried contexts in prefix GADT constructors (#27424)
Prefix GADT constructor declarations now accept multiple consecutive
contexts, equivalent to a single conjoined context:
data G a where
MkCurried :: C a => (D a, E a) => G a
MkConjoined :: (C a, D a, E a) => G a
This is a step towards GHC Proposal #402 "Stable GADT constructor syntax".
To represent multiple contexts, the `con_mb_cxt` field of `ConDeclGADT` has
been replaced by `con_cxts`, which stores a list instead of a Maybe:
- con_mb_cxt :: Maybe (LHsContext pass)
+ con_cxts :: [LHsContext pass]
The rest of this patch follows from this change.
Note that in ConDeclH98, the optional context is still stored as a Maybe.
To accommodate this difference, a few helper functions were generalised over
a Foldable container `t`:
hsConDeclTheta :: Foldable t => t (LHsContext ...) -> [LHsType ...]
pprLHsContext :: (Foldable t, ...) => t (LHsContext ...) -> SDoc
repContexts :: Foldable t => t (LHsContext GhcRn) -> MetaM (Core (M TH.Cxt))
tcHsContext :: Foldable t => t (LHsContext GhcRn) -> TcM [PredType]
In practice, the instantiations of `t` are either `Maybe` or `[]`.
Record-style GADT constructors continue to accept at most one context.
`splitLHsGadtTy` accounts for this by splitting off only the first context
if it detects record syntax, leaving the offending part of the type in the
body for the renamer to reject later on.
Test cases: T12087a T27424a T27424b T27424c T27424d GadtConSigs_th_dump1