Use addToUFM_Acc where appropriate
[ghc-hetmet.git] / compiler / basicTypes / OccName.lhs
index ba17c02..8248b5f 100644 (file)
@@ -4,63 +4,89 @@
 %
 
 \begin{code}
+-- |
+-- #name_types#
+-- 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
+--   data constructors
+--
+-- * 'RdrName.RdrName': see "RdrName#name_types"
+--
+-- * 'Name.Name': see "Name#name_types"
+--
+-- * 'Id.Id': see "Id#name_types"
+--
+-- * 'Var.Var': see "Var#name_types"
 module OccName (
-       -- * The NameSpace type; abstact
-       NameSpace, tcName, clsName, tcClsName, dataName, varName, 
+       -- * The 'NameSpace' type
+       NameSpace, -- Abstract
+       
+       -- ** Construction
+       -- $real_vs_source_data_constructors
+       tcName, clsName, tcClsName, dataName, varName, 
        tvName, srcDataName,
 
-       -- ** Printing
+       -- ** Pretty Printing
        pprNameSpace, pprNonVarNameSpace, pprNameSpaceBrief,
 
-       -- * The OccName type
+       -- * The 'OccName' type
        OccName,        -- Abstract, instance of Outputable
        pprOccName, 
 
        -- ** Construction      
        mkOccName, mkOccNameFS, 
        mkVarOcc, mkVarOccFS,
-       mkTyVarOcc,
+       mkDataOcc, mkDataOccFS,
+       mkTyVarOcc, mkTyVarOccFS,
+       mkTcOcc, mkTcOccFS,
+       mkClsOcc, mkClsOccFS,
        mkDFunOcc,
        mkTupleOcc, 
        setOccNameSpace,
 
-       -- ** Derived OccNames
+       -- ** Derived 'OccName's
+        isDerivedOccName,
        mkDataConWrapperOcc, mkWorkerOcc, mkDefaultMethodOcc,
-       mkDerivedTyConOcc, mkNewTyCoOcc,
+       mkDerivedTyConOcc, mkNewTyCoOcc, mkClassOpAuxOcc,
+        mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc,
        mkClassTyConOcc, mkClassDataConOcc, mkDictOcc, mkIPOcc, 
        mkSpecOcc, mkForeignExportOcc, mkGenOcc1, mkGenOcc2,
        mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc,
        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, isTcClsName, isVarName,
+       parenSymOcc, startsWithUnderscore, 
+       
+       isTcClsNameSpace, isTvNameSpace, isDataConNameSpace, isVarNameSpace, isValNameSpace,
 
        isTupleOcc_maybe,
 
-       -- The OccEnv type
+       -- * The 'OccEnv' type
        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
+       -- * The 'OccSet' type
        OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, 
        extendOccSetList,
        unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, occSetElts, 
        foldOccSet, isEmptyOccSet, intersectOccSet, intersectsOccSet,
                   
-       -- Tidying up
+       -- * Tidying up
        TidyOccEnv, emptyTidyOccEnv, tidyOccName, initTidyOccEnv,
 
-       -- The basic form of names
+       -- * Lexical characteristics of Haskell names
        isLexCon, isLexVar, isLexId, isLexSym,
        isLexConId, isLexConSym, isLexVarId, isLexVarSym,
        startsVarSym, startsVarId, startsConSym, startsConId
@@ -69,17 +95,15 @@ module OccName (
 import Util
 import Unique
 import BasicTypes
-import StaticFlags
 import UniqFM
 import UniqSet
 import FastString
-import FastTypes
 import Outputable
 import Binary
-
-import GHC.Exts
 import Data.Char
+\end{code}
 
+\begin{code}
 -- Unicode TODO: put isSymbol in libcompat
 #if !defined(__GLASGOW_HASKELL__) || __GLASGOW_HASKELL__ > 604
 #else
@@ -106,19 +130,21 @@ data NameSpace = VarName  -- Variables, including "real" data constructors
 
 -- Note [Data Constructors]  
 -- see also: Note [Data Constructor Naming] in DataCon.lhs
--- 
---     "Source" data constructors are the data constructors mentioned
---     in Haskell source code
 --
---     "Real" data constructors are the data constructors of the
---     representation type, which may not be the same as the source
---     type
-
--- Example:
---     data T = T !(Int,Int)
+-- $real_vs_source_data_constructors
+-- There are two forms of data constructor:
+--
+--     [Source data constructors] The data constructors mentioned in Haskell source code
+--
+--     [Real data constructors] The data constructors of the representation type, which may not be the same as the source type
+--
+-- For example:
+--
+-- > data T = T !(Int, Int)
+--
+-- The source datacon has type @(Int, Int) -> T@
+-- The real   datacon has type @Int -> Int -> T@
 --
--- The source datacon has type (Int,Int) -> T
--- The real   datacon has type Int -> Int -> T
 -- GHC chooses a representation based on the strictness etc.
 
 tcName, clsName, tcClsName :: NameSpace
@@ -138,14 +164,27 @@ srcDataName = DataName    -- Haskell-source data constructors should be
 tvName      = TvName
 varName     = VarName
 
-isTcClsName :: NameSpace -> Bool
-isTcClsName TcClsName = True
-isTcClsName _        = False
+isDataConNameSpace :: NameSpace -> Bool
+isDataConNameSpace DataName = True
+isDataConNameSpace _        = False
+
+isTcClsNameSpace :: NameSpace -> Bool
+isTcClsNameSpace TcClsName = True
+isTcClsNameSpace _         = False
+
+isTvNameSpace :: NameSpace -> Bool
+isTvNameSpace TvName = True
+isTvNameSpace _      = False
 
-isVarName :: NameSpace -> Bool -- Variables or type variables, but not constructors
-isVarName TvName  = True
-isVarName VarName = True
-isVarName _       = False
+isVarNameSpace :: NameSpace -> Bool    -- Variables or type variables, but not constructors
+isVarNameSpace TvName  = True
+isVarNameSpace VarName = True
+isVarNameSpace _       = False
+
+isValNameSpace :: NameSpace -> Bool
+isValNameSpace DataName = True
+isValNameSpace VarName  = True
+isValNameSpace _        = False
 
 pprNameSpace :: NameSpace -> SDoc
 pprNameSpace DataName  = ptext (sLit "data constructor")
@@ -230,8 +269,29 @@ mkVarOcc s = mkOccName varName s
 mkVarOccFS :: FastString -> OccName
 mkVarOccFS fs = mkOccNameFS varName fs
 
-mkTyVarOcc :: FastString -> OccName
-mkTyVarOcc fs = mkOccNameFS tvName fs
+mkDataOcc :: String -> OccName
+mkDataOcc = mkOccName dataName
+
+mkDataOccFS :: FastString -> OccName
+mkDataOccFS = mkOccNameFS dataName
+
+mkTyVarOcc :: String -> OccName
+mkTyVarOcc = mkOccName tvName
+
+mkTyVarOccFS :: FastString -> OccName
+mkTyVarOccFS fs = mkOccNameFS tvName fs
+
+mkTcOcc :: String -> OccName
+mkTcOcc = mkOccName tcName
+
+mkTcOccFS :: FastString -> OccName
+mkTcOccFS = mkOccNameFS tcName
+
+mkClsOcc :: String -> OccName
+mkClsOcc = mkOccName clsName
+
+mkClsOccFS :: FastString -> OccName
+mkClsOccFS = mkOccNameFS clsName
 \end{code}
 
 
@@ -243,22 +303,24 @@ mkTyVarOcc fs = mkOccNameFS tvName fs
 
 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   fs) = mkVarOccUnique  fs
+  getUnique (OccName DataName  fs) = mkDataOccUnique fs
+  getUnique (OccName TvName    fs) = mkTvOccUnique   fs
+  getUnique (OccName TcClsName fs) = mkTcOccUnique   fs
 
 newtype OccEnv a = A (UniqFM a)
 
@@ -273,6 +335,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
@@ -292,6 +355,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
@@ -348,7 +412,7 @@ occNameString (OccName _ s) = unpackFS s
 setOccNameSpace :: NameSpace -> OccName -> OccName
 setOccNameSpace sp (OccName _ occ) = OccName sp occ
 
-isVarOcc, isTvOcc, isDataSymOcc, isSymOcc, isTcOcc, isValOcc, isDataOcc :: OccName -> Bool
+isVarOcc, isTvOcc, isTcOcc, isDataOcc :: OccName -> Bool
 
 isVarOcc (OccName VarName _) = True
 isVarOcc _                   = False
@@ -359,45 +423,52 @@ isTvOcc _                  = False
 isTcOcc (OccName TcClsName _) = True
 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 DataName _) = True
 isValOcc _                    = False
 
