X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FhsSyn%2FHsBinds.lhs;h=702e7365847e962c0759ef691d8cd044cd4f12a5;hp=d1c2234cc08cce16fc8cbd79c6b25b672c05da0d;hb=432b9c9322181a3644083e3c19b7e240d90659e7;hpb=30c122df62ec75f9ed7f392f24c2925675bf1d06 diff --git a/compiler/hsSyn/HsBinds.lhs b/compiler/hsSyn/HsBinds.lhs index d1c2234..702e736 100644 --- a/compiler/hsSyn/HsBinds.lhs +++ b/compiler/hsSyn/HsBinds.lhs @@ -16,8 +16,6 @@ Datatype for: @BindGroup@, @Bind@, @Sig@, @Bind@. module HsBinds where -#include "HsVersions.h" - import {-# SOURCE #-} HsExpr ( HsExpr, pprExpr, LHsExpr, MatchGroup, pprFunBind, GRHSs, pprPatBind ) @@ -83,40 +81,44 @@ type LHsBindLR idL idR = Located (HsBindLR idL idR) type LHsBindsLR idL idR = Bag (LHsBindLR idL idR) data HsBindLR idL idR - = FunBind { -- FunBind is used for both functions f x = e - -- and variables f = \x -> e --- Reason 1: Special case for type inference: see TcBinds.tcMonoBinds --- --- Reason 2: instance decls can only have FunBinds, which is convenient --- If you change this, you'll need tochange e.g. rnMethodBinds - --- But note that the form f :: a->a = ... --- parses as a pattern binding, just like --- (f :: a -> a) = ... + = -- | FunBind is used for both functions @f x = e@ + -- and variables @f = \x -> e@ + -- + -- Reason 1: Special case for type inference: see 'TcBinds.tcMonoBinds'. + -- + -- Reason 2: Instance decls can only have FunBinds, which is convenient. + -- If you change this, you'll need to change e.g. rnMethodBinds + -- + -- But note that the form @f :: a->a = ...@ + -- parses as a pattern binding, just like + -- @(f :: a -> a) = ... @ + FunBind { fun_id :: Located idL, - fun_infix :: Bool, -- True => infix declaration + fun_infix :: Bool, -- ^ True => infix declaration - fun_matches :: MatchGroup idR, -- The payload + fun_matches :: MatchGroup idR, -- ^ The payload - fun_co_fn :: HsWrapper, -- Coercion from the type of the MatchGroup to the type of + fun_co_fn :: HsWrapper, -- ^ Coercion from the type of the MatchGroup to the type of -- the Id. Example: + -- @ -- f :: Int -> forall a. a -> a -- f x y = y + -- @ -- Then the MatchGroup will have type (Int -> a' -> a') -- (with a free type variable a'). The coercion will take -- a CoreExpr of this type and convert it to a CoreExpr of -- type Int -> forall a'. a' -> a' -- Notice that the coercion captures the free a'. - bind_fvs :: NameSet, -- After the renamer, this contains a superset of the + bind_fvs :: NameSet, -- ^ After the renamer, this contains a superset of the -- Names of the other binders in this binding group that -- are free in the RHS of the defn -- Before renaming, and after typechecking, -- the field is unused; it's just an error thunk - fun_tick :: Maybe (Int,[idR]) -- This is the (optional) module-local tick number. + fun_tick :: Maybe (Int,[idR]) -- ^ This is the (optional) module-local tick number. } | PatBind { -- The pattern is never a simple variable; @@ -133,8 +135,9 @@ data HsBindLR idL idR } | AbsBinds { -- Binds abstraction; TRANSLATION - abs_tvs :: [TyVar], - abs_dicts :: [DictId], + abs_tvs :: [TyVar], + abs_dicts :: [DictId], -- Includes equality constraints + -- AbsBinds only gets used when idL = idR after renaming, -- but these need to be idL's for the collect... code in HsUtil to have -- the right type @@ -179,8 +182,8 @@ instance (OutputableBndr idL, OutputableBndr idR) => Outputable (HsValBindsLR id pprValBindsForUser (unionManyBags (map snd sccs)) sigs where ppr_scc (rec_flag, binds) = pp_rec rec_flag <+> pprLHsBinds binds - pp_rec Recursive = ptext SLIT("rec") - pp_rec NonRecursive = ptext SLIT("nonrec") + pp_rec Recursive = ptext (sLit "rec") + pp_rec NonRecursive = ptext (sLit "nonrec") -- *not* pprLHsBinds because we don't want braces; 'let' and -- 'where' include a list of HsBindGroups and we don't want @@ -276,7 +279,7 @@ ppr_monobind (FunBind { fun_id = fun, fun_infix = inf, ppr_monobind (AbsBinds { abs_tvs = tyvars, abs_dicts = dictvars, abs_exports = exports, abs_binds = val_binds }) - = sep [ptext SLIT("AbsBinds"), + = sep [ptext (sLit "AbsBinds"), brackets (interpp'SP tyvars), brackets (interpp'SP dictvars), brackets (sep (punctuate comma (map ppr_exp exports)))] @@ -286,7 +289,7 @@ ppr_monobind (AbsBinds { abs_tvs = tyvars, abs_dicts = dictvars, $$ pprLHsBinds val_binds ) where ppr_exp (tvs, gbl, lcl, prags) - = vcat [ppr gbl <+> ptext SLIT("<=") <+> ppr tvs <+> ppr lcl, + = vcat [ppr gbl <+> ptext (sLit "<=") <+> ppr tvs <+> ppr lcl, nest 2 (vcat (map (pprPrag gbl) prags))] \end{code} @@ -339,11 +342,15 @@ data HsWrapper | WpCompose HsWrapper HsWrapper -- (\a1..an. []) `WpCompose` (\x1..xn. []) -- = (\a1..an \x1..xn. []) - | WpCo Coercion -- A cast: [] `cast` co - -- Guaranteedn not the identity coercion + | WpCast Coercion -- A cast: [] `cast` co + -- Guaranteed not the identity coercion + + | WpApp Var -- [] d the 'd' is a type-class dictionary or coercion variable - | WpApp Var -- [] d the 'd' is a type-class dictionary | WpTyApp Type -- [] t the 't' is a type or corecion + -- ToDo: it'd be tidier if 't' was always a type (not coercion), + -- but that is inconvenient in Inst.instCallDicts + | WpLam Var -- \d. [] the 'd' is a type-class dictionary or coercion variable | WpTyLam TyVar -- \a. [] the 'a' is a type variable (not coercion var) | WpInline -- inline_me [] Wrap inline around the thing @@ -354,20 +361,20 @@ data HsWrapper -- (would be nicer to be core bindings) instance Outputable HsWrapper where - ppr co_fn = pprHsWrapper (ptext SLIT("<>")) co_fn + ppr co_fn = pprHsWrapper (ptext (sLit "<>")) co_fn pprHsWrapper :: SDoc -> HsWrapper -> SDoc pprHsWrapper it wrap = let help it WpHole = it help it (WpCompose f1 f2) = help (help it f2) f1 - help it (WpCo co) = sep [it, nest 2 (ptext SLIT("`cast`") <+> pprParendType co)] + help it (WpCast co) = sep [it, nest 2 (ptext (sLit "`cast`") <+> pprParendType co)] help it (WpApp id) = sep [it, nest 2 (ppr id)] - help it (WpTyApp ty) = sep [it, ptext SLIT("@") <+> pprParendType ty] - help it (WpLam id) = sep [ptext SLIT("\\") <> pprBndr LambdaBind id <> dot, it] - help it (WpTyLam tv) = sep [ptext SLIT("/\\") <> pprBndr LambdaBind tv <> dot, it] - help it (WpLet binds) = sep [ptext SLIT("let") <+> braces (ppr binds), it] - help it WpInline = sep [ptext SLIT("_inline_me_"), it] + help it (WpTyApp ty) = sep [it, ptext (sLit "@") <+> pprParendType ty] + help it (WpLam id) = sep [ptext (sLit "\\") <> pprBndr LambdaBind id <> dot, it] + help it (WpTyLam tv) = sep [ptext (sLit "/\\") <> pprBndr LambdaBind tv <> dot, it] + help it (WpLet binds) = sep [ptext (sLit "let") <+> braces (ppr binds), it] + help it WpInline = sep [ptext (sLit "_inline_me_"), it] in -- in debug mode, print the wrapper -- otherwise just print what's inside @@ -381,13 +388,13 @@ c1 <.> c2 = c1 `WpCompose` c2 mkWpTyApps :: [Type] -> HsWrapper mkWpTyApps tys = mk_co_fn WpTyApp (reverse tys) -mkWpApps :: [Id] -> HsWrapper +mkWpApps :: [Var] -> HsWrapper mkWpApps ids = mk_co_fn WpApp (reverse ids) mkWpTyLams :: [TyVar] -> HsWrapper mkWpTyLams ids = mk_co_fn WpTyLam ids -mkWpLams :: [Id] -> HsWrapper +mkWpLams :: [Var] -> HsWrapper mkWpLams ids = mk_co_fn WpLam ids mk_co_fn :: (a -> HsWrapper) -> [a] -> HsWrapper @@ -419,12 +426,18 @@ type LSig name = Located (Sig name) data Sig name -- Signatures and pragmas = -- An ordinary type signature -- f :: Num a => a -> a - TypeSig (Located name) -- A bog-std type signature - (LHsType name) + TypeSig (Located name) (LHsType name) + + -- A type signature in generated code, notably the code + -- generated for record selectors. We simply record + -- the desired Id itself, replete with its name, type + -- and IdDetails. Otherwise it's just like a type + -- signature: there should be an accompanying binding + | IdSig Id -- An ordinary fixity declaration -- infixl *** 8 - | FixSig (FixitySig name) -- Fixity declaration + | FixSig (FixitySig name) -- An inline pragma -- {#- INLINE f #-} @@ -467,25 +480,22 @@ isSpecPrag _ = False \end{code} \begin{code} -okBindSig :: NameSet -> LSig Name -> Bool -okBindSig ns sig = sigForThisGroup ns sig +okBindSig :: Sig a -> Bool +okBindSig _ = True -okHsBootSig :: LSig Name -> Bool -okHsBootSig (L _ (TypeSig _ _)) = True -okHsBootSig (L _ (FixSig _)) = True -okHsBootSig _ = False +okHsBootSig :: Sig a -> Bool +okHsBootSig (TypeSig _ _) = True +okHsBootSig (FixSig _) = True +okHsBootSig _ = False -okClsDclSig :: LSig Name -> Bool -okClsDclSig (L _ (SpecInstSig _)) = False -okClsDclSig _ = True -- All others OK +okClsDclSig :: Sig a -> Bool +okClsDclSig (SpecInstSig _) = False +okClsDclSig _ = True -- All others OK -okInstDclSig :: NameSet -> LSig Name -> Bool -okInstDclSig ns lsig@(L _ sig) = ok ns sig - where - ok _ (TypeSig _ _) = False - ok _ (FixSig _) = False - ok _ (SpecInstSig _) = True - ok ns _ = sigForThisGroup ns lsig +okInstDclSig :: Sig a -> Bool +okInstDclSig (TypeSig _ _) = False +okInstDclSig (FixSig _) = False +okInstDclSig _ = True sigForThisGroup :: NameSet -> LSig Name -> Bool sigForThisGroup ns sig @@ -507,10 +517,17 @@ isFixityLSig :: LSig name -> Bool isFixityLSig (L _ (FixSig {})) = True isFixityLSig _ = False -isVanillaLSig :: LSig name -> Bool +isVanillaLSig :: LSig name -> Bool -- User type signatures +-- A badly-named function, but it's part of the GHCi (used +-- by Haddock) so I don't want to change it gratuitously. isVanillaLSig (L _(TypeSig {})) = True isVanillaLSig _ = False +isTypeLSig :: LSig name -> Bool -- Type signatures +isTypeLSig (L _(TypeSig {})) = True +isTypeLSig (L _(IdSig {})) = True +isTypeLSig _ = False + isSpecLSig :: LSig name -> Bool isSpecLSig (L _(SpecSig {})) = True isSpecLSig _ = False @@ -531,18 +548,20 @@ isInlineLSig (L _ (InlineSig {})) = True isInlineLSig _ = False hsSigDoc :: Sig name -> SDoc -hsSigDoc (TypeSig {}) = ptext SLIT("type signature") -hsSigDoc (SpecSig {}) = ptext SLIT("SPECIALISE pragma") -hsSigDoc (InlineSig {}) = ptext SLIT("INLINE pragma") -hsSigDoc (SpecInstSig {}) = ptext SLIT("SPECIALISE instance pragma") -hsSigDoc (FixSig {}) = ptext SLIT("fixity declaration") +hsSigDoc (TypeSig {}) = ptext (sLit "type signature") +hsSigDoc (IdSig {}) = ptext (sLit "id signature") +hsSigDoc (SpecSig {}) = ptext (sLit "SPECIALISE pragma") +hsSigDoc (InlineSig {}) = ptext (sLit "INLINE pragma") +hsSigDoc (SpecInstSig {}) = ptext (sLit "SPECIALISE instance pragma") +hsSigDoc (FixSig {}) = ptext (sLit "fixity declaration") \end{code} Signature equality is used when checking for duplicate signatures \begin{code} -eqHsSig :: LSig Name -> LSig Name -> Bool +eqHsSig :: Eq a => LSig a -> LSig a -> Bool eqHsSig (L _ (FixSig (FixitySig n1 _))) (L _ (FixSig (FixitySig n2 _))) = unLoc n1 == unLoc n2 +eqHsSig (L _ (IdSig n1)) (L _ (IdSig n2)) = n1 == n2 eqHsSig (L _ (TypeSig n1 _)) (L _ (TypeSig n2 _)) = unLoc n1 == unLoc n2 eqHsSig (L _ (InlineSig n1 _)) (L _ (InlineSig n2 _)) = unLoc n1 == unLoc n2 -- For specialisations, we don't have equality over @@ -557,22 +576,23 @@ instance (OutputableBndr name) => Outputable (Sig name) where ppr_sig :: OutputableBndr name => Sig name -> SDoc ppr_sig (TypeSig var ty) = pprVarSig (unLoc var) ty +ppr_sig (IdSig id) = pprVarSig id (varType id) ppr_sig (FixSig fix_sig) = ppr fix_sig ppr_sig (SpecSig var ty inl) = pragBrackets (pprSpec var ty inl) ppr_sig (InlineSig var inl) = pragBrackets (ppr inl <+> ppr var) -ppr_sig (SpecInstSig ty) = pragBrackets (ptext SLIT("SPECIALIZE instance") <+> ppr ty) +ppr_sig (SpecInstSig ty) = pragBrackets (ptext (sLit "SPECIALIZE instance") <+> ppr ty) instance Outputable name => Outputable (FixitySig name) where ppr (FixitySig name fixity) = sep [ppr fixity, ppr name] pragBrackets :: SDoc -> SDoc -pragBrackets doc = ptext SLIT("{-#") <+> doc <+> ptext SLIT("#-}") +pragBrackets doc = ptext (sLit "{-#") <+> doc <+> ptext (sLit "#-}") pprVarSig :: (Outputable id, Outputable ty) => id -> ty -> SDoc pprVarSig var ty = sep [ppr var <+> dcolon, nest 2 (ppr ty)] pprSpec :: (Outputable id, Outputable ty) => id -> ty -> InlineSpec -> SDoc -pprSpec var ty inl = sep [ptext SLIT("SPECIALIZE") <+> ppr inl <+> pprVarSig var ty] +pprSpec var ty inl = sep [ptext (sLit "SPECIALIZE") <+> ppr inl <+> pprVarSig var ty] pprPrag :: Outputable id => id -> LPrag -> SDoc pprPrag var (L _ (InlinePrag inl)) = ppr inl <+> ppr var