[project @ 2002-10-09 15:03:48 by simonpj]
[ghc-hetmet.git] / ghc / compiler / hsSyn / HsDecls.lhs
index 848ef57..4bda850 100644 (file)
@@ -9,34 +9,36 @@ Definitions for: @TyDecl@ and @oCnDecl@, @ClassDecl@,
 \begin{code}
 module HsDecls (
        HsDecl(..), TyClDecl(..), InstDecl(..), RuleDecl(..), RuleBndr(..),
-       DefaultDecl(..), 
+       DefaultDecl(..), HsGroup(..),
        ForeignDecl(..), ForeignImport(..), ForeignExport(..),
        CImportSpec(..), FoType(..),
-       ConDecl(..), ConDetails(..), 
+       ConDecl(..), CoreDecl(..),
        BangType(..), getBangType, getBangStrictness, unbangedType,
        DeprecDecl(..), DeprecTxt,
-       hsDeclName, instDeclName, 
-       tyClDeclName, tyClDeclNames, tyClDeclSysNames, tyClDeclTyVars,
-       isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, isCoreDecl,
+       tyClDeclName, tyClDeclNames, tyClDeclTyVars,
+       isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, 
        isTypeOrClassDecl, countTyClDecls,
-       mkClassDeclSysNames, isSourceInstDecl, ifaceRuleDeclName,
-       getClassDeclSysNames, conDetailsTys,
-       collectRuleBndrSigTys
+       isSourceInstDecl, ifaceRuleDeclName,
+       conDetailsTys,
+       collectRuleBndrSigTys, isSrcRule
     ) where
 
 #include "HsVersions.h"
 
 -- friends:
-import HsBinds         ( HsBinds, MonoBinds, Sig(..), FixitySig(..) )
-import HsExpr          ( HsExpr )
-import HsImpExp                ( ppr_var )
+import {-# SOURCE #-}  HsExpr( HsExpr, pprExpr )
+       -- Because Expr imports Decls via HsBracket
+
+import HsBinds         ( HsBinds, MonoBinds, Sig(..) )
+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(..) )
+import BasicTypes      ( NewOrData(..), StrictnessMark(..), Activation(..), FixitySig(..) )
 import ForeignCall     ( CCallTarget(..), DNCallSpec, CCallConv, Safety,
                          CExportSpec(..)) 
 
@@ -62,18 +64,20 @@ import Maybe                ( isNothing, fromJust )
 %************************************************************************
 
 \begin{code}
-data HsDecl name pat
-  = TyClD      (TyClDecl name pat)
-  | InstD      (InstDecl  name pat)
-  | DefD       (DefaultDecl name)
-  | ValD       (HsBinds name pat)
-  | ForD        (ForeignDecl name)
-  | FixD       (FixitySig name)
-  | DeprecD    (DeprecDecl name)
-  | RuleD      (RuleDecl name pat)
+data HsDecl id
+  = TyClD      (TyClDecl id)
+  | InstD      (InstDecl  id)
+  | ValD       (MonoBinds id)
+  | SigD       (Sig id)
+  | DefD       (DefaultDecl id)
+  | ForD        (ForeignDecl id)
+  | DeprecD    (DeprecDecl id)
+  | RuleD      (RuleDecl id)
+  | CoreD      (CoreDecl id)
+  | SpliceD    (HsExpr id)     -- Top level splice
 
 -- NB: all top-level fixity decls are contained EITHER
--- EITHER FixDs
+-- EITHER SigDs
 -- OR     in the ClassDecls in TyClDs
 --
 -- The former covers
@@ -84,40 +88,63 @@ data HsDecl name pat
 --     d) top level decls
 --
 -- The latter is for class methods only
-\end{code}
-
-\begin{code}
-#ifdef DEBUG
-hsDeclName :: (NamedThing name, Outputable name, Outputable pat)
-          => HsDecl name pat -> name
-#endif
-hsDeclName (TyClD decl)                        = tyClDeclName     decl
-hsDeclName (InstD decl)                        = instDeclName     decl
-hsDeclName (ForD  decl)                        = foreignDeclName decl
-hsDeclName (FixD  (FixitySig name _ _)) = name
--- Others don't make sense
-#ifdef DEBUG
-hsDeclName x                           = pprPanic "HsDecls.hsDeclName" (ppr x)
-#endif
-
-
-instDeclName :: InstDecl name pat -> name
-instDeclName (InstDecl _ _ _ (Just name) _) = name
 