--- Data constructor operator (starts with ':', or '[]')
--- Pretty inefficient!
-isDataSymOcc (OccName DataName s) = isLexConSym s
-isDataSymOcc (OccName VarName s)  
-  | isLexConSym s = pprPanic "isDataSymOcc: check me" (ppr s)
-               -- Jan06: I don't think this should happen
-isDataSymOcc _                    = False
-
 isDataOcc (OccName DataName _) = True
 isDataOcc (OccName VarName s)  
   | isLexCon s = pprPanic "isDataOcc: check me" (ppr s)
                -- Jan06: I don't think this should happen
 isDataOcc _                    = False
 
--- Any operator (data constructor or variable)
+-- | Test if the 'OccName' is a data constructor that starts with
+-- a symbol (e.g. @:@, or @[]@)
+isDataSymOcc :: OccName -> Bool
+isDataSymOcc (OccName DataName s) = isLexConSym s
+isDataSymOcc (OccName VarName s)  
+  | isLexConSym s = pprPanic "isDataSymOcc: check me" (ppr s)
+               -- Jan06: I don't think this should happen
+isDataSymOcc _                    = False
 -- Pretty inefficient!
+
+-- | Test if the 'OccName' is that for any operator (whether 
+-- it is a data constructor or variable or whatever)
+isSymOcc :: OccName -> Bool
 isSymOcc (OccName DataName s)  = isLexConSym s
 isSymOcc (OccName TcClsName s) = isLexConSym s
 isSymOcc (OccName VarName s)   = isLexSym s
 isSymOcc (OccName TvName s)    = isLexSym s
