diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2020-09-13 08:58:40 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-09-15 15:21:43 -0400 |
commit | 4283feaa9e0826211f7a71d543054c989ea32965 (patch) | |
tree | 93f96b0599ed403b0180b0416c13f14a193bb1e4 /compiler/GHC/Hs | |
parent | b3143f5a0827b640840ef241a30933dc23b69d91 (diff) | |
download | haskell-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.hs | 58 | ||||
-rw-r--r-- | compiler/GHC/Hs/Extension.hs | 6 | ||||
-rw-r--r-- | compiler/GHC/Hs/Instances.hs | 5 |
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) |