X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FhsSyn%2FHsDecls.lhs;h=9543cadfca61366620e0dc556e65ef7e7e71d594;hb=3ad8f84f6a75f240383e62a14472d14eb372dcd1;hp=070079e6a6cbb0a4ee9735bb63225aeb67129453;hpb=afef39736dcde6f4947a6f362f9e6b3586933db4;p=ghc-hetmet.git diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs index 070079e..9543cad 100644 --- a/compiler/hsSyn/HsDecls.lhs +++ b/compiler/hsSyn/HsDecls.lhs @@ -9,7 +9,7 @@ Definitions for: @TyDecl@ and @oCnDecl@, @ClassDecl@, \begin{code} module HsDecls ( HsDecl(..), LHsDecl, TyClDecl(..), LTyClDecl, - InstDecl(..), LInstDecl, NewOrData(..), + InstDecl(..), LInstDecl, DerivDecl(..), LDerivDecl, NewOrData(..), RuleDecl(..), LRuleDecl, RuleBndr(..), DefaultDecl(..), LDefaultDecl, SpliceDecl(..), ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..), @@ -18,7 +18,8 @@ module HsDecls ( DeprecDecl(..), LDeprecDecl, HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups, tcdName, tyClDeclNames, tyClDeclTyVars, - isClassDecl, isSynDecl, isDataDecl, + isClassDecl, isTFunDecl, isSynDecl, isDataDecl, isKindSigDecl, + isIdxTyDecl, countTyClDecls, conDetailsTys, instDeclATs, @@ -38,20 +39,19 @@ import HsPat ( HsConDetails(..), hsConArgs ) import HsImpExp ( pprHsVar ) import HsTypes import NameSet ( NameSet ) -import HscTypes ( DeprecTxt ) import CoreSyn ( RuleName ) -import Kind ( Kind, pprKind ) -import BasicTypes ( Activation(..) ) +import {- Kind parts of -} Type ( Kind, pprKind ) +import BasicTypes ( Activation(..), DeprecTxt ) import ForeignCall ( CCallTarget(..), DNCallSpec, CCallConv, Safety, CExportSpec(..), CLabelString ) -- others: -import FunDeps ( pprFundeps ) -import Class ( FunDep ) +import Class ( FunDep, pprFundeps ) import Outputable import Util ( count ) import SrcLoc ( Located(..), unLoc, noLoc ) import FastString +import Maybe ( isJust ) \end{code} @@ -67,6 +67,7 @@ type LHsDecl id = Located (HsDecl id) data HsDecl id = TyClD (TyClDecl id) | InstD (InstDecl id) + | DerivD (DerivDecl id) | ValD (HsBind id) | SigD (Sig id) | DefD (DefaultDecl id) @@ -95,6 +96,7 @@ data HsGroup id hs_valds :: HsValBinds id, hs_tyclds :: [LTyClDecl id], hs_instds :: [LInstDecl id], + hs_derivds :: [LDerivDecl id], hs_fixds :: [LFixitySig id], -- Snaffled out of both top-level fixity signatures, @@ -110,7 +112,7 @@ emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup a emptyRdrGroup = emptyGroup { hs_valds = emptyValBindsIn } emptyRnGroup = emptyGroup { hs_valds = emptyValBindsOut } -emptyGroup = HsGroup { hs_tyclds = [], hs_instds = [], +emptyGroup = HsGroup { hs_tyclds = [], hs_instds = [], hs_derivds = [], hs_fixds = [], hs_defds = [], hs_fords = [], hs_depds = [], hs_ruleds = [], hs_valds = error "emptyGroup hs_valds: Can't happen" } @@ -121,6 +123,7 @@ appendGroups hs_valds = val_groups1, hs_tyclds = tyclds1, hs_instds = instds1, + hs_derivds = derivds1, hs_fixds = fixds1, hs_defds = defds1, hs_fords = fords1, @@ -130,6 +133,7 @@ appendGroups hs_valds = val_groups2, hs_tyclds = tyclds2, hs_instds = instds2, + hs_derivds = derivds2, hs_fixds = fixds2, hs_defds = defds2, hs_fords = fords2, @@ -140,6 +144,7 @@ appendGroups hs_valds = val_groups1 `plusHsValBinds` val_groups2, hs_tyclds = tyclds1 ++ tyclds2, hs_instds = instds1 ++ instds2, + hs_derivds = derivds1 ++ derivds2, hs_fixds = fixds1 ++ fixds2, hs_defds = defds1 ++ defds2, hs_fords = fords1 ++ fords2, @@ -153,6 +158,7 @@ instance OutputableBndr name => Outputable (HsDecl name) where ppr (ValD binds) = ppr binds ppr (DefD def) = ppr def ppr (InstD inst) = ppr inst + ppr (DerivD deriv) = ppr deriv ppr (ForD fd) = ppr fd ppr (SigD sd) = ppr sd ppr (RuleD rd) = ppr rd @@ -163,6 +169,7 @@ instance OutputableBndr name => Outputable (HsGroup name) where ppr (HsGroup { hs_valds = val_decls, hs_tyclds = tycl_decls, hs_instds = inst_decls, + hs_derivds = deriv_decls, hs_fixds = fix_decls, hs_depds = deprec_decls, hs_fords = foreign_decls, @@ -172,6 +179,7 @@ instance OutputableBndr name => Outputable (HsGroup name) where ppr_ds deprec_decls, ppr_ds rule_decls, ppr val_decls, ppr_ds tycl_decls, ppr_ds inst_decls, + ppr_ds deriv_decls, ppr_ds foreign_decls] where ppr_ds [] = empty @@ -329,6 +337,31 @@ Interface file code: -- for a module. That's why (despite the misnomer) IfaceSig and ForeignType -- are both in TyClDecl +-- Representation of indexed types +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Kind signatures of indexed types come in two flavours: +-- +-- * kind signatures for type functions: variant `TyFunction' and +-- +-- * kind signatures for indexed data types and newtypes : variant `TyData' +-- iff a kind is present in `tcdKindSig' and there are no constructors in +-- `tcdCons'. +-- +-- Indexed types are represented by 'TyData' and 'TySynonym' using the field +-- 'tcdTyPats::Maybe [LHsType name]', with the following meaning: +-- +-- * If it is 'Nothing', we have a *vanilla* data type declaration or type +-- synonym declaration and 'tcdVars' contains the type parameters of the +-- type constructor. +-- +-- * If it is 'Just pats', we have the definition of an indexed type Then, +-- 'pats' are type patterns for the type-indexes of the type constructor +-- and 'tcdVars' are the variables in those patterns. Hence, the arity of +-- the indexed type (ie, the number of indexes) is 'length tcdTyPats' and +-- *not* 'length tcdVars'. +-- +-- In both cases, 'tcdVars' collects all variables we need to quantify over. + type LTyClDecl name = Located (TyClDecl name) data TyClDecl name @@ -344,7 +377,9 @@ data TyClDecl name tcdTyVars :: [LHsTyVarBndr name], -- Type variables tcdTyPats :: Maybe [LHsType name], -- Type patterns tcdKindSig:: Maybe Kind, -- Optional kind sig; - -- (only for the 'where' form) + -- (only for the + -- 'where' form and + -- indexed type sigs) tcdCons :: [LConDecl name], -- Data constructors -- For data T a = T1 | T2 a the LConDecls all have ResTyH98 @@ -359,8 +394,17 @@ data TyClDecl name -- are non-empty for the newtype-deriving case } + | TyFunction {tcdLName :: Located name, -- type constructor + tcdTyVars :: [LHsTyVarBndr name], -- type variables + tcdIso :: Bool, -- injective type? + tcdKind :: Kind -- result kind + } + | TySynonym { tcdLName :: Located name, -- type constructor tcdTyVars :: [LHsTyVarBndr name], -- type variables + tcdTyPats :: Maybe [LHsType name], -- Type patterns + -- 'Nothing' => vanilla + -- type synonym tcdSynRhs :: LHsType name -- synonym expansion } @@ -371,7 +415,8 @@ data TyClDecl name tcdSigs :: [LSig name], -- Methods' signatures tcdMeths :: LHsBinds name, -- Default methods tcdATs :: [LTyClDecl name] -- Associated types; ie - -- only 'TyData' + -- only 'TyData', + -- 'TyFunction', -- and 'TySynonym' } @@ -384,16 +429,38 @@ data NewOrData Simple classifiers \begin{code} -isDataDecl, isSynDecl, isClassDecl :: TyClDecl name -> Bool +isTFunDecl, isDataDecl, isSynDecl, isClassDecl, isKindSigDecl, isIdxTyDecl :: + TyClDecl name -> Bool + +-- type function kind signature +isTFunDecl (TyFunction {}) = True +isTFunDecl other = False -isSynDecl (TySynonym {}) = True -isSynDecl other = False +-- vanilla Haskell type synonym +isSynDecl (TySynonym {tcdTyPats = Nothing}) = True +isSynDecl other = False + +-- type equation (of a type function) +isTEqnDecl (TySynonym {tcdTyPats = Just _}) = True +isTEqnDecl other = False isDataDecl (TyData {}) = True isDataDecl other = False isClassDecl (ClassDecl {}) = True isClassDecl other = False + +-- kind signature (for an indexed type) +isKindSigDecl (TyFunction {} ) = True +isKindSigDecl (TyData {tcdKindSig = Just _, + tcdCons = [] }) = True +isKindSigDecl other = False + +-- definition of an instance of an indexed type +isIdxTyDecl tydecl + | isTEqnDecl tydecl = True + | isDataDecl tydecl = isJust (tcdTyPats tydecl) + | otherwise = False \end{code} Dealing with names @@ -408,8 +475,9 @@ tyClDeclNames :: Eq name => TyClDecl name -> [Located name] -- For record fields, the first one counts as the SrcLoc -- We use the equality to filter out duplicate field names -tyClDeclNames (TySynonym {tcdLName = name}) = [name] -tyClDeclNames (ForeignType {tcdLName = name}) = [name] +tyClDeclNames (TyFunction {tcdLName = name}) = [name] +tyClDeclNames (TySynonym {tcdLName = name}) = [name] +tyClDeclNames (ForeignType {tcdLName = name}) = [name] tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs, tcdATs = ats}) = cls_name : @@ -418,18 +486,22 @@ tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs, tcdATs = ats}) tyClDeclNames (TyData {tcdLName = tc_name, tcdCons = cons}) = tc_name : conDeclsNames (map unLoc cons) -tyClDeclTyVars (TySynonym {tcdTyVars = tvs}) = tvs -tyClDeclTyVars (TyData {tcdTyVars = tvs}) = tvs -tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs -tyClDeclTyVars (ForeignType {}) = [] +tyClDeclTyVars (TyFunction {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (TySynonym {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (TyData {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs +tyClDeclTyVars (ForeignType {}) = [] \end{code} \begin{code} -countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int) - -- class, data, newtype, synonym decls +countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int, Int, Int) + -- class, synonym decls, type function signatures, + -- type function equations, data, newtype countTyClDecls decls = (count isClassDecl decls, count isSynDecl decls, + count isTFunDecl decls, + count isTEqnDecl decls, count isDataTy decls, count isNewTy decls) where @@ -447,14 +519,29 @@ instance OutputableBndr name ppr (ForeignType {tcdLName = ltycon}) = hsep [ptext SLIT("foreign import type dotnet"), ppr ltycon] - ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdSynRhs = mono_ty}) - = hang (ptext SLIT("type") <+> pp_decl_head [] ltycon tyvars Nothing <+> equals) + ppr (TyFunction {tcdLName = ltycon, tcdTyVars = tyvars, tcdIso = iso, + tcdKind = kind}) + = typeMaybeIso <+> pp_decl_head [] ltycon tyvars Nothing <+> + dcolon <+> pprKind kind + where + typeMaybeIso = if iso + then ptext SLIT("type family iso") + else ptext SLIT("type family") + + ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdTyPats = typats, + tcdSynRhs = mono_ty}) + = hang (ptext SLIT("type") <+> + (if isJust typats then ptext SLIT("instance") else empty) <+> + pp_decl_head [] ltycon tyvars typats <+> + equals) 4 (ppr mono_ty) ppr (TyData {tcdND = new_or_data, tcdCtxt = context, tcdLName = ltycon, tcdTyVars = tyvars, tcdTyPats = typats, tcdKindSig = mb_sig, tcdCons = condecls, tcdDerivs = derivings}) - = pp_tydecl (ppr new_or_data <+> + = pp_tydecl (null condecls && isJust mb_sig) + (ppr new_or_data <+> + (if isJust typats then ptext SLIT("instance") else empty) <+> pp_decl_head (unLoc context) ltycon tyvars typats <+> ppr_sig mb_sig) (pp_condecls condecls) @@ -498,12 +585,14 @@ pp_condecls cs@(L _ ConDecl{ con_res = ResTyGADT _ } : _) -- In GADT syntax pp_condecls cs -- In H98 syntax = equals <+> sep (punctuate (ptext SLIT(" |")) (map ppr cs)) -pp_tydecl pp_head pp_decl_rhs derivings +pp_tydecl True pp_head pp_decl_rhs derivings + = pp_head +pp_tydecl False pp_head pp_decl_rhs derivings = hang pp_head 4 (sep [ - pp_decl_rhs, - case derivings of - Nothing -> empty - Just ds -> hsep [ptext SLIT("deriving"), parens (interpp'SP ds)] + pp_decl_rhs, + case derivings of + Nothing -> empty + Just ds -> hsep [ptext SLIT("deriving"), parens (interpp'SP ds)] ]) instance Outputable NewOrData where @@ -615,7 +704,8 @@ data InstDecl name -- figures out the quantified type variables for us. (LHsBinds name) [LSig name] -- User-supplied pragmatic info - [LTyClDecl name]-- Associated types + [LTyClDecl name]-- Associated types (ie, 'TyData' and + -- 'TySynonym' only) instance (OutputableBndr name) => Outputable (InstDecl name) where @@ -633,6 +723,23 @@ instDeclATs (InstDecl _ _ _ ats) = ats %************************************************************************ %* * +\subsection[DerivDecl]{A stand-alone instance deriving declaration +%* * +%************************************************************************ + +\begin{code} +type LDerivDecl name = Located (DerivDecl name) + +data DerivDecl name + = DerivDecl (LHsType name) (Located name) + +instance (OutputableBndr name) => Outputable (DerivDecl name) where + ppr (DerivDecl ty n) + = hsep [ptext SLIT("deriving"), ppr ty, ptext SLIT("for"), ppr n] +\end{code} + +%************************************************************************ +%* * \subsection[DefaultDecl]{A @default@ declaration} %* * %************************************************************************