+-- A [HsDecl] is categorised into a HsGroup before being 
+-- 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_fixds  :: [FixitySig 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]
+  }
 \end{code}
 
 \begin{code}
-instance (NamedThing name, Outputable name, Outputable pat)
-       => Outputable (HsDecl name pat) where
-
+instance OutputableBndr name => Outputable (HsDecl name) where
     ppr (TyClD dcl)  = ppr dcl
     ppr (ValD binds) = ppr binds
     ppr (DefD def)   = ppr def
     ppr (InstD inst) = ppr inst
     ppr (ForD fd)    = ppr fd
-    ppr (FixD fd)    = ppr fd
+    ppr (SigD sd)    = ppr sd
     ppr (RuleD rd)   = ppr rd
     ppr (DeprecD dd) = ppr dd
+    ppr (CoreD dd)   = ppr dd
+    ppr (SpliceD e)  = ptext SLIT("splice") <> parens (pprExpr e)
+
+instance OutputableBndr name => Outputable (HsGroup name) where
+    ppr (HsGroup { hs_valds  = val_decls,
+                  hs_tyclds = tycl_decls,
+                  hs_instds = inst_decls,
+                  hs_fixds  = fix_decls,
+                  hs_depds  = deprec_decls,
+                  hs_fords  = foreign_decls,
+                  hs_defds  = default_decls,
+                  hs_ruleds = rule_decls,
+                  hs_coreds = core_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]
+       where
+         ppr_ds [] = empty
+         ppr_ds ds = text "" $$ vcat (map ppr ds)
 \end{code}
 
 
@@ -153,15 +180,16 @@ interface files, of course.  Any such occurrence must haul in the
 relevant type or class decl.
 
 Plan of attack:
- - Make up their occurrence names immediately
-   This is done in RdrHsSyn.mkClassDecl, mkTyDecl, mkConDecl
-
  - Ensure they "point to" the parent data/class decl 
    when loading that decl from an interface file
-   (See RnHiFiles.getTyClDeclSysNames)
+   (See RnHiFiles.getSysBinders)
+
+ - When typechecking the decl, we build the implicit TyCons and Ids.
+   When doing so we look them up in the name cache (RnEnv.lookupSysName),
+   to ensure correct module and provenance is set
 
- - When renaming the decl look them up in the name cache,
-   ensure correct module and provenance is set
+These are the two places that we have to conjure up the magic derived
+names.  (The actual magic is in OccName.mkWorkerOcc, etc.)
 
 Default methods
 ~~~~~~~~~~~~~~~
@@ -263,7 +291,7 @@ Interface file code:
 -- for a module.  That's why (despite the misnomer) IfaceSig and ForeignType
 -- are both in TyClDecl
 
-data TyClDecl name pat
+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],
@@ -276,14 +304,19 @@ data TyClDecl name pat
                  tcdLoc     :: SrcLoc }
 
   | TyData {   tcdND     :: NewOrData,
-               tcdCtxt   :: HsContext name,     -- context
-               tcdName   :: name,               -- type constructor
-               tcdTyVars :: [HsTyVarBndr name], -- type variables
-               tcdCons   :: DataConDetails (ConDecl name),      -- data constructors (empty if abstract)
-               tcdDerivs :: Maybe (HsContext name),    -- derivings; Nothing => not specified
+               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
-               tcdSysNames :: DataSysNames name,       -- Generic converter functions
-               tcdLoc      :: SrcLoc
+               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
     }
 
   | TySynonym {        tcdName :: name,                        -- type constructor
@@ -297,25 +330,17 @@ data TyClDecl name pat
                tcdTyVars  :: [HsTyVarBndr name],       -- The class type variables
                tcdFDs     :: [FunDep name],            -- Functional dependencies
                tcdSigs    :: [Sig name],               -- Methods' signatures
-               tcdMeths   :: Maybe (MonoBinds name pat),       -- Default methods
-                                                               -- Nothing for imported class decls
-                                                               -- Just bs for source   class decls
-               tcdSysNames :: ClassSysNames name,
+               tcdMeths   :: Maybe (MonoBinds name),   -- Default methods
+                                                       --      Nothing for imported class decls
+                                                       --      Just bs for source   class decls
                tcdLoc      :: SrcLoc
     }
