Initial checkin of HetMet / -XModalTypes modifications
[ghc-hetmet.git] / compiler / basicTypes / OccName.lhs
index 1868c3f..c528acb 100644 (file)
@@ -9,7 +9,7 @@
 -- GHC uses several kinds of name internally:
 --
 -- * 'OccName.OccName' represents names as strings with just a little more information:
---   the "namespace" that the name came from, e.g. the namespace of value, type constructors or
+--   the \"namespace\" that the name came from, e.g. the namespace of value, type constructors or
 --   data constructors
 --
 -- * 'RdrName.RdrName': see "RdrName#name_types"
@@ -25,8 +25,8 @@ module OccName (
        
        -- ** Construction
        -- $real_vs_source_data_constructors
-       tcName, clsName, tcClsName, dataName, varName, 
-       tvName, srcDataName,
+       tcName, clsName, tcClsName, dataName, varName, varNameDepth,
+       tvName, srcDataName, setOccNameDepth, getOccNameDepth,
 
        -- ** Pretty Printing
        pprNameSpace, pprNonVarNameSpace, pprNameSpaceBrief,
@@ -42,14 +42,14 @@ module OccName (
        mkTyVarOcc, mkTyVarOccFS,
        mkTcOcc, mkTcOccFS,
        mkClsOcc, mkClsOccFS,
-       mkDFunOcc,
+        mkDFunOcc,
        mkTupleOcc, 
        setOccNameSpace,
 
        -- ** Derived 'OccName's
         isDerivedOccName,
        mkDataConWrapperOcc, mkWorkerOcc, mkDefaultMethodOcc,
-       mkDerivedTyConOcc, mkNewTyCoOcc, 
+       mkDerivedTyConOcc, mkNewTyCoOcc, mkClassOpAuxOcc,
         mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc,
        mkClassTyConOcc, mkClassDataConOcc, mkDictOcc, mkIPOcc, 
        mkSpecOcc, mkForeignExportOcc, mkGenOcc1, mkGenOcc2,
@@ -57,15 +57,15 @@ module OccName (
        mkSuperDictSelOcc, mkLocalOcc, mkMethodOcc, mkInstTyTcOcc,
        mkInstTyCoOcc, mkEqPredCoOcc,
         mkVectOcc, mkVectTyConOcc, mkVectDataConOcc, mkVectIsoOcc,
-        mkPArrayTyConOcc, mkPArrayDataConOcc,
-        mkPReprTyConOcc,
+        mkPDataTyConOcc, mkPDataDataConOcc,
+        mkPReprTyConOcc, 
         mkPADFunOcc,
 
        -- ** Deconstruction
        occNameFS, occNameString, occNameSpace, 
 
        isVarOcc, isTvOcc, isTcOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc,
-       parenSymOcc, reportIfUnused, 
+       parenSymOcc, startsWithUnderscore, 
        
        isTcClsNameSpace, isTvNameSpace, isDataConNameSpace, isVarNameSpace, isValNameSpace,
 
@@ -75,7 +75,7 @@ module OccName (
        OccEnv, emptyOccEnv, unitOccEnv, extendOccEnv, mapOccEnv,
        lookupOccEnv, mkOccEnv, mkOccEnv_C, extendOccEnvList, elemOccEnv,
        occEnvElts, foldOccEnv, plusOccEnv, plusOccEnv_C, extendOccEnv_C,
-        filterOccEnv, delListFromOccEnv, delFromOccEnv,
+        extendOccEnv_Acc, filterOccEnv, delListFromOccEnv, delFromOccEnv,
 
        -- * The 'OccSet' type
        OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, 
@@ -92,29 +92,19 @@ module OccName (
        startsVarSym, startsVarId, startsConSym, startsConId
     ) where
 
+#include "Typeable.h"
+
 import Util
 import Unique
 import BasicTypes
-import StaticFlags
 import UniqFM
 import UniqSet
 import FastString
-import FastTypes
 import Outputable
 import Binary
-
-import GHC.Exts
+import StaticFlags( opt_SuppressUniques )
 import Data.Char
-\end{code}
-
-\begin{code}
--- Unicode TODO: put isSymbol in libcompat
-#if !defined(__GLASGOW_HASKELL__) || __GLASGOW_HASKELL__ > 604
-#else
-isSymbol :: a -> Bool
-isSymbol = const False
-#endif
-
+import Data.Data
 \end{code}
 
 %************************************************************************
@@ -124,7 +114,7 @@ isSymbol = const False
 %************************************************************************
 
 \begin{code}
-data NameSpace = VarName       -- Variables, including "real" data constructors
+data NameSpace = VarName   Int  -- Variables, including "real" data constructors; Int is the syntactic HetMet bracket depth
               | DataName       -- "Source" data constructors 
               | TvName         -- Type variables
               | TcClsName      -- Type constructors and classes; Haskell has them
@@ -154,6 +144,7 @@ data NameSpace = VarName    -- Variables, including "real" data constructors
 tcName, clsName, tcClsName :: NameSpace
 dataName, srcDataName      :: NameSpace
 tvName, varName            :: NameSpace
+varNameDepth               :: Int -> NameSpace
 
 -- Though type constructors and classes are in the same name space now,
 -- the NameSpace type is abstract, so we can easily separate them later
@@ -165,8 +156,23 @@ dataName    = DataName
 srcDataName = DataName -- Haskell-source data constructors should be
                        -- in the Data name space
 
-tvName      = TvName
-varName     = VarName
+tvName       = TvName
+
+varName      = VarName 0
+varNameDepth = VarName
+
+getOccNameDepth :: OccName -> Int
+getOccNameDepth name =
+    case occNameSpace name of
+      (VarName d) -> d
+      _           -> 0
+setOccNameDepth :: Int -> OccName -> OccName
+setOccNameDepth depth name =
+    case occNameSpace name of
+      (VarName _) -> name{ occNameSpace = VarName depth }
+      ns           -> if depth==0
+                     then name
+                     else error ("tried to change the depth of a name in namespace " ++ (showSDoc $ ppr name))
 
 isDataConNameSpace :: NameSpace -> Bool
 isDataConNameSpace DataName = True
@@ -182,27 +188,27 @@ isTvNameSpace _      = False
 
 isVarNameSpace :: NameSpace -> Bool    -- Variables or type variables, but not constructors
 isVarNameSpace TvName  = True
-isVarNameSpace VarName = True
+isVarNameSpace (VarName _) = True
 isVarNameSpace _       = False
 
 isValNameSpace :: NameSpace -> Bool
 isValNameSpace DataName = True
-isValNameSpace VarName  = True
+isValNameSpace (VarName _)  = True
 isValNameSpace _        = False
 
 pprNameSpace :: NameSpace -> SDoc
 pprNameSpace DataName  = ptext (sLit "data constructor")
-pprNameSpace VarName   = ptext (sLit "variable")
+pprNameSpace (VarName _)  = ptext (sLit "variable")
 pprNameSpace TvName    = ptext (sLit "type variable")
 pprNameSpace TcClsName = ptext (sLit "type constructor or class")
 
 pprNonVarNameSpace :: NameSpace -> SDoc
-pprNonVarNameSpace VarName = empty
+pprNonVarNameSpace (VarName _) = empty
 pprNonVarNameSpace ns = pprNameSpace ns
 
 pprNameSpaceBrief :: NameSpace -> SDoc
 pprNameSpaceBrief DataName  = char 'd'
-pprNameSpaceBrief VarName   = char 'v'
+pprNameSpaceBrief (VarName _)  = char 'v'
 pprNameSpaceBrief TvName    = ptext (sLit "tv")
 pprNameSpaceBrief TcClsName = ptext (sLit "tc")
 \end{code}
@@ -230,6 +236,14 @@ instance Ord OccName where
        -- Compares lexicographically, *not* by Unique of the string
     compare (OccName sp1 s1) (OccName sp2 s2) 
        = (s1  `compare` s2) `thenCmp` (sp1 `compare` sp2)
+
+INSTANCE_TYPEABLE0(OccName,occNameTc,"OccName")
+
+instance Data OccName where
+  -- don't traverse?
+  toConstr _   = abstractConstr "OccName"
+  gunfold _ _  = error "gunfold"
+  dataTypeOf _ = mkNoRepType "OccName"
 \end{code}
 
 
@@ -247,12 +261,26 @@ pprOccName :: OccName -> SDoc
 pprOccName (OccName sp occ) 
   = getPprStyle $ \ sty ->
     if codeStyle sty 
-       then ftext (zEncodeFS occ)
-       else ftext occ <> if debugStyle sty 
-                           then braces (pprNameSpaceBrief sp)
-                           else empty
+    then ftext (zEncodeFS occ)
+    else pp_occ <> pp_debug sty
+  where
+    pp_debug sty | debugStyle sty = braces (pprNameSpaceBrief sp)
+                | otherwise      = empty
+
+    pp_occ | opt_SuppressUniques = text (strip_th_unique (unpackFS occ))
+           | otherwise           = ftext occ
+
+       -- See Note [Suppressing uniques in OccNames]
+    strip_th_unique ('[' : c : _) | isAlphaNum c = []
+    strip_th_unique (c : cs) = c : strip_th_unique cs
+    strip_th_unique []       = []
 \end{code}
 
+Note [Suppressing uniques in OccNames]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This is a hack to de-wobblify the OccNames that contain uniques from
+Template Haskell that have been turned into a string in the OccName.
+See Note [Unique OccNames from Template Haskell] in Convert.hs
 
 %************************************************************************
 %*                                                                     *
@@ -307,22 +335,24 @@ mkClsOccFS = mkOccNameFS clsName
 
 OccEnvs are used mainly for the envts in ModIfaces.
 
+Note [The Unique of an OccName]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 They are efficient, because FastStrings have unique Int# keys.  We assume
-this key is less than 2^24, so we can make a Unique using
+this key is less than 2^24, and indeed FastStrings are allocated keys 
+sequentially starting at 0.
+
+So we can make a Unique using
        mkUnique ns key  :: Unique
 where 'ns' is a Char reprsenting the name space.  This in turn makes it
 easy to build an OccEnv.
 
 \begin{code}
 instance Uniquable OccName where
-  getUnique (OccName ns fs)
-      = mkUnique char (iBox (uniqueOfFS fs))
-      where    -- See notes above about this getUnique function
-        char = case ns of
-               VarName   -> 'i'
-               DataName  -> 'd'
-               TvName    -> 'v'
-               TcClsName -> 't'
+      -- See Note [The Unique of an OccName]
+  getUnique (OccName (VarName depth) fs) = mkVarOccUnique fs depth
+  getUnique (OccName DataName  fs) = mkDataOccUnique fs
+  getUnique (OccName TvName    fs) = mkTvOccUnique   fs
+  getUnique (OccName TcClsName fs) = mkTcOccUnique   fs
 
 newtype OccEnv a = A (UniqFM a)
 
@@ -337,6 +367,7 @@ elemOccEnv   :: OccName -> OccEnv a -> Bool
 foldOccEnv   :: (a -> b -> b) -> b -> OccEnv a -> b
 occEnvElts   :: OccEnv a -> [a]
 extendOccEnv_C :: (a->a->a) -> OccEnv a -> OccName -> a -> OccEnv a
+extendOccEnv_Acc :: (a->b->b) -> (a->b) -> OccEnv b -> OccName -> a -> OccEnv b
 plusOccEnv     :: OccEnv a -> OccEnv a -> OccEnv a
 plusOccEnv_C   :: (a->a->a) -> OccEnv a -> OccEnv a -> OccEnv a
 mapOccEnv      :: (a->b) -> OccEnv a -> OccEnv b
@@ -356,6 +387,7 @@ occEnvElts (A x)     = eltsUFM x
 plusOccEnv (A x) (A y)  = A $ plusUFM x y 
 plusOccEnv_C f (A x) (A y)      = A $ plusUFM_C f x y 
 extendOccEnv_C f (A x) y z   = A $ addToUFM_C f x y z
+extendOccEnv_Acc f g (A x) y z   = A $ addToUFM_Acc f g x y z
 mapOccEnv f (A x)       = A $ mapUFM f x
 mkOccEnv_C comb l = A $ addListToUFM_C comb emptyUFM l
 delFromOccEnv (A x) y    = A $ delFromUFM x y
@@ -414,7 +446,7 @@ setOccNameSpace sp (OccName _ occ) = OccName sp occ
 
 isVarOcc, isTvOcc, isTcOcc, isDataOcc :: OccName -> Bool
 
-isVarOcc (OccName VarName _) = True
+isVarOcc (OccName (VarName _) _) = True
 isVarOcc _                   = False
 
 isTvOcc (OccName TvName _) = True
@@ -426,12 +458,12 @@ isTcOcc _                     = False
 -- | /Value/ 'OccNames's are those that are either in 
 -- the variable or data constructor namespaces
 isValOcc :: OccName -> Bool
-isValOcc (OccName VarName  _) = True
+isValOcc (OccName (VarName _) _) = True
 isValOcc (OccName DataName _) = True
 isValOcc _                    = False
 
 isDataOcc (OccName DataName _) = True
-isDataOcc (OccName VarName s)  
+isDataOcc (OccName (VarName _) s)  
   | isLexCon s = pprPanic "isDataOcc: check me" (ppr s)
                -- Jan06: I don't think this should happen
 isDataOcc _                    = False
@@ -440,7 +472,7 @@ isDataOcc _                    = False
 -- a symbol (e.g. @:@, or @[]@)
 isDataSymOcc :: OccName -> Bool
 isDataSymOcc (OccName DataName s) = isLexConSym s
-isDataSymOcc (OccName VarName s)  
+isDataSymOcc (OccName (VarName _) s)  
   | isLexConSym s = pprPanic "isDataSymOcc: check me" (ppr s)
                -- Jan06: I don't think this should happen
 isDataSymOcc _                    = False
@@ -451,7 +483,7 @@ isDataSymOcc _                    = False
 isSymOcc :: OccName -> Bool
 isSymOcc (OccName DataName s)  = isLexConSym s
 isSymOcc (OccName TcClsName s) = isLexConSym s
-isSymOcc (OccName VarName s)   = isLexSym s
+isSymOcc (OccName (VarName _) s)   = isLexSym s
 isSymOcc (OccName TvName s)    = isLexSym s
 -- Pretty inefficient!
 
@@ -463,13 +495,12 @@ parenSymOcc occ doc | isSymOcc occ = parens doc
 
 
 \begin{code}
-reportIfUnused :: OccName -> Bool
--- ^ Haskell 98 encourages compilers to suppress warnings about
--- unused names in a pattern if they start with @_@: this implements
--- that test
-reportIfUnused occ = case occNameString occ of
-                       ('_' : _) -> False
-                       _other    -> True
+startsWithUnderscore :: OccName -> Bool
+-- ^ Haskell 98 encourages compilers to suppress warnings about unsed
+-- names in a pattern if they start with @_@: this implements that test
+startsWithUnderscore occ = case occNameString occ of
+                            ('_' : _) -> True
+                            _other    -> False
 \end{code}
 
 
@@ -481,19 +512,24 @@ reportIfUnused occ = case occNameString occ of
 
 Here's our convention for splitting up the interface file name space:
 
-       d...            dictionary identifiers
-                       (local variables, so no name-clash worries)
+   d...                dictionary identifiers
+               (local variables, so no name-clash worries)
 
-       \$f...          dict-fun identifiers (from inst decls)
-       \$dm...         default methods
-       \$p...          superclass selectors
-       \$w...          workers
-       :T...           compiler-generated tycons for dictionaries
-       :D...           ...ditto data cons
-        :Co...          ...ditto coercions
-       \$sf..          specialised version of f
+All of these other OccNames contain a mixture of alphabetic
+and symbolic characters, and hence cannot possibly clash with
+a user-written type or function name
 
-       in encoded form these appear as Zdfxxx etc
+   $f...       Dict-fun identifiers (from inst decls)
+   $dmop       Default method for 'op'
+   $pnC                n'th superclass selector for class C
+   $wf         Worker for functtoin 'f'
+   $sf..       Specialised version of f
+   T:C         Tycon for dictionary for class C
+   D:C         Data constructor for dictionary for class C
+   NTCo:T       Coercion connecting newtype T with its representation type
+   TFCo:R       Coercion connecting a data family to its respresentation type R
+
+In encoded form these appear as Zdfxxx etc
 
        :...            keywords (export:, letrec: etc.)
 --- I THINK THIS IS WRONG!
@@ -524,27 +560,28 @@ mkDataConWrapperOcc, mkWorkerOcc, mkDefaultMethodOcc, mkDerivedTyConOcc,
        mkClassTyConOcc, mkClassDataConOcc, mkDictOcc, mkIPOcc, 
        mkSpecOcc, mkForeignExportOcc, mkGenOcc1, mkGenOcc2,
        mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc, mkNewTyCoOcc,
-       mkInstTyCoOcc, mkEqPredCoOcc, 
+       mkInstTyCoOcc, mkEqPredCoOcc, mkClassOpAuxOcc,
         mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc,
        mkVectOcc, mkVectTyConOcc, mkVectDataConOcc, mkVectIsoOcc,
-       mkPArrayTyConOcc, mkPArrayDataConOcc, mkPReprTyConOcc, mkPADFunOcc
+       mkPDataTyConOcc, mkPDataDataConOcc, mkPReprTyConOcc, mkPADFunOcc
    :: OccName -> OccName
 
 -- These derived variables have a prefix that no Haskell value could have
 mkDataConWrapperOcc = mk_simple_deriv varName  "$W"
 mkWorkerOcc         = mk_simple_deriv varName  "$w"
 mkDefaultMethodOcc  = mk_simple_deriv varName  "$dm"
+mkClassOpAuxOcc     = mk_simple_deriv varName  "$c"
 mkDerivedTyConOcc   = mk_simple_deriv tcName   ":"     -- The : prefix makes sure it classifies
-mkClassTyConOcc     = mk_simple_deriv tcName   ":T"    -- as a tycon/datacon
-mkClassDataConOcc   = mk_simple_deriv dataName ":D"    -- We go straight to the "real" data con
+mkClassTyConOcc     = mk_simple_deriv tcName   "T:"    -- as a tycon/datacon
+mkClassDataConOcc   = mk_simple_deriv dataName "D:"    -- We go straight to the "real" data con
                                                        -- for datacons from classes
 mkDictOcc          = mk_simple_deriv varName  "$d"
 mkIPOcc                    = mk_simple_deriv varName  "$i"
 mkSpecOcc          = mk_simple_deriv varName  "$s"
 mkForeignExportOcc  = mk_simple_deriv varName  "$f"
-mkNewTyCoOcc        = mk_simple_deriv tcName  ":Co"
-mkInstTyCoOcc       = mk_simple_deriv tcName  ":CoF"     -- derived from rep ty
-mkEqPredCoOcc      = mk_simple_deriv tcName  "$co"
+mkNewTyCoOcc        = mk_simple_deriv tcName   "NTCo:" -- Coercion for newtypes
+mkInstTyCoOcc       = mk_simple_deriv tcName   "TFCo:"   -- Coercion for type functions
+mkEqPredCoOcc      = mk_simple_deriv tcName   "$co"
 
 -- used in derived instances
 mkCon2TagOcc        = mk_simple_deriv varName  "$con2tag_"
@@ -566,8 +603,8 @@ mkVectOcc          = mk_simple_deriv varName  "$v_"
 mkVectTyConOcc     = mk_simple_deriv tcName   ":V_"
 mkVectDataConOcc   = mk_simple_deriv dataName ":VD_"
 mkVectIsoOcc       = mk_simple_deriv varName  "$VI_"
-mkPArrayTyConOcc   = mk_simple_deriv tcName   ":VP_"
-mkPArrayDataConOcc = mk_simple_deriv dataName ":VPD_"
+mkPDataTyConOcc    = mk_simple_deriv tcName   ":VP_"
+mkPDataDataConOcc  = mk_simple_deriv dataName ":VPD_"
 mkPReprTyConOcc    = mk_simple_deriv tcName   ":VR_"
 mkPADFunOcc        = mk_simple_deriv varName  "$PA_"
 
@@ -597,33 +634,43 @@ mkLocalOcc uniq occ
 \end{code}
 
 \begin{code}
--- | Derive a name for the representation type constructor of a @data@/@newtype@
--- instance.
-mkInstTyTcOcc :: Int                   -- ^ DFun Index
-             -> OccName                -- ^ Family name, e.g. @Map@
-             -> OccName                -- ^ Nice unique version, e.g. @:R23Map@
-mkInstTyTcOcc index occ
-   = mk_deriv tcName (":R" ++ show index) (occNameString occ)
+-- | Derive a name for the representation type constructor of a
+-- @data@\/@newtype@ instance.
+mkInstTyTcOcc :: String                -- ^ Family name, e.g. @Map@
+              -> OccSet                 -- ^ avoid these Occs
+             -> OccName                -- ^ @R:Map@
+mkInstTyTcOcc str set =
+  chooseUniqueOcc tcName ('R' : ':' : str) set
 \end{code}
 
 \begin{code}
 mkDFunOcc :: String            -- ^ Typically the class and type glommed together e.g. @OrdMaybe@.
                                -- Only used in debug mode, for extra clarity
          -> Bool               -- ^ Is this a hs-boot instance DFun?
-         -> Int                -- ^ Unique index
+          -> OccSet             -- ^ avoid these Occs
          -> OccName            -- ^ E.g. @$f3OrdMaybe@
 
 -- In hs-boot files we make dict funs like $fx7ClsTy, which get bound to the real
 -- thing when we compile the mother module. Reason: we don't know exactly
 -- what the  mother module will call it.
 
-mkDFunOcc info_str is_boot index 
-  = mk_deriv VarName prefix string
+mkDFunOcc info_str is_boot set
+  = chooseUniqueOcc (VarName 0) (prefix ++ info_str) set
   where
     prefix | is_boot   = "$fx"
           | otherwise = "$f"
-    string | opt_PprStyle_Debug = show index ++ info_str
-          | otherwise          = show index
+\end{code}
+
+Sometimes we need to pick an OccName that has not already been used,
+given a set of in-use OccNames.
+
+\begin{code}
+chooseUniqueOcc :: NameSpace -> String -> OccSet -> OccName
+chooseUniqueOcc ns str set = loop (mkOccName ns str) (0::Int)
+  where
+  loop occ n
+   | occ `elemOccSet` set = loop (mkOccName ns (str ++ show n)) (n+1)
+   | otherwise            = occ
 \end{code}
 
 We used to add a '$m' to indicate a method, but that gives rise to bad
@@ -647,7 +694,7 @@ guys never show up in error messages.  What a hack.
 
 \begin{code}
 mkMethodOcc :: OccName -> OccName
-mkMethodOcc occ@(OccName VarName _) = occ
+mkMethodOcc occ@(OccName (VarName _) _) = occ
 mkMethodOcc occ                     = mk_simple_deriv varName "$m" occ
 \end{code}
 
@@ -689,7 +736,9 @@ tidyOccName in_scope occ@(OccName occ_sp fs)
        Just n  ->      -- Already used: make a new guess, 
                        -- change the guess base, and try again
                   tidyOccName  (extendOccEnv in_scope occ (n+1))
-                               (mkOccName occ_sp (unpackFS fs ++ show n))
+                                (mkOccName occ_sp (base_occ ++ show n))
+  where
+    base_occ = reverse (dropWhile isDigit (reverse (unpackFS fs)))
 \end{code}
 
 %************************************************************************
@@ -781,21 +830,22 @@ isSymbolASCII c = c `elem` "!#$%&*+./<=>?@\\^|~-"
 
 \begin{code}
 instance Binary NameSpace where
-    put_ bh VarName = do
-           putByte bh 0
+    put_ bh (VarName depth) = do if depth > 255-4
+                                   then error "FIXME: no support for serializing VarNames at this syntactic depth"
+                                   else putByte bh ((fromIntegral ((depth+3) :: Int)))
     put_ bh DataName = do
-           putByte bh 1
+           putByte bh 0
     put_ bh TvName = do
-           putByte bh 2
+           putByte bh 1
     put_ bh TcClsName = do
-           putByte bh 3
+           putByte bh 2
     get bh = do
            h <- getByte bh
            case h of
-             0 -> do return VarName
-             1 -> do return DataName
-             2 -> do return TvName
-             _ -> do return TcClsName
+             0 -> do return DataName
+             1 -> do return TvName
+             2 -> do return TcClsName
+             n -> do return (VarName (fromIntegral (n-3)))
 
 instance Binary OccName where
     put_ bh (OccName aa ab) = do