[project @ 2002-10-09 15:03:48 by simonpj]
[ghc-hetmet.git] / ghc / compiler / hsSyn / HsDecls.lhs
index 90a211f..4bda850 100644 (file)
@@ -9,40 +9,47 @@ Definitions for: @TyDecl@ and @oCnDecl@, @ClassDecl@,
 \begin{code}
 module HsDecls (
        HsDecl(..), TyClDecl(..), InstDecl(..), RuleDecl(..), RuleBndr(..),
-       DefaultDecl(..), 
-       ForeignDecl(..), FoImport(..), FoExport(..), FoType(..),
-       ConDecl(..), ConDetails(..), 
+       DefaultDecl(..), HsGroup(..),
+       ForeignDecl(..), ForeignImport(..), ForeignExport(..),
+       CImportSpec(..), FoType(..),
+       ConDecl(..), CoreDecl(..),
        BangType(..), getBangType, getBangStrictness, unbangedType,
        DeprecDecl(..), DeprecTxt,
-       hsDeclName, instDeclName, 
-       tyClDeclName, tyClDeclNames, tyClDeclSysNames, tyClDeclTyVars,
-       isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, countTyClDecls,
-       mkClassDeclSysNames, isIfaceRuleDecl, ifaceRuleDeclName,
-       getClassDeclSysNames, conDetailsTys
+       tyClDeclName, tyClDeclNames, tyClDeclTyVars,
+       isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, 
+       isTypeOrClassDecl, countTyClDecls,
+       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 ForeignCall     ( CExportSpec, CCallSpec, DNCallSpec, CCallConv )
+import BasicTypes      ( NewOrData(..), StrictnessMark(..), Activation(..), FixitySig(..) )
+import ForeignCall     ( CCallTarget(..), DNCallSpec, CCallConv, Safety,
+                         CExportSpec(..)) 
 
 -- others:
 import Name            ( NamedThing )
 import FunDeps         ( pprFundeps )
+import TyCon           ( DataConDetails(..), visibleDataCons )
 import Class           ( FunDep, DefMeth(..) )
 import CStrings                ( CLabelString )
 import Outputable      
-import Util            ( eqListBy )
+import Util            ( eqListBy, count )
 import SrcLoc          ( SrcLoc )
 import FastString
 
@@ -57,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
@@ -79,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)                = forDeclName 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}
 
 
@@ -148,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
 ~~~~~~~~~~~~~~~
@@ -234,7 +267,7 @@ Source code:
        instance Foo [Bool] where ...
     These might both be dFooList
 
-  - The CoreTidy phase globalises the name, and ensures the occurrence name is
+  - The CoreTidy phase externalises the name, and ensures the occurrence name is
     unique (this isn't special to dict funs).  So we'd get dFooList and dFooList1.
 
   - We can take this relaxed approach (changing the occurrence name later) 
@@ -258,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],
@@ -271,17 +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   :: [ConDecl name],     -- data constructors (empty if abstract)
-               tcdNCons  :: Int,                -- Number of data constructors (valid even if type is abstract)
-               tcdDerivs :: Maybe [name],       -- derivings; Nothing => not specified
-                                -- (i.e., derive default); Just [] => derive
-                                -- *nothing*; Just <list> => as you would
-                                -- expect...
-               tcdSysNames :: DataSysNames name,       -- Generic converter functions
-               tcdLoc      :: SrcLoc
+               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
     }
 
   | TySynonym {        tcdName :: name,                        -- type constructor
@@ -295,10 +330,9 @@ 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
     }
 \end{code}
@@ -306,7 +340,7 @@ data TyClDecl name pat
 Simple classifiers
 
 \begin{code}
-isIfaceSigDecl, isDataDecl, isSynDecl, isClassDecl :: TyClDecl name pat -> Bool
+isIfaceSigDecl, isDataDecl, isSynDecl, isClassDecl :: TyClDecl name -> Bool
 
 isIfaceSigDecl (IfaceSig {}) = True
 isIfaceSigDecl other        = False
@@ -319,17 +353,23 @@ 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 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
@@ -351,44 +391,10 @@ tyClDeclTyVars (TyData    {tcdTyVars = tvs}) = tvs
 tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs
 tyClDeclTyVars (ForeignType {})                     = []
 tyClDeclTyVars (IfaceSig {})                = []