-    -- a Core value binding (coming from 'external Core' input.)
-  | CoreDecl { tcdName      :: name,  
-               tcdType      :: HsType name,
-              tcdRhs       :: UfExpr name,
-              tcdLoc       :: SrcLoc
-    }
-
 \end{code}
 
 Simple classifiers
 
 \begin{code}
-isIfaceSigDecl, isCoreDecl, isDataDecl, isSynDecl, isClassDecl :: TyClDecl name pat -> Bool
+isIfaceSigDecl, isDataDecl, isSynDecl, isClassDecl :: TyClDecl name -> Bool
 
 isIfaceSigDecl (IfaceSig {}) = True
 isIfaceSigDecl other        = False
@@ -334,21 +359,17 @@ isTypeOrClassDecl (TyData      {}) = True
 isTypeOrClassDecl (TySynonym   {}) = True
 isTypeOrClassDecl (ForeignType {}) = True
 isTypeOrClassDecl other                   = False
-
-isCoreDecl (CoreDecl {}) = True
-isCoreDecl other        = False
-
 \end{code}
 
 Dealing with names
 
 \begin{code}
 --------------------------------
-tyClDeclName :: TyClDecl name pat -> name
+tyClDeclName :: TyClDecl name -> name
 tyClDeclName tycl_decl = tcdName tycl_decl
 
 --------------------------------
-tyClDeclNames :: Eq name => TyClDecl name pat -> [(name, SrcLoc)]
+tyClDeclNames :: Eq name => TyClDecl name -> [(name, SrcLoc)]
 -- 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
@@ -356,7 +377,6 @@ tyClDeclNames :: Eq name => TyClDecl name pat -> [(name, SrcLoc)]
 
 tyClDeclNames (TySynonym   {tcdName = name, tcdLoc = loc})  = [(name,loc)]
 tyClDeclNames (IfaceSig    {tcdName = name, tcdLoc = loc})  = [(name,loc)]
-tyClDeclNames (CoreDecl    {tcdName = name, tcdLoc = loc})  = [(name,loc)]
 tyClDeclNames (ForeignType {tcdName = name, tcdLoc = loc})  = [(name,loc)]
 
 tyClDeclNames (ClassDecl {tcdName = cls_name, tcdSigs = sigs, tcdLoc = loc})
@@ -371,56 +391,16 @@ tyClDeclTyVars (TyData    {tcdTyVars = tvs}) = tvs
 tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs
 tyClDeclTyVars (ForeignType {})                     = []
 tyClDeclTyVars (IfaceSig {})                = []
-tyClDeclTyVars (CoreDecl {})                = []
-
-
---------------------------------
--- The "system names" are extra implicit names *bound* by the decl.
--- They are kept in a list rather than a tuple 
--- to make the renamer easier.
-
-type ClassSysNames name = [name]
--- For class decls they are:
---     [tycon, datacon wrapper, datacon worker, 
---      superclass selector 1, ..., superclass selector n]
-
-type DataSysNames name =  [name]
--- For data decls they are
---     [from, to]
--- where from :: T -> Tring
---      to   :: Tring -> T
-
-tyClDeclSysNames :: TyClDecl name pat -> [(name, SrcLoc)]
--- Similar to tyClDeclNames, but returns the "implicit" 
--- or "system" names of the declaration
-
-tyClDeclSysNames (ClassDecl {tcdSysNames = names, tcdLoc = loc})
-  = [(n,loc) | n <- names]
-tyClDeclSysNames (TyData {tcdCons = DataCons cons, tcdSysNames = names, tcdLoc = loc})
-  = [(n,loc) | n <- names] ++ 
-    [(wkr_name,loc) | ConDecl _ wkr_name _ _ _ loc <- cons]
-tyClDeclSysNames decl = []
-
-
-mkClassDeclSysNames  :: (name, name, name, [name]) -> [name]
-getClassDeclSysNames :: [name] -> (name, name, name, [name])
-mkClassDeclSysNames  (a,b,c,ds) = a:b:c:ds
-getClassDeclSysNames (a:b:c:ds) = (a,b,c,ds)
 \end{code}
 
 \begin{code}
