[project @ 2000-09-14 13:46:39 by simonpj]
[ghc-hetmet.git] / ghc / compiler / hsSyn / HsDecls.lhs
index 5267681..81fac47 100644 (file)
@@ -11,10 +11,11 @@ module HsDecls (
        HsDecl(..), TyClDecl(..), InstDecl(..), RuleDecl(..), RuleBndr(..),
        DefaultDecl(..), ForeignDecl(..), ForKind(..),
        ExtName(..), isDynamicExtName, extNameStatic,
-       ConDecl(..), ConDetails(..), BangType(..),
+       ConDecl(..), ConDetails(..), 
+       BangType(..), getBangType,
        IfaceSig(..),  SpecDataSig(..), 
        DeprecDecl(..), DeprecTxt,
-       hsDeclName, tyClDeclName, isClassDecl, isSynDecl, isDataDecl, countTyClDecls, toHsRule
+       hsDeclName, instDeclName, tyClDeclName, isClassDecl, isSynDecl, isDataDecl, countTyClDecls, toHsRule
     ) where
 
 #include "HsVersions.h"
@@ -30,17 +31,14 @@ import HsCore               ( UfExpr(UfVar), UfBinder, IfaceSig(..), eq_ufBinders, eq_ufExpr,
 import CoreSyn         ( CoreRule(..) )
 import BasicTypes      ( Fixity, NewOrData(..) )
 import CallConv                ( CallConv, pprCallConv )
-import Var             ( TyVar, Id )
 import Name            ( toRdrName )
 
 -- others:
-import PprType
 import FunDeps         ( pprFundeps )
 import Class           ( FunDep )
 import CStrings                ( CLabelString, pprCLabelString )
 import Outputable      
 import SrcLoc          ( SrcLoc, noSrcLoc )
-import Util
 \end{code}
 
 
@@ -81,20 +79,24 @@ data HsDecl name pat
 hsDeclName :: (Outputable name, Outputable pat)
           => HsDecl name pat -> name
 #endif
-hsDeclName (TyClD decl)                                  = tyClDeclName decl
-hsDeclName (SigD    (IfaceSig name _ _ _))       = name
-hsDeclName (InstD   (InstDecl _ _ _ name _))      = name
-hsDeclName (ForD    (ForeignDecl name _ _ _ _ _)) = name
-hsDeclName (FixD    (FixitySig name _ _))        = name
+hsDeclName (TyClD decl)                                    = tyClDeclName decl
+hsDeclName (InstD   decl)                          = instDeclName decl
+hsDeclName (SigD    (IfaceSig name _ _ _))         = name
+hsDeclName (ForD    (ForeignDecl name _ _ _ _ _))   = name
+hsDeclName (FixD    (FixitySig name _ _))          = name
 -- Others don't make sense
 #ifdef DEBUG
 hsDeclName x                                 = pprPanic "HsDecls.hsDeclName" (ppr x)
 #endif
 
+
 tyClDeclName :: TyClDecl name pat -> name
 tyClDeclName (TyData _ _ name _ _ _ _ _ _)          = name
 tyClDeclName (TySynonym name _ _ _)                 = name
 tyClDeclName (ClassDecl _ name _ _ _ _ _ _ _ _ _ _) = name
+
+instDeclName :: InstDecl name pat -> name
+instDeclName (InstDecl _ _ _ (Just name) _) = name
 \end{code}
 
 \begin{code}
@@ -128,6 +130,48 @@ instance Ord name => Eq (HsDecl name pat) where
 %*                                                                     *
 %************************************************************************
 
+Type and class declarations carry 'implicit names'.  In particular:
+
+Type A.  
+~~~~~~~
+  Each data type decl defines 
+       a worker name for each constructor
+       to-T and from-T convertors
+  Each class decl defines
+       a tycon for the class
+       a data constructor for that tycon
+       the worker for that constructor
+       a selector for each superclass
+
+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
+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
+
+ - Ensure they "point to" the parent data/class decl 
+   when loading that decl from an interface file
+
+ - When renaming the decl look them up in the name cache,
+   ensure correct module and provenance is set
+
+Type B: Default methods and dictionary functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Have their own binding in an interface file.
+
+Default methods : occurrence name is derived uniquely from the class decl.
+Dict functions  : occurrence name is derived from the instance decl, plus a unique number.
+
+Plan of attack: 
+  - Do *not* make them point to the parent class decl
+  - Interface-file decls: treat just like Type A
+  - Source-file decls:    the names aren't in the decl at all; 
+                         instead the typechecker makes them up
+
 \begin{code}
 data TyClDecl name pat
   = TyData     NewOrData
@@ -167,7 +211,7 @@ instance Ord name => Eq (TyClDecl name pat) where
     = n1 == n2 &&
       nd1 == nd2 &&
       eqWithHsTyVars tvs1 tvs2 (\ env -> 
-         eq_hsContext env cxt1 cxt2 &&
+         eq_hsContext env cxt1 cxt2  &&
          eqListBy (eq_ConDecl env) cons1 cons2
       )
 
@@ -185,11 +229,22 @@ instance Ord name => Eq (TyClDecl name pat) where
          eqListBy (eq_cls_sig env) sigs1 sigs2
        )
 
