summaryrefslogtreecommitdiff
path: root/compiler/GHC/Hs
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2020-09-13 08:58:40 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-09-15 15:21:43 -0400
commit4283feaa9e0826211f7a71d543054c989ea32965 (patch)
tree93f96b0599ed403b0180b0416c13f14a193bb1e4 /compiler/GHC/Hs
parentb3143f5a0827b640840ef241a30933dc23b69d91 (diff)
downloadhaskell-4283feaa9e0826211f7a71d543054c989ea32965.tar.gz
Introduce and use DerivClauseTys (#18662)
This switches `deriv_clause_tys` so that instead of using a list of `LHsSigType`s to represent the types in a `deriving` clause, it now uses a sum type. `DctSingle` represents a `deriving` clause with no enclosing parentheses, while `DctMulti` represents a clause with enclosing parentheses. This makes pretty-printing easier and avoids confusion between `HsParTy` and the enclosing parentheses in `deriving` clauses, which are different semantically. Fixes #18662.
Diffstat (limited to 'compiler/GHC/Hs')
-rw-r--r--compiler/GHC/Hs/Decls.hs58
-rw-r--r--compiler/GHC/Hs/Extension.hs6
-rw-r--r--compiler/GHC/Hs/Instances.hs5
3 files changed, 52 insertions, 17 deletions
diff --git a/compiler/GHC/Hs/Decls.hs b/compiler/GHC/Hs/Decls.hs
index c4d9ff99c5..a8dd4549e4 100644
--- a/compiler/GHC/Hs/Decls.hs
+++ b/compiler/GHC/Hs/Decls.hs
@@ -25,7 +25,8 @@
module GHC.Hs.Decls (
-- * Toplevel declarations
HsDecl(..), LHsDecl, HsDataDefn(..), HsDeriving, LHsFunDep,
- HsDerivingClause(..), LHsDerivingClause, NewOrData(..), newOrDataToFlavour,
+ HsDerivingClause(..), LHsDerivingClause, DerivClauseTys(..), LDerivClauseTys,
+ NewOrData(..), newOrDataToFlavour,
StandaloneKindSig(..), LStandaloneKindSig, standaloneKindSigName,
-- ** Class or type declarations
@@ -1321,15 +1322,8 @@ data HsDerivingClause pass
, deriv_clause_strategy :: Maybe (LDerivStrategy pass)
-- ^ The user-specified strategy (if any) to use when deriving
-- 'deriv_clause_tys'.
- , deriv_clause_tys :: XRec pass [LHsSigType pass]
+ , deriv_clause_tys :: LDerivClauseTys pass
-- ^ The types to derive.
- --
- -- It uses 'LHsSigType's because, with @-XGeneralizedNewtypeDeriving@,
- -- we can mention type variables that aren't bound by the datatype, e.g.
- --
- -- > data T b = ... deriving (C [a])
- --
- -- should produce a derived instance for @C [a] (T b)@.
}
| XHsDerivingClause !(XXHsDerivingClause pass)
@@ -1342,16 +1336,9 @@ instance OutputableBndrId p
, deriv_clause_tys = L _ dct })
= hsep [ text "deriving"
, pp_strat_before
- , pp_dct dct
+ , ppr dct
, pp_strat_after ]
where
- -- This complexity is to distinguish between
- -- deriving Show
- -- deriving (Show)
- pp_dct [HsIB { hsib_body = ty }]
- = ppr (parenthesizeHsType appPrec ty)
- pp_dct _ = parens (interpp'SP dct)
-
-- @via@ is unique in that in comes /after/ the class being derived,
-- so we must special-case it.
(pp_strat_before, pp_strat_after) =
@@ -1359,6 +1346,43 @@ instance OutputableBndrId p
Just (L _ via@ViaStrategy{}) -> (empty, ppr via)
_ -> (ppDerivStrategy dcs, empty)
+type LDerivClauseTys pass = XRec pass (DerivClauseTys pass)
+
+-- | The types mentioned in a single @deriving@ clause. This can come in two
+-- forms, 'DctSingle' or 'DctMulti', depending on whether the types are
+-- surrounded by enclosing parentheses or not. These parentheses are
+-- semantically differnt than 'HsParTy'. For example, @deriving ()@ means
+-- \"derive zero classes\" rather than \"derive an instance of the 0-tuple\".
+--
+-- 'DerivClauseTys' use 'LHsSigType' because @deriving@ clauses can mention
+-- type variables that aren't bound by the datatype, e.g.
+--
+-- > data T b = ... deriving (C [a])
+--
+-- should produce a derived instance for @C [a] (T b)@.
+data DerivClauseTys pass
+ = -- | A @deriving@ clause with a single type. Moreover, that type can only
+ -- be a type constructor without any arguments.
+ --
+ -- Example: @deriving Eq@
+ DctSingle (XDctSingle pass) (LHsSigType pass)
+
+ -- | A @deriving@ clause with a comma-separated list of types, surrounded
+ -- by enclosing parentheses.
+ --
+ -- Example: @deriving (Eq, C a)@
+ | DctMulti (XDctMulti pass) [LHsSigType pass]
+
+ | XDerivClauseTys !(XXDerivClauseTys pass)
+
+type instance XDctSingle (GhcPass _) = NoExtField
+type instance XDctMulti (GhcPass _) = NoExtField
+type instance XXDerivClauseTys (GhcPass _) = NoExtCon
+
+instance OutputableBndrId p => Outputable (DerivClauseTys (GhcPass p)) where
+ ppr (DctSingle _ ty) = ppr ty
+ ppr (DctMulti _ tys) = parens (interpp'SP tys)
+
-- | Located Standalone Kind Signature
type LStandaloneKindSig pass = XRec pass (StandaloneKindSig pass)
diff --git a/compiler/GHC/Hs/Extension.hs b/compiler/GHC/Hs/Extension.hs
index 072e3cc8a9..db1738ec02 100644
--- a/compiler/GHC/Hs/Extension.hs
+++ b/compiler/GHC/Hs/Extension.hs
@@ -447,6 +447,12 @@ type family XCHsDerivingClause x
type family XXHsDerivingClause x
-- -------------------------------------
+-- DerivClauseTys type families
+type family XDctSingle x
+type family XDctMulti x
+type family XXDerivClauseTys x
+
+-- -------------------------------------
-- ConDecl type families
type family XConDeclGADT x
type family XConDeclH98 x
diff --git a/compiler/GHC/Hs/Instances.hs b/compiler/GHC/Hs/Instances.hs
index 34afe3a72d..e1f3d29f21 100644
--- a/compiler/GHC/Hs/Instances.hs
+++ b/compiler/GHC/Hs/Instances.hs
@@ -163,6 +163,11 @@ deriving instance Data (HsDerivingClause GhcPs)
deriving instance Data (HsDerivingClause GhcRn)
deriving instance Data (HsDerivingClause GhcTc)
+-- deriving instance DataIdLR p p => Data (DerivClauseTys p)
+deriving instance Data (DerivClauseTys GhcPs)
+deriving instance Data (DerivClauseTys GhcRn)
+deriving instance Data (DerivClauseTys GhcTc)
+
-- deriving instance (DataIdLR p p) => Data (ConDecl p)
deriving instance Data (ConDecl GhcPs)
deriving instance Data (ConDecl GhcRn)