-instance (NamedThing name, Ord name) => Eq (TyClDecl name pat) where
+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@(CoreDecl {}) d2@(CoreDecl {})
-      = tcdName d1 == tcdName d2 && 
-       tcdType d1 == tcdType d2 && 
-       tcdRhs d1  == tcdRhs  d2
-
   (==) d1@(ForeignType {}) d2@(ForeignType {})
       = tcdName d1 == tcdName d2 && 
        tcdFoType d1 == tcdFoType d2
@@ -468,17 +448,15 @@ eq_cls_sig env (ClassOpSig n1 dm1 ty1 _) (ClassOpSig n2 dm2 ty2 _)
     GenDefMeth `eq_dm` GenDefMeth = True
     DefMeth _  `eq_dm` DefMeth _  = True
     dm1               `eq_dm` dm2        = False
-
-    
 \end{code}
 
 \begin{code}
-countTyClDecls :: [TyClDecl name pat] -> (Int, Int, Int, Int, Int)
+countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int, Int)
        -- class, data, newtype, synonym decls
 countTyClDecls decls 
  = (count isClassDecl     decls,
     count isSynDecl       decls,
-    count (\ x -> isIfaceSigDecl x || isCoreDecl x) decls,
+    count isIfaceSigDecl  decls,
     count isDataTy        decls,
     count isNewTy         decls) 
  where
@@ -490,12 +468,12 @@ countTyClDecls decls
 \end{code}
 
 \begin{code}
-instance (NamedThing name, Outputable name, Outputable pat)
-             => Outputable (TyClDecl name pat) where
+instance OutputableBndr name
+             => Outputable (TyClDecl name) where
 
     ppr (IfaceSig {tcdName = var, tcdType = ty, tcdIdInfo = info})
        = getPprStyle $ \ sty ->
-          hsep [ ppr_var var, dcolon, ppr ty, pprHsIdInfo info ]
+          hsep [ pprHsVar var, dcolon, ppr ty, pprHsIdInfo info ]
 
     ppr (ForeignType {tcdName = tycon})
        = hsep [ptext SLIT("foreign import type dotnet"), ppr tycon]
@@ -530,12 +508,8 @@ instance (NamedThing name, Outputable name, Outputable pat)
        pp_methods = if isNothing methods
                        then empty
                        else ppr (fromJust methods)
-        
-    ppr (CoreDecl {tcdName = var, tcdType = ty, tcdRhs = rhs})
-       = getPprStyle $ \ sty ->
-          hsep [ ppr_var var, dcolon, ppr ty, ppr rhs ]
 
-pp_decl_head :: Outputable name => HsContext name -> name -> [HsTyVarBndr name] -> SDoc
+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 -}")
@@ -563,26 +537,12 @@ data ConDecl name
   = ConDecl    name                    -- Constructor name; this is used for the
                                        -- DataCon itself, and for the user-callable wrapper Id
 
-               name                    -- Name of the constructor's 'worker Id'
-                                       -- Filled in as the ConDecl is built
-
                [HsTyVarBndr name]      -- Existentially quantified type variables
                (HsContext name)        -- ...and context
                                        -- If both are empty then there are no existentials
 
-               (ConDetails name)
+               (HsConDetails name (BangType name))
                SrcLoc
-
-data ConDetails name
-  = VanillaCon                 -- prefix-style con decl
-               [BangType name]
-
-  | InfixCon                   -- infix-style con decl
-               (BangType name)
-               (BangType name)
-
-  | RecCon                     -- record-style con decl
-               [([name], BangType name)]       -- list of "fields"
 \end{code}
 
 \begin{code}
@@ -593,34 +553,26 @@ conDeclsNames :: Eq name => DataConDetails (ConDecl name) -> [(name,SrcLoc)]
 conDeclsNames cons
   = snd (foldl do_one ([], []) (visibleDataCons cons))
   where
-    do_one (flds_seen, acc) (ConDecl name _ _ _ details loc)
-       = do_details ((name,loc):acc) details
+    do_one (flds_seen, acc) (ConDecl name _ _ (RecCon flds) loc)
+       = (new_flds ++ flds_seen, (name,loc) : [(f,loc) | f <- new_flds] ++ acc)
        where