+  (==) _ _ = False     -- default case
+
+
 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 _ b1 ty1 _) (ClassOpSig n2 _ b2 ty2 _)
-  = n1==n2 && b1==b2 && eq_hsType env ty1 ty2
+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.
+       -- This is used for comparing declarations before putting
+       -- them into interface files, and the name of the default 
+       -- method isn't relevant
+    (Just (_,explicit_dm1)) `eq_dm` (Just (_,explicit_dm2)) = explicit_dm1 == explicit_dm2
+    Nothing                `eq_dm` Nothing                 = True
+    dm1                            `eq_dm` dm2                     = False
 \end{code}
 
 \begin{code}
@@ -309,16 +364,6 @@ data ConDetails name
   | RecCon                     -- record-style con decl
                [([name], BangType name)]       -- list of "fields"
 
-  | NewCon                     -- newtype con decl, possibly with a labelled field.
-               (HsType name)
-               (Maybe name)    -- Just x => labelled field 'x'
-
-data BangType name
-  = Banged   (HsType name)     -- HsType: to allow Haskell extensions
-  | Unbanged (HsType name)     -- (MonoType only needed for straight Haskell)
-  | Unpacked (HsType name)     -- Field is strict and to be unpacked if poss.
-
-
 eq_ConDecl env (ConDecl n1 _ tvs1 cxt1 cds1 _)
               (ConDecl n2 _ tvs2 cxt2 cds2 _)
   = n1 == n2 &&
@@ -332,16 +377,24 @@ 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 (NewCon t1 mn1) (NewCon t2 mn2)
-  = eq_hsType env t1 t2 && mn1 == mn2
 eq_ConDetails env _ _ = False
 
 eq_fld env (ns1,bt1) (ns2, bt2) = ns1==ns2 && eq_btype env bt1 bt2
 
+  
+data BangType name
+  = Banged   (HsType name)     -- HsType: to allow Haskell extensions
+  | Unbanged (HsType name)     -- (MonoType only needed for straight Haskell)
+  | Unpacked (HsType name)     -- Field is strict and to be unpacked if poss.
+
+getBangType (Banged ty)   = ty
+getBangType (Unbanged ty) = ty
+getBangType (Unpacked ty) = ty
+
 eq_btype env (Banged t1)   (Banged t2)   = eq_hsType env t1 t2
 eq_btype env (Unbanged t1) (Unbanged t2) = eq_hsType env t1 t2
 eq_btype env (Unpacked t1) (Unpacked t2) = eq_hsType env t1 t2
-eq_btype env _             _             = False
+eq_btype env _            _             = False
 \end{code}
 
 \begin{code}
@@ -355,14 +408,6 @@ ppr_con_details con (InfixCon ty1 ty2)
 ppr_con_details con (VanillaCon tys)
   = ppr con <+> hsep (map (ppr_bang) tys)
 
-ppr_con_details con (NewCon ty Nothing)
-  = ppr con <+> pprParendHsType ty
-
-ppr_con_details con (NewCon ty (Just x))
-  = ppr con <+> braces pp_field 
-   where
-    pp_field = ppr x <+> dcolon <+> pprParendHsType ty
 ppr_con_details con (RecCon fields)
   = ppr con <+> braces (hsep (punctuate comma (map ppr_field fields)))
   where
@@ -395,7 +440,8 @@ data InstDecl name pat
 
                [Sig name]              -- User-supplied pragmatic info
 
-               name                    -- Name for the dictionary function
+               (Maybe name)            -- Name for the dictionary function
+                                       -- Nothing for source-file instance decls
 
                SrcLoc
 \end{code}
@@ -404,14 +450,18 @@ data InstDecl name pat
 instance (Outputable name, Outputable pat)
              => Outputable (InstDecl name pat) where
 
-    ppr (InstDecl inst_ty binds uprags dfun_name src_loc)
+    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, ppr dfun_name]
+           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) ]
+      where
+       pp_dfun = case maybe_dfun_name of
+                   Just df -> ppr df
+                   Nothing -> empty
 \end{code}
 
 \begin{code}