-
-
---------------------------------
--- 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 = 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 && 
@@ -404,7 +410,7 @@ instance (NamedThing name, Ord name) => Eq (TyClDecl name pat) where
        tcdND d1   == tcdND   d2 && 
        eqWithHsTyVars (tcdTyVars d1) (tcdTyVars d2) (\ env -> 
          eq_hsContext env (tcdCtxt d1) (tcdCtxt d2)  &&
-         eqListBy (eq_ConDecl env) (tcdCons d1) (tcdCons d2)
+         eq_hsCD      env (tcdCons d1) (tcdCons d2)
        )
 
   (==) d1@(TySynonym {}) d2@(TySynonym {})
@@ -423,6 +429,11 @@ instance (NamedThing name, Ord name) => Eq (TyClDecl name pat) where
 
   (==) _ _ = 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
 
@@ -437,30 +448,32 @@ 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 
- = (length [() | ClassDecl {} <- decls],
-    length [() | TySynonym {} <- decls],
-    length [() | IfaceSig  {} <- decls],
-    length [() | TyData {tcdND = DataType} <- decls],
-    length [() | TyData {tcdND = NewType} <- decls])
+ = (count isClassDecl     decls,
+    count isSynDecl       decls,
+    count isIfaceSigDecl  decls,
+    count isDataTy        decls,
+    count isNewTy         decls) 
+ where
+   isDataTy TyData{tcdND=DataType} = True
+   isDataTy _                      = False
+   
+   isNewTy TyData{tcdND=NewType} = True
+   isNewTy _                     = False
 \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 [ if ifaceStyle sty then ppr var else 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]
@@ -470,10 +483,10 @@ instance (NamedThing name, Outputable name, Outputable pat)
             4 (ppr mono_ty)
 
     ppr (TyData {tcdND = new_or_data, tcdCtxt = context, tcdName = tycon,
-                tcdTyVars = tyvars, tcdCons = condecls, tcdNCons = ncons,
+                tcdTyVars = tyvars, tcdCons = condecls, 
                 tcdDerivs = derivings})
       = pp_tydecl (ptext keyword <+> pp_decl_head context tycon tyvars)
-                 (pp_condecls condecls ncons)
+                 (pp_condecls condecls)
                  derivings
       where
        keyword = case new_or_data of
@@ -492,23 +505,23 @@ instance (NamedThing name, Outputable name, Outputable pat)
         top_matter  = ptext SLIT("class") <+> pp_decl_head context clas tyvars <+> pprFundeps fds
        ppr_sig sig = ppr sig <> semi
 
-       pp_methods = getPprStyle $ \ sty ->
-                    if ifaceStyle sty || isNothing methods
+       pp_methods = if isNothing methods
                        then empty
                        else ppr (fromJust methods)
-        
-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 []     ncons = ptext SLIT("{- abstract with") <+> int ncons <+> ptext SLIT("constructors -}")
-pp_condecls (c:cs) ncons = equals <+> sep (ppr c : map (\ c -> ptext SLIT("|") <+> ppr c) cs)
+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_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"), parens (interpp'SP ds)]
+         Just ds          -> hsep [ptext SLIT("deriving"), ppr_hs_context ds]
     ])
 \end{code}
 
@@ -524,64 +537,42 @@ 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}
-conDeclsNames :: Eq name => [ConDecl name] -> [(name,SrcLoc)]
+conDeclsNames :: Eq name => DataConDetails (ConDecl name) -> [(name,SrcLoc)]
   -- 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 ([], []) 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)
-
-         do_fld acc (flds, _) = foldl do_fld1 acc flds
+         new_flds = [ f | (f,_) <- flds, not (f `elem` flds_seen) ]
 
-         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
@@ -604,30 +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)
-  = getPprStyle $ \ sty ->
-    hsep ((if ifaceStyle sty then ppr con else 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
@@ -641,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
 
@@ -654,20 +641,18 @@ data InstDecl name pat
                                        -- Nothing for source-file instance decls
 
                SrcLoc
+
+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)
-      = getPprStyle $ \ sty ->
-        if ifaceStyle sty then
-           hsep [ptext SLIT("instance"), ppr inst_ty, equals, pp_dfun]
-       else
-          vcat [hsep [ptext SLIT("instance"), ppr inst_ty, ptext SLIT("where")],
-                nest 4 (ppr uprags),
-                nest 4 (ppr binds) ]
+      = 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
@@ -675,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
@@ -697,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)
@@ -711,43 +696,110 @@ instance (Outputable name)
 %************************************************************************
 
 \begin{code}
