summaryrefslogtreecommitdiff
path: root/compiler/GHC/Iface
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2020-10-24 10:39:50 -0400
committerRyan Scott <ryan.gl.scott@gmail.com>2020-10-25 08:27:47 -0400
commit265f0811d568ea8f32daf78def96b1d4e1bd2d90 (patch)
treebe75aa2d2b48d4ef639cdcc5f03ddc0113d6efb0 /compiler/GHC/Iface
parent730bb59086ad1036143983c3fba61bd851bebc03 (diff)
downloadhaskell-265f0811d568ea8f32daf78def96b1d4e1bd2d90.tar.gz
Split HsConDecl{H98,GADT}Detailswip/T18844-alternate
Haskell98 and GADT constructors both use `HsConDeclDetails`, which includes `InfixCon`. But `InfixCon` is never used for GADT constructors, which results in an awkward unrepresentable state. This removes the unrepresentable state by: * Renaming the existing `HsConDeclDetails` synonym to `HsConDeclH98Details`, which emphasizes the fact that it is now only used for Haskell98-style data constructors, and * Creating a new `HsConDeclGADTDetails` data type with `PrefixConGADT` and `RecConGADT` constructors that closely resemble `PrefixCon` and `InfixCon` in `HsConDeclH98Details`. The key difference is that `HsConDeclGADTDetails` lacks any way to represent infix constructors. The rest of the patch is refactoring to accommodate the new structure of `HsConDecl{H98,GADT}Details`. Some highlights: * The `getConArgs` and `hsConDeclArgTys` functions have been removed, as there is no way to implement these functions uniformly for all `ConDecl`s. For the most part, their previous call sites now pattern match on the `ConDecl`s directly and do different things for `ConDeclH98`s and `ConDeclGADT`s. I did introduce one new function to make the transition easier: `getRecConArgs_maybe`, which extracts the arguments from a `RecCon(GADT)`. This is still possible since `RecCon(GADT)`s still use the same representation in both `HsConDeclH98Details` and `HsConDeclGADTDetails`, and since the pattern that `getRecConArgs_maybe` implements is used in several places, I thought it worthwhile to factor it out into its own function. * Previously, the `con_args` fields in `ConDeclH98` and `ConDeclGADT` were both of type `HsConDeclDetails`. Now, the former is of type `HsConDeclH98Details`, and the latter is of type `HsConDeclGADTDetails`, which are distinct types. As a result, I had to rename the `con_args` field in `ConDeclGADT` to `con_g_args` to make it typecheck. A consequence of all this is that the `con_args` field is now partial, so using `con_args` as a top-level field selector is dangerous. (Indeed, Haddock was using `con_args` at the top-level, which caused it to crash at runtime before I noticed what was wrong!) I decided to add a disclaimer in the 9.2.1 release notes to advertise this pitfall. Fixes #18844. Bumps the `haddock` submodule.
Diffstat (limited to 'compiler/GHC/Iface')
-rw-r--r--compiler/GHC/Iface/Ext/Ast.hs23
1 files changed, 14 insertions, 9 deletions
diff --git a/compiler/GHC/Iface/Ext/Ast.hs b/compiler/GHC/Iface/Ext/Ast.hs
index 01c5b6102f..e612ccd9c8 100644
--- a/compiler/GHC/Iface/Ext/Ast.hs
+++ b/compiler/GHC/Iface/Ext/Ast.hs
@@ -1319,6 +1319,10 @@ instance (ToHie arg, ToHie rec) => ToHie (HsConDetails arg rec) where
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 HiePass p => ToHie (Located (HsCmdTop (GhcPass p))) where
toHie (L span top) = concatM $ makeNode top span : case top of
HsCmdTop _ cmd ->
@@ -1530,7 +1534,7 @@ instance ToHie a => ToHie (HsScaled GhcRn a) where
instance ToHie (Located (ConDecl GhcRn)) where
toHie (L span decl) = concatM $ makeNode decl span : case decl of
ConDeclGADT { con_names = names, con_qvars = exp_vars, con_g_ext = imp_vars
- , con_mb_cxt = ctx, con_args = args, con_res_ty = typ } ->
+ , con_mb_cxt = ctx, con_g_args = args, con_res_ty = typ } ->
[ toHie $ map (C (Decl ConDec $ getRealSpan span)) names
, concatM $ [ bindingsOnly bindings
, toHie $ tvScopes resScope NoScope exp_vars ]
@@ -1541,7 +1545,9 @@ instance ToHie (Located (ConDecl GhcRn)) where
where
rhsScope = combineScopes argsScope tyScope
ctxScope = maybe NoScope mkLScope ctx
- argsScope = condecl_scope args
+ argsScope = case args of
+ PrefixConGADT xs -> scaled_args_scope xs
+ RecConGADT x -> mkLScope x
tyScope = mkLScope typ
resScope = ResolvedScopes [ctxScope, rhsScope]
bindings = map (C $ TyVarBind (mkScope (loc exp_vars)) resScope) imp_vars
@@ -1555,13 +1561,12 @@ instance ToHie (Located (ConDecl GhcRn)) where
where
rhsScope = combineScopes ctxScope argsScope
ctxScope = maybe NoScope mkLScope ctx
- argsScope = condecl_scope dets
- where condecl_scope :: HsConDeclDetails (GhcPass p) -> Scope
- condecl_scope args = case args of
- PrefixCon xs -> foldr combineScopes NoScope $ map (mkLScope . hsScaledThing) xs
- InfixCon a b -> combineScopes (mkLScope (hsScaledThing a))
- (mkLScope (hsScaledThing b))
- RecCon x -> mkLScope x
+ argsScope = case dets of
+ PrefixCon xs -> scaled_args_scope xs
+ InfixCon a b -> scaled_args_scope [a, b]
+ RecCon x -> mkLScope x
+ where scaled_args_scope :: [HsScaled GhcRn (LHsType GhcRn)] -> Scope
+ scaled_args_scope = foldr combineScopes NoScope . map (mkLScope . hsScaledThing)
instance ToHie (Located [Located (ConDeclField GhcRn)]) where
toHie (L span decls) = concatM $