X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FhsSyn%2FHsDecls.lhs;h=5253d11482adb1cfc615e850575d86c0d93e94cf;hb=9d7da331989abcd1844e9d03b8d1e4163796fa85;hp=ca0e32413a89f5f618975cad1234024fa4c84c79;hpb=e0445ffa5a89632b542e7d7bc2ad46d944716453;p=ghc-hetmet.git diff --git a/ghc/compiler/hsSyn/HsDecls.lhs b/ghc/compiler/hsSyn/HsDecls.lhs index ca0e324..5253d11 100644 --- a/ghc/compiler/hsSyn/HsDecls.lhs +++ b/ghc/compiler/hsSyn/HsDecls.lhs @@ -8,19 +8,20 @@ Definitions for: @TyDecl@ and @oCnDecl@, @ClassDecl@, \begin{code} module HsDecls ( - HsDecl(..), TyClDecl(..), InstDecl(..), RuleDecl(..), RuleBndr(..), - DefaultDecl(..), HsGroup(..), SpliceDecl(..), - ForeignDecl(..), ForeignImport(..), ForeignExport(..), + HsDecl(..), LHsDecl, TyClDecl(..), LTyClDecl, + InstDecl(..), LInstDecl, NewOrData(..), + RuleDecl(..), LRuleDecl, RuleBndr(..), + DefaultDecl(..), LDefaultDecl, SpliceDecl(..), + ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..), CImportSpec(..), FoType(..), - ConDecl(..), CoreDecl(..), - BangType(..), getBangType, getBangStrictness, unbangedType, - DeprecDecl(..), DeprecTxt, - tyClDeclName, tyClDeclNames, tyClDeclTyVars, - isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, - isTypeOrClassDecl, countTyClDecls, - isSourceInstDecl, instDeclDFun, ifaceRuleDeclName, + ConDecl(..), ResType(..), LConDecl, + DeprecDecl(..), LDeprecDecl, + HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups, + tcdName, tyClDeclNames, tyClDeclTyVars, + isClassDecl, isSynDecl, isDataDecl, + countTyClDecls, conDetailsTys, - collectRuleBndrSigTys, isSrcRule + collectRuleBndrSigTys, ) where #include "HsVersions.h" @@ -29,31 +30,26 @@ module HsDecls ( import {-# SOURCE #-} HsExpr( HsExpr, pprExpr ) -- Because Expr imports Decls via HsBracket -import HsBinds ( HsBinds, MonoBinds, Sig(..) ) +import HsBinds ( HsValBinds(..), HsBind, LHsBinds, plusHsValBinds, + Sig(..), LSig, LFixitySig, pprLHsBinds, + emptyValBindsIn, emptyValBindsOut ) import HsPat ( HsConDetails(..), hsConArgs ) import HsImpExp ( pprHsVar ) import HsTypes -import PprCore ( pprCoreRule ) -import HsCore ( UfExpr, UfBinder, HsIdInfo, pprHsIdInfo, - eq_ufBinders, eq_ufExpr, pprUfExpr - ) -import CoreSyn ( CoreRule(..), RuleName ) -import BasicTypes ( NewOrData(..), StrictnessMark(..), Activation(..), FixitySig(..) ) +import HscTypes ( DeprecTxt ) +import CoreSyn ( RuleName ) +import Kind ( Kind, pprKind ) +import BasicTypes ( Activation(..) ) import ForeignCall ( CCallTarget(..), DNCallSpec, CCallConv, Safety, - CExportSpec(..)) + CExportSpec(..), CLabelString ) -- others: -import Name ( NamedThing ) import FunDeps ( pprFundeps ) -import TyCon ( DataConDetails(..), visibleDataCons ) -import Class ( FunDep, DefMeth(..) ) -import CStrings ( CLabelString ) +import Class ( FunDep ) import Outputable -import Util ( eqListBy, count ) -import SrcLoc ( SrcLoc ) +import Util ( count ) +import SrcLoc ( Located(..), unLoc, noLoc ) import FastString - -import Maybe ( isNothing, fromJust ) \end{code} @@ -64,16 +60,17 @@ import Maybe ( isNothing, fromJust ) %************************************************************************ \begin{code} +type LHsDecl id = Located (HsDecl id) + data HsDecl id = TyClD (TyClDecl id) | InstD (InstDecl id) - | ValD (MonoBinds id) + | ValD (HsBind id) | SigD (Sig id) | DefD (DefaultDecl id) | ForD (ForeignDecl id) | DeprecD (DeprecDecl id) | RuleD (RuleDecl id) - | CoreD (CoreDecl id) | SpliceD (SpliceDecl id) -- NB: all top-level fixity decls are contained EITHER @@ -93,25 +90,58 @@ data HsDecl id -- fed to the renamer. data HsGroup id = HsGroup { - hs_valds :: HsBinds id, - -- Before the renamer, this is a single big MonoBinds, - -- with all the bindings, and all the signatures. - -- The renamer does dependency analysis, using ThenBinds - -- to give the structure - - hs_tyclds :: [TyClDecl id], - hs_instds :: [InstDecl id], + hs_valds :: HsValBinds id, + hs_tyclds :: [LTyClDecl id], + hs_instds :: [LInstDecl id], - hs_fixds :: [FixitySig id], + hs_fixds :: [LFixitySig id], -- Snaffled out of both top-level fixity signatures, -- and those in class declarations - hs_defds :: [DefaultDecl id], - hs_fords :: [ForeignDecl id], - hs_depds :: [DeprecDecl id], - hs_ruleds :: [RuleDecl id], - hs_coreds :: [CoreDecl id] + hs_defds :: [LDefaultDecl id], + hs_fords :: [LForeignDecl id], + hs_depds :: [LDeprecDecl id], + hs_ruleds :: [LRuleDecl id] } + +emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup a +emptyRdrGroup = emptyGroup { hs_valds = emptyValBindsIn } +emptyRnGroup = emptyGroup { hs_valds = emptyValBindsOut } + +emptyGroup = HsGroup { hs_tyclds = [], hs_instds = [], + hs_fixds = [], hs_defds = [], hs_fords = [], + hs_depds = [] ,hs_ruleds = [] } + +appendGroups :: HsGroup a -> HsGroup a -> HsGroup a +appendGroups + HsGroup { + hs_valds = val_groups1, + hs_tyclds = tyclds1, + hs_instds = instds1, + hs_fixds = fixds1, + hs_defds = defds1, + hs_fords = fords1, + hs_depds = depds1, + hs_ruleds = rulds1 } + HsGroup { + hs_valds = val_groups2, + hs_tyclds = tyclds2, + hs_instds = instds2, + hs_fixds = fixds2, + hs_defds = defds2, + hs_fords = fords2, + hs_depds = depds2, + hs_ruleds = rulds2 } + = + HsGroup { + hs_valds = val_groups1 `plusHsValBinds` val_groups2, + hs_tyclds = tyclds1 ++ tyclds2, + hs_instds = instds1 ++ instds2, + hs_fixds = fixds1 ++ fixds2, + hs_defds = defds1 ++ defds2, + hs_fords = fords1 ++ fords2, + hs_depds = depds1 ++ depds2, + hs_ruleds = rulds1 ++ rulds2 } \end{code} \begin{code} @@ -124,7 +154,6 @@ instance OutputableBndr name => Outputable (HsDecl name) where ppr (SigD sd) = ppr sd ppr (RuleD rd) = ppr rd ppr (DeprecD dd) = ppr dd - ppr (CoreD dd) = ppr dd ppr (SpliceD dd) = ppr dd instance OutputableBndr name => Outputable (HsGroup name) where @@ -135,21 +164,20 @@ instance OutputableBndr name => Outputable (HsGroup name) where hs_depds = deprec_decls, hs_fords = foreign_decls, hs_defds = default_decls, - hs_ruleds = rule_decls, - hs_coreds = core_decls }) + hs_ruleds = rule_decls }) = vcat [ppr_ds fix_decls, ppr_ds default_decls, ppr_ds deprec_decls, ppr_ds rule_decls, ppr val_decls, ppr_ds tycl_decls, ppr_ds inst_decls, - ppr_ds foreign_decls, ppr_ds core_decls] + ppr_ds foreign_decls] where ppr_ds [] = empty ppr_ds ds = text "" $$ vcat (map ppr ds) -data SpliceDecl id = SpliceDecl (HsExpr id) SrcLoc -- Top level splice +data SpliceDecl id = SpliceDecl (Located (HsExpr id)) -- Top level splice instance OutputableBndr name => Outputable (SpliceDecl name) where - ppr (SpliceDecl e _) = ptext SLIT("$") <> parens (pprExpr e) + ppr (SpliceDecl e) = ptext SLIT("$") <> parens (pprExpr (unLoc e)) \end{code} @@ -163,8 +191,8 @@ instance OutputableBndr name => Outputable (SpliceDecl name) where THE NAMING STORY -------------------------------- -Here is the story about the implicit names that go with type, class, and instance -decls. It's a bit tricky, so pay attention! +Here is the story about the implicit names that go with type, class, +and instance decls. It's a bit tricky, so pay attention! "Implicit" (or "system") binders ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -177,7 +205,8 @@ decls. It's a bit tricky, so pay attention! the worker for that constructor a selector for each superclass -All have occurrence names that are derived uniquely from their parent declaration. +All have occurrence names that are derived uniquely from their parent +declaration. None of these get separate definitions in an interface file; they are fully defined by the data or class decl. But they may *occur* in @@ -211,6 +240,7 @@ Here's the deal. (We distinguish the two cases because source-code decls have (Just binds) in the tcdMeths field, whereas interface decls have Nothing. In *source-code* class declarations: + - When parsing, every ClassOpSig gets a DefMeth with a suitable RdrName This is done by RdrHsSyn.mkClassOpSigDM @@ -296,59 +326,58 @@ Interface file code: -- for a module. That's why (despite the misnomer) IfaceSig and ForeignType -- are both in TyClDecl -data TyClDecl name - = IfaceSig { tcdName :: name, -- It may seem odd to classify an interface-file signature - tcdType :: HsType name, -- as a 'TyClDecl', but it's very convenient. - tcdIdInfo :: [HsIdInfo name], - tcdLoc :: SrcLoc - } +type LTyClDecl name = Located (TyClDecl name) - | ForeignType { tcdName :: name, -- See remarks about IfaceSig above - tcdExtName :: Maybe FastString, - tcdFoType :: FoType, - tcdLoc :: SrcLoc } +data TyClDecl name + = ForeignType { + tcdLName :: Located name, + tcdExtName :: Maybe FastString, + tcdFoType :: FoType + } | TyData { tcdND :: NewOrData, - tcdCtxt :: HsContext name, -- Context - tcdName :: name, -- Type constructor - tcdTyVars :: [HsTyVarBndr name], -- Type variables - tcdCons :: DataConDetails (ConDecl name), -- Data constructors - tcdDerivs :: Maybe (HsContext name), -- Derivings; Nothing => not specified - -- Just [] => derive exactly what is asked - tcdGeneric :: Maybe Bool, -- Nothing <=> source decl - -- Just x <=> interface-file decl; - -- x=True <=> generic converter functions available - -- We need this for imported data decls, since the - -- imported modules may have been compiled with - -- different flags to the current compilation unit - tcdLoc :: SrcLoc + tcdCtxt :: LHsContext name, -- Context + tcdLName :: Located name, -- Type constructor + tcdTyVars :: [LHsTyVarBndr name], -- Type variables + tcdKindSig :: Maybe Kind, -- Optional kind sig; + -- (only for the 'where' form) + + tcdCons :: [LConDecl name], -- Data constructors + -- For data T a = T1 | T2 a the LConDecls all have ResTyH98 + -- For data T a where { T1 :: T a } the LConDecls all have ResTyGADT + + tcdDerivs :: Maybe [LHsType name] + -- Derivings; Nothing => not specified + -- Just [] => derive exactly what is asked + -- These "types" must be of form + -- forall ab. C ty1 ty2 + -- Typically the foralls and ty args are empty, but they + -- are non-empty for the newtype-deriving case } - | TySynonym { tcdName :: name, -- type constructor - tcdTyVars :: [HsTyVarBndr name], -- type variables - tcdSynRhs :: HsType name, -- synonym expansion - tcdLoc :: SrcLoc + | TySynonym { tcdLName :: Located name, -- type constructor + tcdTyVars :: [LHsTyVarBndr name], -- type variables + tcdSynRhs :: LHsType name -- synonym expansion } - | ClassDecl { tcdCtxt :: HsContext name, -- Context... - tcdName :: name, -- Name of the class - tcdTyVars :: [HsTyVarBndr name], -- The class type variables - tcdFDs :: [FunDep name], -- Functional dependencies - tcdSigs :: [Sig name], -- Methods' signatures - tcdMeths :: Maybe (MonoBinds name), -- Default methods - -- Nothing for imported class decls - -- Just bs for source class decls - tcdLoc :: SrcLoc + | ClassDecl { tcdCtxt :: LHsContext name, -- Context... + tcdLName :: Located name, -- Name of the class + tcdTyVars :: [LHsTyVarBndr name], -- Class type variables + tcdFDs :: [Located (FunDep name)], -- Functional deps + tcdSigs :: [LSig name], -- Methods' signatures + tcdMeths :: LHsBinds name -- Default methods } + +data NewOrData + = NewType -- "newtype Blah ..." + | DataType -- "data Blah ..." + deriving( Eq ) -- Needed because Demand derives Eq \end{code} Simple classifiers \begin{code} -isIfaceSigDecl, isDataDecl, isSynDecl, isClassDecl :: TyClDecl name -> Bool - -isIfaceSigDecl (IfaceSig {}) = True -isIfaceSigDecl other = False +isDataDecl, isSynDecl, isClassDecl :: TyClDecl name -> Bool isSynDecl (TySynonym {}) = True isSynDecl other = False @@ -358,110 +387,41 @@ isDataDecl other = False isClassDecl (ClassDecl {}) = True isClassDecl other = False - -isTypeOrClassDecl (ClassDecl {}) = True -isTypeOrClassDecl (TyData {}) = True -isTypeOrClassDecl (TySynonym {}) = True -isTypeOrClassDecl (ForeignType {}) = True -isTypeOrClassDecl other = False \end{code} Dealing with names \begin{code} --------------------------------- -tyClDeclName :: TyClDecl name -> name -tyClDeclName tycl_decl = tcdName tycl_decl +tcdName :: TyClDecl name -> name +tcdName decl = unLoc (tcdLName decl) --------------------------------- -tyClDeclNames :: Eq name => TyClDecl name -> [(name, SrcLoc)] +tyClDeclNames :: Eq name => TyClDecl name -> [Located name] -- Returns all the *binding* names of the decl, along with their SrcLocs -- The first one is guaranteed to be the name of the decl -- For record fields, the first one counts as the SrcLoc -- We use the equality to filter out duplicate field names -tyClDeclNames (TySynonym {tcdName = name, tcdLoc = loc}) = [(name,loc)] -tyClDeclNames (IfaceSig {tcdName = name, tcdLoc = loc}) = [(name,loc)] -tyClDeclNames (ForeignType {tcdName = name, tcdLoc = loc}) = [(name,loc)] - -tyClDeclNames (ClassDecl {tcdName = cls_name, tcdSigs = sigs, tcdLoc = loc}) - = (cls_name,loc) : [(n,loc) | ClassOpSig n _ _ loc <- sigs] +tyClDeclNames (TySynonym {tcdLName = name}) = [name] +tyClDeclNames (ForeignType {tcdLName = name}) = [name] -tyClDeclNames (TyData {tcdName = tc_name, tcdCons = cons, tcdLoc = loc}) - = (tc_name,loc) : conDeclsNames cons +tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs}) + = cls_name : [n | L _ (TypeSig n _) <- sigs] +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 (IfaceSig {}) = [] -\end{code} - -\begin{code} -instance (NamedThing name, Ord name) => Eq (TyClDecl name) where - -- Used only when building interface files - (==) d1@(IfaceSig {}) d2@(IfaceSig {}) - = tcdName d1 == tcdName d2 && - tcdType d1 == tcdType d2 && - tcdIdInfo d1 == tcdIdInfo d2 - - (==) d1@(ForeignType {}) d2@(ForeignType {}) - = tcdName d1 == tcdName d2 && - tcdFoType d1 == tcdFoType d2 - - (==) d1@(TyData {}) d2@(TyData {}) - = tcdName d1 == tcdName d2 && - tcdND d1 == tcdND d2 && - eqWithHsTyVars (tcdTyVars d1) (tcdTyVars d2) (\ env -> - eq_hsContext env (tcdCtxt d1) (tcdCtxt d2) && - eq_hsCD env (tcdCons d1) (tcdCons d2) - ) - - (==) d1@(TySynonym {}) d2@(TySynonym {}) - = tcdName d1 == tcdName d2 && - eqWithHsTyVars (tcdTyVars d1) (tcdTyVars d2) (\ env -> - eq_hsType env (tcdSynRhs d1) (tcdSynRhs d2) - ) - - (==) d1@(ClassDecl {}) d2@(ClassDecl {}) - = tcdName d1 == tcdName d2 && - eqWithHsTyVars (tcdTyVars d1) (tcdTyVars d2) (\ env -> - eq_hsContext env (tcdCtxt d1) (tcdCtxt d2) && - eqListBy (eq_hsFD env) (tcdFDs d1) (tcdFDs d2) && - eqListBy (eq_cls_sig env) (tcdSigs d1) (tcdSigs d2) - ) - - (==) _ _ = False -- default case - -eq_hsCD env (DataCons c1) (DataCons c2) = eqListBy (eq_ConDecl env) c1 c2 -eq_hsCD env Unknown Unknown = True -eq_hsCD env (HasCons n1) (HasCons n2) = n1 == n2 -eq_hsCD env d1 d2 = False - -eq_hsFD env (ns1,ms1) (ns2,ms2) - = eqListBy (eq_hsVar env) ns1 ns2 && eqListBy (eq_hsVar env) ms1 ms2 - -eq_cls_sig env (ClassOpSig n1 dm1 ty1 _) (ClassOpSig n2 dm2 ty2 _) - = n1==n2 && dm1 `eq_dm` dm2 && eq_hsType env ty1 ty2 - where - -- Ignore the name of the default method for (DefMeth id) - -- This is used for comparing declarations before putting - -- them into interface files, and the name of the default - -- method isn't relevant - NoDefMeth `eq_dm` NoDefMeth = True - GenDefMeth `eq_dm` GenDefMeth = True - DefMeth _ `eq_dm` DefMeth _ = True - dm1 `eq_dm` dm2 = False \end{code} \begin{code} -countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int, Int) +countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int) -- class, data, newtype, synonym decls countTyClDecls decls = (count isClassDecl decls, count isSynDecl decls, - count isIfaceSigDecl decls, count isDataTy decls, count isNewTy decls) where @@ -476,58 +436,58 @@ countTyClDecls decls instance OutputableBndr name => Outputable (TyClDecl name) where - ppr (IfaceSig {tcdName = var, tcdType = ty, tcdIdInfo = info}) - = getPprStyle $ \ sty -> - hsep [ pprHsVar var, dcolon, ppr ty, pprHsIdInfo info ] - - ppr (ForeignType {tcdName = tycon}) - = hsep [ptext SLIT("foreign import type dotnet"), ppr tycon] + ppr (ForeignType {tcdLName = ltycon}) + = hsep [ptext SLIT("foreign import type dotnet"), ppr ltycon] - ppr (TySynonym {tcdName = tycon, tcdTyVars = tyvars, tcdSynRhs = mono_ty}) - = hang (ptext SLIT("type") <+> pp_decl_head [] tycon tyvars <+> equals) + ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdSynRhs = mono_ty}) + = hang (ptext SLIT("type") <+> pp_decl_head [] ltycon tyvars <+> equals) 4 (ppr mono_ty) - ppr (TyData {tcdND = new_or_data, tcdCtxt = context, tcdName = tycon, - tcdTyVars = tyvars, tcdCons = condecls, + ppr (TyData {tcdND = new_or_data, tcdCtxt = context, tcdLName = ltycon, + tcdTyVars = tyvars, tcdKindSig = mb_sig, tcdCons = condecls, tcdDerivs = derivings}) - = pp_tydecl (ptext keyword <+> pp_decl_head context tycon tyvars) + = pp_tydecl (ppr new_or_data <+> pp_decl_head (unLoc context) ltycon tyvars <+> ppr_sig mb_sig) (pp_condecls condecls) derivings where - keyword = case new_or_data of - NewType -> SLIT("newtype") - DataType -> SLIT("data") + ppr_sig Nothing = empty + ppr_sig (Just kind) = dcolon <+> pprKind kind - ppr (ClassDecl {tcdCtxt = context, tcdName = clas, tcdTyVars = tyvars, tcdFDs = fds, + ppr (ClassDecl {tcdCtxt = context, tcdLName = lclas, tcdTyVars = tyvars, tcdFDs = fds, tcdSigs = sigs, tcdMeths = methods}) | null sigs -- No "where" part = top_matter | otherwise -- Laid out = sep [hsep [top_matter, ptext SLIT("where {")], - nest 4 (sep [sep (map ppr_sig sigs), pp_methods, char '}'])] + nest 4 (sep [sep (map ppr_sig sigs), ppr methods, char '}'])] where - top_matter = ptext SLIT("class") <+> pp_decl_head context clas tyvars <+> pprFundeps fds + top_matter = ptext SLIT("class") <+> pp_decl_head (unLoc context) lclas tyvars <+> pprFundeps (map unLoc fds) ppr_sig sig = ppr sig <> semi - pp_methods = if isNothing methods - then empty - else ppr (fromJust methods) - -pp_decl_head :: OutputableBndr name => HsContext name -> name -> [HsTyVarBndr name] -> SDoc -pp_decl_head context thing tyvars = hsep [pprHsContext context, ppr thing, interppSP tyvars] - -pp_condecls Unknown = ptext SLIT("{- abstract -}") -pp_condecls (HasCons n) = ptext SLIT("{- abstract with") <+> int n <+> ptext SLIT("constructors -}") -pp_condecls (DataCons cs) = equals <+> sep (punctuate (ptext SLIT(" |")) (map ppr cs)) +pp_decl_head :: OutputableBndr name + => HsContext name + -> Located name + -> [LHsTyVarBndr name] + -> SDoc +pp_decl_head context thing tyvars + = hsep [pprHsContext context, ppr thing, interppSP tyvars] +pp_condecls cs@(L _ ConDecl{ con_res = ResTyGADT _ } : _) -- In GADT syntax + = hang (ptext SLIT("where")) 2 (vcat (map ppr cs)) +pp_condecls cs -- In H98 syntax + = equals <+> sep (punctuate (ptext SLIT(" |")) (map ppr cs)) pp_tydecl 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"), ppr_hs_context ds] + Just ds -> hsep [ptext SLIT("deriving"), parens (interpp'SP ds)] ]) + +instance Outputable NewOrData where + ppr NewType = ptext SLIT("newtype") + ppr DataType = ptext SLIT("data") \end{code} @@ -538,94 +498,88 @@ pp_tydecl pp_head pp_decl_rhs derivings %************************************************************************ \begin{code} +type LConDecl name = Located (ConDecl name) + +-- data T b = forall a. Eq a => MkT a b +-- MkT :: forall b a. Eq a => MkT a b + +-- data T b where +-- MkT1 :: Int -> T Int + +-- data T = Int `MkT` Int +-- | MkT2 + +-- data T a where +-- Int `MkT` Int :: T Int + data ConDecl name - = ConDecl name -- Constructor name; this is used for the - -- DataCon itself, and for the user-callable wrapper Id + = ConDecl + { con_name :: Located name -- Constructor name; this is used for the + -- DataCon itself, and for the user-callable wrapper Id + + , con_explicit :: HsExplicitForAll -- Is there an user-written forall? (cf. HStypes.HsForAllTy) + + , con_qvars :: [LHsTyVarBndr name] -- ResTyH98: the constructor's existential type variables + -- ResTyGADT: all the constructor's quantified type variables - [HsTyVarBndr name] -- Existentially quantified type variables - (HsContext name) -- ...and context - -- If both are empty then there are no existentials + , con_cxt :: LHsContext name -- The context. This *does not* include the + -- "stupid theta" which lives only in the TyData decl - (HsConDetails name (BangType name)) - SrcLoc + , con_details :: HsConDetails name (LBangType name) -- The main payload + + , con_res :: ResType name -- Result type of the constructor + } + +data ResType name + = ResTyH98 -- Constructor was declared using Haskell 98 syntax + | ResTyGADT (LHsType name) -- Constructor was declared using GADT-style syntax, + -- and here is its result type \end{code} \begin{code} -conDeclsNames :: Eq name => DataConDetails (ConDecl name) -> [(name,SrcLoc)] +conDeclsNames :: Eq name => [ConDecl name] -> [Located name] -- See tyClDeclNames for what this does -- The function is boringly complicated because of the records -- And since we only have equality, we have to be a little careful conDeclsNames cons - = snd (foldl do_one ([], []) (visibleDataCons cons)) + = snd (foldl do_one ([], []) cons) where - do_one (flds_seen, acc) (ConDecl name _ _ (RecCon flds) loc) - = (new_flds ++ flds_seen, (name,loc) : [(f,loc) | f <- new_flds] ++ acc) + do_one (flds_seen, acc) (ConDecl { con_name = lname, con_details = RecCon flds }) + = (map unLoc new_flds ++ flds_seen, lname : [f | f <- new_flds] ++ acc) where - new_flds = [ f | (f,_) <- flds, not (f `elem` flds_seen) ] + new_flds = [ f | (f,_) <- flds, not (unLoc f `elem` flds_seen) ] - do_one (flds_seen, acc) (ConDecl name _ _ _ loc) - = (flds_seen, (name,loc):acc) -\end{code} + do_one (flds_seen, acc) c + = (flds_seen, (con_name c):acc) -\begin{code} conDetailsTys details = map getBangType (hsConArgs details) - -eq_ConDecl env (ConDecl n1 tvs1 cxt1 cds1 _) - (ConDecl n2 tvs2 cxt2 cds2 _) - = n1 == n2 && - (eq_hsTyVars env tvs1 tvs2 $ \ env -> - eq_hsContext env cxt1 cxt2 && - eq_ConDetails env cds1 cds2) - -eq_ConDetails env (PrefixCon bts1) (PrefixCon bts2) - = eqListBy (eq_btype env) bts1 bts2 -eq_ConDetails env (InfixCon bta1 btb1) (InfixCon bta2 btb2) - = eq_btype env bta1 bta2 && eq_btype env btb1 btb2 -eq_ConDetails env (RecCon fs1) (RecCon fs2) - = eqListBy (eq_fld env) fs1 fs2 -eq_ConDetails env _ _ = False - -eq_fld env (ns1,bt1) (ns2, bt2) = ns1==ns2 && eq_btype env bt1 bt2 \end{code} -\begin{code} -data BangType name = BangType StrictnessMark (HsType name) - -getBangType (BangType _ ty) = ty -getBangStrictness (BangType s _) = s - -unbangedType ty = BangType NotMarkedStrict ty - -eq_btype env (BangType s1 t1) (BangType s2 t2) = s1==s2 && eq_hsType env t1 t2 -\end{code} \begin{code} instance (OutputableBndr name) => Outputable (ConDecl name) where - ppr (ConDecl con tvs cxt con_details loc) - = sep [pprHsForAll tvs cxt, ppr_con_details con con_details] + ppr = pprConDecl -ppr_con_details con (InfixCon ty1 ty2) - = hsep [ppr_bang ty1, ppr con, ppr_bang ty2] - --- ConDecls generated by MkIface.ifaceTyThing always have a PrefixCon, even --- if the constructor is an infix one. This is because in an interface file --- we don't distinguish between the two. Hence when printing these for the --- user, we need to parenthesise infix constructor names. -ppr_con_details con (PrefixCon tys) - = hsep (pprHsVar con : map ppr_bang tys) +pprConDecl (ConDecl con expl tvs cxt details ResTyH98) + = sep [pprHsForAll expl tvs cxt, ppr_details con details] + where + ppr_details con (InfixCon t1 t2) = hsep [ppr t1, pprHsVar con, ppr t2] + ppr_details con (PrefixCon tys) = hsep (pprHsVar con : map ppr tys) + ppr_details con (RecCon fields) = ppr con <+> ppr_fields fields -ppr_con_details con (RecCon fields) - = ppr con <+> braces (sep (punctuate comma (map ppr_field fields))) +pprConDecl (ConDecl con expl tvs cxt details (ResTyGADT res_ty)) + = sep [pprHsForAll expl tvs cxt, ppr con <+> ppr_details details] where - ppr_field (n, ty) = ppr n <+> dcolon <+> ppr_bang ty + ppr_details (PrefixCon arg_tys) = dcolon <+> ppr (foldr mk_fun_ty res_ty arg_tys) + ppr_details (RecCon fields) = ppr fields <+> dcolon <+> ppr res_ty + ppr_details (PrefixCon _) = pprPanic "pprConDecl" (ppr con) -instance OutputableBndr name => Outputable (BangType name) where - ppr = ppr_bang + mk_fun_ty a b = noLoc (HsFunTy a b) -ppr_bang (BangType s ty) = ppr s <> pprParendHsType ty +ppr_fields fields = braces (sep (punctuate comma (map ppr_field fields))) +ppr_field (n, ty) = ppr n <+> dcolon <+> ppr ty \end{code} - %************************************************************************ %* * \subsection[InstDecl]{An instance declaration @@ -633,48 +587,23 @@ ppr_bang (BangType s ty) = ppr s <> pprParendHsType ty %************************************************************************ \begin{code} +type LInstDecl name = Located (InstDecl name) + data InstDecl name - = InstDecl (HsType name) -- Context => Class Instance-type + = InstDecl (LHsType name) -- Context => Class Instance-type -- Using a polytype means that the renamer conveniently -- figures out the quantified type variables for us. + (LHsBinds name) + [LSig name] -- User-supplied pragmatic info - (MonoBinds name) - - [Sig name] -- User-supplied pragmatic info - - (Maybe name) -- Name for the dictionary function - -- Nothing for source-file instance decls - - SrcLoc - -isSourceInstDecl :: InstDecl name -> Bool -isSourceInstDecl (InstDecl _ _ _ maybe_dfun _) = isNothing maybe_dfun - -instDeclDFun :: InstDecl name -> Maybe name -instDeclDFun (InstDecl _ _ _ df _) = df -- A Maybe, but that's ok -\end{code} - -\begin{code} instance (OutputableBndr name) => Outputable (InstDecl name) where - ppr (InstDecl inst_ty binds uprags maybe_dfun_name src_loc) + ppr (InstDecl inst_ty binds uprags) = vcat [hsep [ptext SLIT("instance"), ppr inst_ty, ptext SLIT("where")], nest 4 (ppr uprags), - nest 4 (ppr binds) ] - where - pp_dfun = case maybe_dfun_name of - Just df -> ppr df - Nothing -> empty -\end{code} - -\begin{code} -instance Ord name => Eq (InstDecl name) where - -- Used for interface comparison only, so don't compare bindings - (==) (InstDecl inst_ty1 _ _ dfun1 _) (InstDecl inst_ty2 _ _ dfun2 _) - = inst_ty1 == inst_ty2 && dfun1 == dfun2 + nest 4 (pprLHsBinds binds) ] \end{code} - %************************************************************************ %* * \subsection[DefaultDecl]{A @default@ declaration} @@ -686,14 +615,15 @@ for the parser to check that; we pass them all through in the abstract syntax, and that restriction must be checked in the front end. \begin{code} +type LDefaultDecl name = Located (DefaultDecl name) + data DefaultDecl name - = DefaultDecl [HsType name] - SrcLoc + = DefaultDecl [LHsType name] instance (OutputableBndr name) => Outputable (DefaultDecl name) where - ppr (DefaultDecl tys src_loc) + ppr (DefaultDecl tys) = ptext SLIT("default") <+> parens (interpp'SP tys) \end{code} @@ -708,35 +638,31 @@ instance (OutputableBndr name) -- foreign declarations are distinguished as to whether they define or use a -- Haskell name -- --- * the Boolean value indicates whether the pre-standard deprecated syntax +-- * the Boolean value indicates whether the pre-standard deprecated syntax -- has been used -- -data ForeignDecl name - = ForeignImport name (HsType name) ForeignImport Bool SrcLoc -- defines name - | ForeignExport name (HsType name) ForeignExport Bool SrcLoc -- uses name +type LForeignDecl name = Located (ForeignDecl name) --- yield the Haskell name defined or used in a foreign declaration --- -foreignDeclName :: ForeignDecl name -> name -foreignDeclName (ForeignImport n _ _ _ _) = n -foreignDeclName (ForeignExport n _ _ _ _) = n +data ForeignDecl name + = ForeignImport (Located name) (LHsType name) ForeignImport Bool -- defines name + | ForeignExport (Located name) (LHsType name) ForeignExport Bool -- uses name -- specification of an imported external entity in dependence on the calling -- convention -- data ForeignImport = -- import of a C entity -- - -- * the two strings specifying a header file or library + -- * the two strings specifying a header file or library -- may be empty, which indicates the absence of a -- header or object specification (both are not used -- in the case of `CWrapper' and when `CFunction' -- has a dynamic target) -- - -- * the calling convention is irrelevant for code + -- * the calling convention is irrelevant for code -- generation in the case of `CLabel', but is needed -- for pretty printing -- - -- * `Safety' is irrelevant for `CLabel' and `CWrapper' + -- * `Safety' is irrelevant for `CLabel' and `CWrapper' -- CImport CCallConv -- ccall or stdcall Safety -- safe or unsafe @@ -771,10 +697,10 @@ data FoType = DNType -- In due course we'll add subtype stuff -- instance OutputableBndr name => Outputable (ForeignDecl name) where - ppr (ForeignImport n ty fimport _ _) = + ppr (ForeignImport n ty fimport _) = ptext SLIT("foreign import") <+> ppr fimport <+> ppr n <+> dcolon <+> ppr ty - ppr (ForeignExport n ty fexport _ _) = + ppr (ForeignExport n ty fexport _) = ptext SLIT("foreign export") <+> ppr fexport <+> ppr n <+> dcolon <+> ppr ty @@ -793,12 +719,10 @@ instance Outputable ForeignImport where pprLib lib <> ppr lbl pprCEntity header lib (CFunction (DynamicTarget)) = ptext SLIT("dynamic") - pprCEntity header lib (CFunction (CasmTarget _)) = - panic "HsDecls.pprCEntity: malformed C function target" pprCEntity _ _ (CWrapper) = ptext SLIT("wrapper") -- - pprLib lib | nullFastString lib = empty - | otherwise = char '[' <> ppr lib <> char ']' + pprLib lib | nullFS lib = empty + | otherwise = char '[' <> ppr lib <> char ']' instance Outputable ForeignExport where ppr (CExport (CExportStatic lbl cconv)) = @@ -818,68 +742,32 @@ instance Outputable FoType where %************************************************************************ \begin{code} +type LRuleDecl name = Located (RuleDecl name) + data RuleDecl name = HsRule -- Source rule RuleName -- Rule name Activation [RuleBndr name] -- Forall'd vars; after typechecking this includes tyvars - (HsExpr name) -- LHS - (HsExpr name) -- RHS - SrcLoc - - | IfaceRule -- One that's come in from an interface file; pre-typecheck - RuleName - Activation - [UfBinder name] -- Tyvars and term vars - name -- Head of lhs - [UfExpr name] -- Args of LHS - (UfExpr name) -- Pre typecheck - SrcLoc - - | IfaceRuleOut -- Post typecheck - name -- Head of LHS - CoreRule - -isSrcRule (HsRule _ _ _ _ _ _) = True -isSrcRule other = False - -ifaceRuleDeclName :: RuleDecl name -> name -ifaceRuleDeclName (IfaceRule _ _ _ n _ _ _) = n -ifaceRuleDeclName (IfaceRuleOut n r) = n -ifaceRuleDeclName (HsRule fs _ _ _ _ _) = pprPanic "ifaceRuleDeclName" (ppr fs) + (Located (HsExpr name)) -- LHS + (Located (HsExpr name)) -- RHS data RuleBndr name - = RuleBndr name - | RuleBndrSig name (HsType name) + = RuleBndr (Located name) + | RuleBndrSig (Located name) (LHsType name) -collectRuleBndrSigTys :: [RuleBndr name] -> [HsType name] +collectRuleBndrSigTys :: [RuleBndr name] -> [LHsType name] collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ ty <- bndrs] -instance (NamedThing name, Ord name) => Eq (RuleDecl name) where - -- Works for IfaceRules only; used when comparing interface file versions - (IfaceRule n1 a1 bs1 f1 es1 rhs1 _) == (IfaceRule n2 a2 bs2 f2 es2 rhs2 _) - = n1==n2 && f1 == f2 && a1==a2 && - eq_ufBinders emptyEqHsEnv bs1 bs2 (\env -> - eqListBy (eq_ufExpr env) (rhs1:es1) (rhs2:es2)) - instance OutputableBndr name => Outputable (RuleDecl name) where - ppr (HsRule name act ns lhs rhs loc) + ppr (HsRule name act ns lhs rhs) = sep [text "{-# RULES" <+> doubleQuotes (ftext name) <+> ppr act, - pp_forall, pprExpr lhs, equals <+> pprExpr rhs, - text "#-}" ] + nest 4 (pp_forall <+> pprExpr (unLoc lhs)), + nest 4 (equals <+> pprExpr (unLoc rhs) <+> text "#-}") ] where pp_forall | null ns = empty | otherwise = text "forall" <+> fsep (map ppr ns) <> dot - ppr (IfaceRule name act tpl_vars fn tpl_args rhs loc) - = hsep [ doubleQuotes (ftext name), ppr act, - ptext SLIT("__forall") <+> braces (interppSP tpl_vars), - ppr fn <+> sep (map (pprUfExpr parens) tpl_args), - ptext SLIT("=") <+> ppr rhs - ] <+> semi - - ppr (IfaceRuleOut fn rule) = pprCoreRule (ppr fn) rule - instance OutputableBndr name => Outputable (RuleBndr name) where ppr (RuleBndr name) = ppr name ppr (RuleBndrSig name ty) = ppr name <> dcolon <> ppr ty @@ -895,31 +783,11 @@ instance OutputableBndr name => Outputable (RuleBndr name) where We use exported entities for things to deprecate. \begin{code} -data DeprecDecl name = Deprecation name DeprecTxt SrcLoc +type LDeprecDecl name = Located (DeprecDecl name) -type DeprecTxt = FastString -- reason/explanation for deprecation +data DeprecDecl name = Deprecation name DeprecTxt instance OutputableBndr name => Outputable (DeprecDecl name) where - ppr (Deprecation thing txt _) + ppr (Deprecation thing txt) = hsep [text "{-# DEPRECATED", ppr thing, doubleQuotes (ppr txt), text "#-}"] \end{code} - - -%************************************************************************ -%* * - External-core declarations -%* * -%************************************************************************ - -\begin{code} -data CoreDecl name -- a Core value binding (from 'external Core' input) - = CoreDecl name - (HsType name) - (UfExpr name) - SrcLoc - -instance OutputableBndr name => Outputable (CoreDecl name) where - ppr (CoreDecl var ty rhs loc) - = getPprStyle $ \ sty -> - hsep [ pprHsVar var, dcolon, ppr ty, ppr rhs ] -\end{code}