+
+-- foreign declarations are distinguished as to whether they define or use a
+-- Haskell name
+--
+-- * the Boolean value indicates whether the pre-standard deprecated syntax
+--   has been used
+--
 data ForeignDecl name
-  = ForeignImport name (HsType name) FoImport    SrcLoc
-  | ForeignExport name (HsType name) FoExport    SrcLoc
+  = ForeignImport name (HsType name) ForeignImport Bool SrcLoc  -- defines name
+  | ForeignExport name (HsType name) ForeignExport Bool SrcLoc  -- uses name
 
-forDeclName (ForeignImport n _ _ _) = n
-forDeclName (ForeignExport n _ _ _) = n
+-- yield the Haskell name defined or used in a foreign declaration
+--
+foreignDeclName                           :: ForeignDecl name -> name
+foreignDeclName (ForeignImport n _ _ _ _)  = n
+foreignDeclName (ForeignExport n _ _ _ _)  = n
 
-data FoImport 
-  = LblImport  CLabelString    -- foreign label
-  | CImport    CCallSpec       -- foreign import 
-  | CDynImport CCallConv       -- foreign export dynamic
-  | DNImport   DNCallSpec      -- foreign import dotnet
+-- 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
+                     --   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
+                    --   generation in the case of `CLabel', but is needed
+                    --   for pretty printing 
+                    --
+                    -- * `Safety' is irrelevant for `CLabel' and `CWrapper'
+                    --
+                    CImport  CCallConv       -- ccall or stdcall
+                             Safety          -- safe or unsafe
+                             FastString      -- name of C header
+                             FastString      -- name of library object
+                             CImportSpec     -- details of the C entity
+
+                     -- import of a .NET function
+                    --
+                  | DNImport DNCallSpec
+
+-- details of an external C entity
+--
+data CImportSpec = CLabel    CLabelString     -- import address of a C label
+                | CFunction CCallTarget      -- static or dynamic function
+                | CWrapper                   -- wrapper to expose closures
+                                             -- (former f.e.d.)
 
-data FoExport = CExport CExportSpec
+-- specification of an externally exported entity in dependence on the calling
+-- convention
+--
+data ForeignExport = CExport  CExportSpec    -- contains the calling convention
+                  | DNExport                -- presently unused
 
+-- abstract type imported from .NET
+--
 data FoType = DNType           -- In due course we'll add subtype stuff
-           deriving( Eq )      -- Used for equality instance for TyClDecl
+           deriving (Eq)       -- Used for equality instance for TyClDecl
 
-instance Outputable name => Outputable (ForeignDecl name) where
-  ppr (ForeignImport nm ty (LblImport lbl) src_loc)
-    = ptext SLIT("foreign label") <+> ppr lbl <+> ppr nm <+> dcolon <+> ppr ty
-  ppr (ForeignImport nm ty decl src_loc)
-    = ptext SLIT("foreign import") <+> ppr decl <+> ppr nm <+> dcolon <+> ppr ty
-  ppr (ForeignExport nm ty decl src_loc)
-    = ptext SLIT("foreign export") <+> ppr decl <+> ppr nm <+> dcolon <+> ppr ty
 
-instance Outputable FoImport where
-   ppr (CImport  d)      = ppr d
-   ppr (CDynImport conv) = text "dynamic" <+> ppr conv
-   ppr (DNImport d)     = ptext SLIT("dotnet") <+> ppr d
-   ppr (LblImport l)    = ptext SLIT("label") <+> ppr l
+-- pretty printing of foreign declarations
+--
 
-instance Outputable FoExport where
-   ppr (CExport d) = ppr d
+instance OutputableBndr name => Outputable (ForeignDecl name) where
+  ppr (ForeignImport n ty fimport _ _) =
+    ptext SLIT("foreign import") <+> ppr fimport <+> 
+    ppr n <+> dcolon <+> ppr ty
+  ppr (ForeignExport n ty fexport _ _) =
+    ptext SLIT("foreign export") <+> ppr fexport <+> 
+    ppr n <+> dcolon <+> ppr ty
+
+instance Outputable ForeignImport where
+  ppr (DNImport                                spec) = 
+    ptext SLIT("dotnet") <+> ppr spec
+  ppr (CImport  cconv safety header lib spec) =
+    ppr cconv <+> ppr safety <+> 
+    char '"' <> pprCEntity header lib spec <> char '"'
+    where
+      pprCEntity header lib (CLabel lbl) = 
+        ptext SLIT("static") <+> ftext header <+> char '&' <>
+       pprLib lib <> ppr lbl
+      pprCEntity header lib (CFunction (StaticTarget lbl)) = 
+        ptext SLIT("static") <+> ftext header <+> char '&' <>
+       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 ']'
+
+instance Outputable ForeignExport where
+  ppr (CExport  (CExportStatic lbl cconv)) = 
+    ppr cconv <+> char '"' <> ppr lbl <> char '"'
+  ppr (DNExport                          ) = 
+    ptext SLIT("dotnet") <+> ptext SLIT("\"<unused>\"")
 
 instance Outputable FoType where
-   ppr DNType = ptext SLIT("type dotnet")
+  ppr DNType = ptext SLIT("type dotnet")
 \end{code}
 
 
@@ -758,15 +810,13 @@ instance Outputable FoType where
 %************************************************************************
 
 \begin{code}
-data RuleDecl name pat
+data RuleDecl name
   = HsRule                     -- Source rule
        RuleName                -- Rule name
        Activation
-       [name]                  -- Forall'd tyvars, filled in by the renamer with
-                               -- tyvars mentioned in sigs; then filled out by typechecker
-       [RuleBndr name]         -- Forall'd term vars
-       (HsExpr name pat)       -- LHS
-       (HsExpr name pat)       -- RHS
+       [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
@@ -782,40 +832,39 @@ data RuleDecl name pat
        name                    -- Head of LHS
        CoreRule
 
-isIfaceRuleDecl :: RuleDecl name pat -> Bool
-isIfaceRuleDecl (HsRule _ _ _ _ _ _ _) = False
-isIfaceRuleDecl other                 = True
+isSrcRule (HsRule _ _ _ _ _ _) = True
+isSrcRule other                       = False
 
-ifaceRuleDeclName :: RuleDecl name pat -> name
+ifaceRuleDeclName :: RuleDecl name -> name
 ifaceRuleDeclName (IfaceRule _ _ _ n _ _ _) = n
 ifaceRuleDeclName (IfaceRuleOut n r)       = n
-ifaceRuleDeclName (HsRule fs _ _ _ _ _ _)   = pprPanic "ifaceRuleDeclName" (ppr fs)
+ifaceRuleDeclName (HsRule fs _ _ _ _ _)     = pprPanic "ifaceRuleDeclName" (ppr fs)
 
 data RuleBndr name
   = RuleBndr name
   | RuleBndrSig name (HsType name)
 
-instance (NamedThing name, Ord name) => Eq (RuleDecl name pat) where
+collectRuleBndrSigTys :: [RuleBndr name] -> [HsType 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 (NamedThing name, Outputable name, Outputable pat)
-             => Outputable (RuleDecl name pat) where
-  ppr (HsRule name act tvs ns lhs rhs loc)
-       = sep [text "{-# RULES" <+> doubleQuotes (ptext name) <+> ppr act,
-              pp_forall, ppr lhs, equals <+> ppr rhs,
+instance OutputableBndr name => Outputable (RuleDecl name) where
+  ppr (HsRule name act ns lhs rhs loc)
+       = sep [text "{-# RULES" <+> doubleQuotes (ftext name) <+> ppr act,
+              pp_forall, pprExpr lhs, equals <+> pprExpr rhs,
                text "#-}" ]
        where
-         pp_forall | null tvs && null ns = empty
-                   | otherwise           = text "forall" <+> 
-                                           fsep (map ppr tvs ++ map ppr ns)
-                                           <> dot
+         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
@@ -823,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}
@@ -840,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}