-         do_details acc (RecCon flds) = foldl do_fld (flds_seen, acc) flds
-         do_details acc other         = (flds_seen, acc)
+         new_flds = [ f | (f,_) <- flds, not (f `elem` flds_seen) ]
 
-         do_fld acc (flds, _) = foldl do_fld1 acc flds
-
-         do_fld1 (flds_seen, acc) fld
-               | fld `elem` flds_seen = (flds_seen,acc)
-               | otherwise            = (fld:flds_seen, (fld,loc):acc)
+    do_one (flds_seen, acc) (ConDecl name _ _ _ loc)
+       = (flds_seen, (name,loc):acc)
 \end{code}
 
 \begin{code}
-conDetailsTys :: ConDetails name -> [HsType name]
-conDetailsTys (VanillaCon btys)    = map getBangType btys
-conDetailsTys (InfixCon bty1 bty2) = [getBangType bty1, getBangType bty2]
-conDetailsTys (RecCon fields)     = [getBangType bty | (_, bty) <- fields]
-
+conDetailsTys details = map getBangType (hsConArgs details)
 
-eq_ConDecl env (ConDecl n1 _ tvs1 cxt1 cds1 _)
-              (ConDecl n2 _ tvs2 cxt2 cds2 _)
+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 (VanillaCon bts1) (VanillaCon bts2)
+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
@@ -643,28 +595,26 @@ eq_btype env (BangType s1 t1) (BangType s2 t2) = s1==s2 && eq_hsType env t1 t2
 \end{code}
 
 \begin{code}
-instance (Outputable name) => Outputable (ConDecl name) where
-    ppr (ConDecl con _ tvs cxt con_details  loc)
+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_con_details con (InfixCon ty1 ty2)
   = hsep [ppr_bang ty1, ppr con, ppr_bang ty2]
 
--- ConDecls generated by MkIface.ifaceTyThing always have a VanillaCon, even
+-- 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 (VanillaCon tys)
-  = hsep (ppr_var con : map (ppr_bang) tys)
+ppr_con_details con (PrefixCon tys)
+  = hsep (pprHsVar con : map ppr_bang tys)
 
 ppr_con_details con (RecCon fields)
   = ppr con <+> braces (sep (punctuate comma (map ppr_field fields)))
   where
-    ppr_field (ns, ty) = hsep (map (ppr) ns) <+> 
-                        dcolon <+>
-                        ppr_bang ty
+    ppr_field (n, ty) = ppr n <+> dcolon <+> ppr_bang ty
 
-instance Outputable name => Outputable (BangType name) where
+instance OutputableBndr name => Outputable (BangType name) where
     ppr = ppr_bang
 
 ppr_bang (BangType s ty) = ppr s <> pprParendHsType ty
@@ -678,12 +628,12 @@ ppr_bang (BangType s ty) = ppr s <> pprParendHsType ty
 %************************************************************************
 
 \begin{code}
-data InstDecl name pat
+data InstDecl name
   = InstDecl   (HsType name)   -- Context => Class Instance-type
                                -- Using a polytype means that the renamer conveniently
                                -- figures out the quantified type variables for us.
 
-               (MonoBinds name pat)
+               (MonoBinds name)
 
                [Sig name]              -- User-supplied pragmatic info
 
@@ -692,13 +642,12 @@ data InstDecl name pat
 
                SrcLoc
 
-isSourceInstDecl :: InstDecl name pat -> Bool
+isSourceInstDecl :: InstDecl name -> Bool
 isSourceInstDecl (InstDecl _ _ _ maybe_dfun _) = isNothing maybe_dfun
 \end{code}
 
 \begin{code}