+-- Pretty inefficient!
 
 parenSymOcc :: OccName -> SDoc -> SDoc
--- Wrap parens around an operator
+-- ^ Wrap parens around an operator
 parenSymOcc occ doc | isSymOcc occ = parens doc
                    | otherwise    = doc
 \end{code}
 
 
 \begin{code}
-reportIfUnused :: OccName -> Bool
-  -- Haskell 98 encourages compilers to suppress warnings about
-  -- unused names in a pattern if they start with "_".
-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}
 
 
@@ -409,26 +480,30 @@ 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)
+
+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
 
-       $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
+   $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
+In encoded form these appear as Zdfxxx etc
 
        :...            keywords (export:, letrec: etc.)
 --- I THINK THIS IS WRONG!
 
 This knowledge is encoded in the following functions.
 
-
 @mk_deriv@ generates an @OccName@ from the prefix and a string.
 NB: The string must already be encoded!
 
@@ -439,6 +514,13 @@ mk_deriv :: NameSpace
         -> OccName
 
 mk_deriv occ_sp sys_prefix str = mkOccName occ_sp (sys_prefix ++ str)
+
+isDerivedOccName :: OccName -> Bool
+isDerivedOccName occ = 
+   case occNameString occ of
+     '$':c:_ | isAlphaNum c -> True
+     ':':c:_ | isAlphaNum c -> True
+     _other                 -> False
 \end{code}
 
 \begin{code}
@@ -446,26 +528,33 @@ 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_"
+mkTag2ConOcc        = mk_simple_deriv varName  "$tag2con_"
+mkMaxTagOcc         = mk_simple_deriv varName  "$maxtag_"
 
 -- Generic derivable classes
 mkGenOcc1           = mk_simple_deriv varName  "$gfrom"
@@ -482,8 +571,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_"
 
@@ -497,50 +586,59 @@ mkDataConWorkerOcc datacon_occ = setOccNameSpace varName datacon_occ
 \end{code}
 
 \begin{code}
-mkSuperDictSelOcc :: Int       -- Index of superclass, eg 3
-                 -> OccName    -- Class, eg "Ord"
-                 -> OccName    -- eg "$p3Ord"
+mkSuperDictSelOcc :: Int       -- ^ Index of superclass, e.g. 3
+                 -> OccName    -- ^ Class, e.g. @Ord@
+                 -> OccName    -- ^ Derived 'Occname', e.g. @$p3Ord@
 mkSuperDictSelOcc index cls_occ
   = mk_deriv varName "$p" (show index ++ occNameString cls_occ)
 
-mkLocalOcc :: Unique           -- Unique
-          -> OccName           -- Local name (e.g. "sat")
-          -> OccName           -- Nice unique version ("$L23sat")
+mkLocalOcc :: Unique           -- ^ Unique to combine with the 'OccName'
+          -> OccName           -- ^ Local name, e.g. @sat@
+          -> OccName           -- ^ Nice unique version, e.g. @$L23sat@
 mkLocalOcc uniq occ
    = mk_deriv varName ("$L" ++ show uniq) (occNameString occ)
        -- The Unique might print with characters 
        -- that need encoding (e.g. 'z'!)
 \end{code}
 
-Derive a name for the representation type constructor of a data/newtype
-instance.
-
 \begin{code}
-mkInstTyTcOcc :: Int                   -- Index
-             -> OccName                -- Family name (e.g. "Map")
-             -> OccName                -- Nice unique version (":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"
+mkDFunOcc :: String            -- ^ Typically the class and type glommed together e.g. @OrdMaybe@.
                                -- Only used in debug mode, for extra clarity
-         -> Bool               -- True <=> hs-boot instance dfun
-         -> Int                -- Unique index
-         -> OccName            -- "$f3OrdMaybe"
+         -> Bool               -- ^ Is this a hs-boot instance DFun?
+          -> 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 (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