-instance (Outputable name, Outputable pat)
-             => Outputable (InstDecl name pat) where
+instance (OutputableBndr name) => Outputable (InstDecl name) where
 
     ppr (InstDecl inst_ty binds uprags maybe_dfun_name src_loc)
       = vcat [hsep [ptext SLIT("instance"), ppr inst_ty, ptext SLIT("where")],
@@ -711,7 +660,7 @@ instance (Outputable name, Outputable pat)
 \end{code}
 
 \begin{code}
-instance Ord name => Eq (InstDecl name pat) where
+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
@@ -733,7 +682,7 @@ data DefaultDecl name
   = DefaultDecl        [HsType name]
                SrcLoc
 
-instance (Outputable name)
+instance (OutputableBndr name)
              => Outputable (DefaultDecl name) where
 
     ppr (DefaultDecl tys src_loc)
@@ -813,7 +762,7 @@ data FoType = DNType                -- In due course we'll add subtype stuff
 -- pretty printing of foreign declarations
 --
 
-instance Outputable name => Outputable (ForeignDecl name) where
+instance OutputableBndr name => Outputable (ForeignDecl name) where
   ppr (ForeignImport n ty fimport _ _) =
     ptext SLIT("foreign import") <+> ppr fimport <+> 
     ppr n <+> dcolon <+> ppr ty
@@ -829,10 +778,10 @@ instance Outputable ForeignImport where
     char '"' <> pprCEntity header lib spec <> char '"'
     where
       pprCEntity header lib (CLabel lbl) = 
-        ptext SLIT("static") <+> ptext header <+> char '&' <>
+        ptext SLIT("static") <+> ftext header <+> char '&' <>
        pprLib lib <> ppr lbl
       pprCEntity header lib (CFunction (StaticTarget lbl)) = 
-        ptext SLIT("static") <+> ptext header <+> char '&' <>
+        ptext SLIT("static") <+> ftext header <+> char '&' <>
        pprLib lib <> ppr lbl
       pprCEntity header lib (CFunction (DynamicTarget)) = 
         ptext SLIT("dynamic")
@@ -861,13 +810,13 @@ instance Outputable FoType where
 %************************************************************************
 
 \begin{code}
-data RuleDecl name pat
+data RuleDecl name
   = HsRule                     -- Source rule
        RuleName                -- Rule name
        Activation
        [RuleBndr name]         -- Forall'd vars; after typechecking this includes tyvars
-       (HsExpr name pat)       -- LHS
-       (HsExpr name pat)       -- RHS
+       (HsExpr name)   -- LHS
+       (HsExpr name)   -- RHS
        SrcLoc          
 
   | IfaceRule                  -- One that's come in from an interface file; pre-typecheck
@@ -883,7 +832,10 @@ data RuleDecl name pat
        name                    -- Head of LHS
        CoreRule
 
-ifaceRuleDeclName :: RuleDecl name pat -> name
+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)
@@ -895,25 +847,24 @@ data RuleBndr name
 collectRuleBndrSigTys :: [RuleBndr name] -> [HsType name]
 collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ ty <- bndrs]
 
-instance (NamedThing name, Ord name) => Eq (RuleDecl name pat) where
+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 (NamedThing name, Outputable name, Outputable pat)
-             => Outputable (RuleDecl name pat) where
+instance OutputableBndr name => Outputable (RuleDecl name) where
   ppr (HsRule name act ns lhs rhs loc)
-       = sep [text "{-# RULES" <+> doubleQuotes (ptext name) <+> ppr act,
-              pp_forall, ppr lhs, equals <+> ppr rhs,
+       = sep [text "{-# RULES" <+> doubleQuotes (ftext name) <+> ppr act,
+              pp_forall, pprExpr lhs, equals <+> pprExpr 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 (ptext name), ppr act,
+    = 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
@@ -921,7 +872,7 @@ instance (NamedThing name, Outputable name, Outputable pat)
 
   ppr (IfaceRuleOut fn rule) = pprCoreRule (ppr fn) rule
 
-instance Outputable name => Outputable (RuleBndr name) where
+instance OutputableBndr name => Outputable (RuleBndr name) where
    ppr (RuleBndr name) = ppr name
    ppr (RuleBndrSig name ty) = ppr name <> dcolon <> ppr ty
 \end{code}
@@ -938,9 +889,29 @@ We use exported entities for things to deprecate.
 \begin{code}
 data DeprecDecl name = Deprecation name DeprecTxt SrcLoc
 
-type DeprecTxt = FAST_STRING   -- reason/explanation for deprecation
+type DeprecTxt = FastString    -- reason/explanation for deprecation
 
-instance Outputable name => Outputable (DeprecDecl name) where
+instance OutputableBndr name => Outputable (DeprecDecl name) where
     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}