{-
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-}

{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE LambdaCase #-}

-- |
-- #name_types#
-- GHC uses several kinds of name internally:
--
-- * 'GHC.Types.Name.Occurrence.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
--
-- * 'GHC.Types.Name.Reader.RdrName': see "GHC.Types.Name.Reader#name_types"
--
-- * 'GHC.Types.Name.Name': see "GHC.Types.Name#name_types"
--
-- * 'GHC.Types.Id.Id': see "GHC.Types.Id#name_types"
--
-- * 'GHC.Types.Var.Var': see "GHC.Types.Var#name_types"

module GHC.Types.Name.Occurrence (
        -- * The 'NameSpace' type
        NameSpace, -- Abstract

        nameSpacesRelated,

        -- ** Construction
        -- $real_vs_source_data_constructors
        tcName, clsName, tcClsName, dataName, varName,
        tvName, srcDataName,

        -- ** Pretty Printing
        pprNameSpace, pprNonVarNameSpace, pprNameSpaceBrief,

        -- * The 'OccName' type
        OccName,        -- Abstract, instance of Outputable
        pprOccName,

        -- ** Construction
        mkOccName, mkOccNameFS,
        mkVarOcc, mkVarOccFS,
        mkDataOcc, mkDataOccFS,
        mkTyVarOcc, mkTyVarOccFS,
        mkTcOcc, mkTcOccFS,
        mkClsOcc, mkClsOccFS,
        mkDFunOcc,
        setOccNameSpace,
        demoteOccName,
        promoteOccName,
        HasOccName(..),

        -- ** Derived 'OccName's
        isDerivedOccName,
        mkDataConWrapperOcc, mkWorkerOcc,
        mkMatcherOcc, mkBuilderOcc,
        mkDefaultMethodOcc, isDefaultMethodOcc, isTypeableBindOcc,
        mkNewTyCoOcc, mkClassOpAuxOcc,
        mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc,
        mkClassDataConOcc, mkDictOcc, mkIPOcc,
        mkSpecOcc, mkForeignExportOcc, mkRepEqOcc,
        mkGenR, mkGen1R,
        mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc,
        mkSuperDictSelOcc, mkSuperDictAuxOcc,
        mkLocalOcc, mkMethodOcc, mkInstTyTcOcc,
        mkInstTyCoOcc, mkEqPredCoOcc,
        mkRecFldSelOcc,
        mkTyConRepOcc,

        -- ** Deconstruction
        occNameFS, occNameString, occNameSpace,

        isVarOcc, isTvOcc, isTcOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc,
        parenSymOcc, startsWithUnderscore,

        isTcClsNameSpace, isTvNameSpace, isDataConNameSpace, isVarNameSpace, isValNameSpace,

        -- * The 'OccEnv' type
        OccEnv, emptyOccEnv, unitOccEnv, extendOccEnv, mapOccEnv,
        lookupOccEnv, mkOccEnv, mkOccEnv_C, extendOccEnvList, elemOccEnv,
        occEnvElts, foldOccEnv, plusOccEnv, plusOccEnv_C, extendOccEnv_C,
        extendOccEnv_Acc, filterOccEnv, delListFromOccEnv, delFromOccEnv,
        alterOccEnv, pprOccEnv,

        -- * The 'OccSet' type
        OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet,
        extendOccSetList,
        unionOccSets, unionManyOccSets, minusOccSet, elemOccSet,
        isEmptyOccSet, intersectOccSet,
        filterOccSet,

        -- * Tidying up
        TidyOccEnv, emptyTidyOccEnv, initTidyOccEnv,
        tidyOccName, avoidClashesOccEnv, delTidyOccEnvList,

        -- FsEnv
        FastStringEnv, emptyFsEnv, lookupFsEnv, extendFsEnv, mkFsEnv
    ) where

import GHC.Prelude

import GHC.Utils.Misc
import GHC.Types.Unique
import GHC.Builtin.Uniques
import GHC.Types.Unique.FM
import GHC.Types.Unique.Set
import GHC.Data.FastString
import GHC.Data.FastString.Env
import GHC.Utils.Outputable
import GHC.Utils.Lexeme
import GHC.Utils.Binary
import Control.DeepSeq
import Data.Char
import Data.Data

{-
************************************************************************
*                                                                      *
\subsection{Name space}
*                                                                      *
************************************************************************
-}

data NameSpace = VarName        -- Variables, including "real" data constructors
               | DataName       -- "Source" data constructors
               | TvName         -- Type variables
               | TcClsName      -- Type constructors and classes; Haskell has them
                                -- in the same name space for now.
               deriving( NameSpace -> NameSpace -> Bool
(NameSpace -> NameSpace -> Bool)
-> (NameSpace -> NameSpace -> Bool) -> Eq NameSpace
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NameSpace -> NameSpace -> Bool
$c/= :: NameSpace -> NameSpace -> Bool
== :: NameSpace -> NameSpace -> Bool
$c== :: NameSpace -> NameSpace -> Bool
Eq, Eq NameSpace
Eq NameSpace
-> (NameSpace -> NameSpace -> Ordering)
-> (NameSpace -> NameSpace -> Bool)
-> (NameSpace -> NameSpace -> Bool)
-> (NameSpace -> NameSpace -> Bool)
-> (NameSpace -> NameSpace -> Bool)
-> (NameSpace -> NameSpace -> NameSpace)
-> (NameSpace -> NameSpace -> NameSpace)
-> Ord NameSpace
NameSpace -> NameSpace -> Bool
NameSpace -> NameSpace -> Ordering
NameSpace -> NameSpace -> NameSpace
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NameSpace -> NameSpace -> NameSpace
$cmin :: NameSpace -> NameSpace -> NameSpace
max :: NameSpace -> NameSpace -> NameSpace
$cmax :: NameSpace -> NameSpace -> NameSpace
>= :: NameSpace -> NameSpace -> Bool
$c>= :: NameSpace -> NameSpace -> Bool
> :: NameSpace -> NameSpace -> Bool
$c> :: NameSpace -> NameSpace -> Bool
<= :: NameSpace -> NameSpace -> Bool
$c<= :: NameSpace -> NameSpace -> Bool
< :: NameSpace -> NameSpace -> Bool
$c< :: NameSpace -> NameSpace -> Bool
compare :: NameSpace -> NameSpace -> Ordering
$ccompare :: NameSpace -> NameSpace -> Ordering
Ord )

-- Note [Data Constructors]
-- see also: Note [Data Constructor Naming] in GHC.Core.DataCon
--
-- $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@
--
-- GHC chooses a representation based on the strictness etc.

tcName, clsName, tcClsName :: NameSpace
dataName, srcDataName      :: NameSpace
tvName, varName            :: 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
tcName :: NameSpace
tcName    = NameSpace
TcClsName           -- Type constructors
clsName :: NameSpace
clsName   = NameSpace
TcClsName           -- Classes
tcClsName :: NameSpace
tcClsName = NameSpace
TcClsName           -- Not sure which!

dataName :: NameSpace
dataName    = NameSpace
DataName
srcDataName :: NameSpace
srcDataName = NameSpace
DataName  -- Haskell-source data constructors should be
                        -- in the Data name space

tvName :: NameSpace
tvName      = NameSpace
TvName
varName :: NameSpace
varName     = NameSpace
VarName

isDataConNameSpace :: NameSpace -> Bool
isDataConNameSpace :: NameSpace -> Bool
isDataConNameSpace NameSpace
DataName = Bool
True
isDataConNameSpace NameSpace
_        = Bool
False

isTcClsNameSpace :: NameSpace -> Bool
isTcClsNameSpace :: NameSpace -> Bool
isTcClsNameSpace NameSpace
TcClsName = Bool
True
isTcClsNameSpace NameSpace
_         = Bool
False

isTvNameSpace :: NameSpace -> Bool
isTvNameSpace :: NameSpace -> Bool
isTvNameSpace NameSpace
TvName = Bool
True
isTvNameSpace NameSpace
_      = Bool
False

isVarNameSpace :: NameSpace -> Bool     -- Variables or type variables, but not constructors
isVarNameSpace :: NameSpace -> Bool
isVarNameSpace NameSpace
TvName  = Bool
True
isVarNameSpace NameSpace
VarName = Bool
True
isVarNameSpace NameSpace
_       = Bool
False

isValNameSpace :: NameSpace -> Bool
isValNameSpace :: NameSpace -> Bool
isValNameSpace NameSpace
DataName = Bool
True
isValNameSpace NameSpace
VarName  = Bool
True
isValNameSpace NameSpace
_        = Bool
False

pprNameSpace :: NameSpace -> SDoc
pprNameSpace :: NameSpace -> SDoc
pprNameSpace NameSpace
DataName  = [Char] -> SDoc
text [Char]
"data constructor"
pprNameSpace NameSpace
VarName   = [Char] -> SDoc
text [Char]
"variable"
pprNameSpace NameSpace
TvName    = [Char] -> SDoc
text [Char]
"type variable"
pprNameSpace NameSpace
TcClsName = [Char] -> SDoc
text [Char]
"type constructor or class"

pprNonVarNameSpace :: NameSpace -> SDoc
pprNonVarNameSpace :: NameSpace -> SDoc
pprNonVarNameSpace NameSpace
VarName = SDoc
empty
pprNonVarNameSpace NameSpace
ns = NameSpace -> SDoc
pprNameSpace NameSpace
ns

pprNameSpaceBrief :: NameSpace -> SDoc
pprNameSpaceBrief :: NameSpace -> SDoc
pprNameSpaceBrief NameSpace
DataName  = Char -> SDoc
char Char
'd'
pprNameSpaceBrief NameSpace
VarName   = Char -> SDoc
char Char
'v'
pprNameSpaceBrief NameSpace
TvName    = [Char] -> SDoc
text [Char]
"tv"
pprNameSpaceBrief NameSpace
TcClsName = [Char] -> SDoc
text [Char]
"tc"

-- demoteNameSpace lowers the NameSpace if possible.  We can not know
-- in advance, since a TvName can appear in an HsTyVar.
-- See Note [Demotion] in GHC.Rename.Env.
demoteNameSpace :: NameSpace -> Maybe NameSpace
demoteNameSpace :: NameSpace -> Maybe NameSpace
demoteNameSpace NameSpace
VarName = Maybe NameSpace
forall a. Maybe a
Nothing
demoteNameSpace NameSpace
DataName = Maybe NameSpace
forall a. Maybe a
Nothing
demoteNameSpace NameSpace
TvName = Maybe NameSpace
forall a. Maybe a
Nothing
demoteNameSpace NameSpace
TcClsName = NameSpace -> Maybe NameSpace
forall a. a -> Maybe a
Just NameSpace
DataName

-- promoteNameSpace promotes the NameSpace as follows.
-- See Note [Promotion] in GHC.Rename.Env.
promoteNameSpace :: NameSpace -> Maybe NameSpace
promoteNameSpace :: NameSpace -> Maybe NameSpace
promoteNameSpace NameSpace
DataName = NameSpace -> Maybe NameSpace
forall a. a -> Maybe a
Just NameSpace
TcClsName
promoteNameSpace NameSpace
VarName = NameSpace -> Maybe NameSpace
forall a. a -> Maybe a
Just NameSpace
TvName
promoteNameSpace NameSpace
TcClsName = Maybe NameSpace
forall a. Maybe a
Nothing
promoteNameSpace NameSpace
TvName = Maybe NameSpace
forall a. Maybe a
Nothing

{-
************************************************************************
*                                                                      *
\subsection[Name-pieces-datatypes]{The @OccName@ datatypes}
*                                                                      *
************************************************************************
-}

-- | Occurrence Name
--
-- In this context that means:
-- "classified (i.e. as a type name, value name, etc) but not qualified
-- and not yet resolved"
data OccName = OccName
    { OccName -> NameSpace
occNameSpace  :: !NameSpace
    , OccName -> FastString
occNameFS     :: !FastString
    }

instance Eq OccName where
    (OccName NameSpace
sp1 FastString
s1) == :: OccName -> OccName -> Bool
== (OccName NameSpace
sp2 FastString
s2) = FastString
s1 FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
s2 Bool -> Bool -> Bool
&& NameSpace
sp1 NameSpace -> NameSpace -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace
sp2

instance Ord OccName where
        -- Compares lexicographically, *not* by Unique of the string
    compare :: OccName -> OccName -> Ordering
compare (OccName NameSpace
sp1 FastString
s1) (OccName NameSpace
sp2 FastString
s2)
        = (FastString
s1  FastString -> FastString -> Ordering
`lexicalCompareFS` FastString
s2) Ordering -> Ordering -> Ordering
`thenCmp` (NameSpace
sp1 NameSpace -> NameSpace -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` NameSpace
sp2)

instance Data OccName where
  -- don't traverse?
  toConstr :: OccName -> Constr
toConstr OccName
_   = [Char] -> Constr
abstractConstr [Char]
"OccName"
  gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OccName
gunfold forall b r. Data b => c (b -> r) -> c r
_ forall r. r -> c r
_  = [Char] -> Constr -> c OccName
forall a. HasCallStack => [Char] -> a
error [Char]
"gunfold"
  dataTypeOf :: OccName -> DataType
dataTypeOf OccName
_ = [Char] -> DataType
mkNoRepType [Char]
"OccName"

instance HasOccName OccName where
  occName :: OccName -> OccName
occName = OccName -> OccName
forall a. a -> a
id

instance NFData OccName where
  rnf :: OccName -> ()
rnf OccName
x = OccName
x OccName -> () -> ()
`seq` ()

{-
************************************************************************
*                                                                      *
\subsection{Printing}
*                                                                      *
************************************************************************
-}

instance Outputable OccName where
    ppr :: OccName -> SDoc
ppr = OccName -> SDoc
pprOccName

instance OutputableBndr OccName where
    pprBndr :: BindingSite -> OccName -> SDoc
pprBndr BindingSite
_ = OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr
    pprInfixOcc :: OccName -> SDoc
pprInfixOcc OccName
n = Bool -> SDoc -> SDoc
pprInfixVar (OccName -> Bool
isSymOcc OccName
n) (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
n)
    pprPrefixOcc :: OccName -> SDoc
pprPrefixOcc OccName
n = Bool -> SDoc -> SDoc
pprPrefixVar (OccName -> Bool
isSymOcc OccName
n) (OccName -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccName
n)

pprOccName :: OccName -> SDoc
pprOccName :: OccName -> SDoc
pprOccName (OccName NameSpace
sp FastString
occ)
  = (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \ PprStyle
sty ->
    if PprStyle -> Bool
codeStyle PprStyle
sty
    then FastZString -> SDoc
ztext (FastString -> FastZString
zEncodeFS FastString
occ)
    else SDoc
pp_occ SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
whenPprDebug (SDoc -> SDoc
braces (NameSpace -> SDoc
pprNameSpaceBrief NameSpace
sp))
  where
    pp_occ :: SDoc
pp_occ = (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressUniques ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \case
               Bool
True  -> [Char] -> SDoc
text ([Char] -> [Char]
strip_th_unique (FastString -> [Char]
unpackFS FastString
occ))
               Bool
False -> FastString -> SDoc
ftext FastString
occ

        -- See Note [Suppressing uniques in OccNames]
    strip_th_unique :: [Char] -> [Char]
strip_th_unique (Char
'[' : Char
c : [Char]
_) | Char -> Bool
isAlphaNum Char
c = []
    strip_th_unique (Char
c : [Char]
cs) = Char
c Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
strip_th_unique [Char]
cs
    strip_th_unique []       = []

{-
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 "GHC.ThToHs"

************************************************************************
*                                                                      *
\subsection{Construction}
*                                                                      *
************************************************************************
-}

mkOccName :: NameSpace -> String -> OccName
mkOccName :: NameSpace -> [Char] -> OccName
mkOccName NameSpace
occ_sp [Char]
str = NameSpace -> FastString -> OccName
OccName NameSpace
occ_sp ([Char] -> FastString
mkFastString [Char]
str)

mkOccNameFS :: NameSpace -> FastString -> OccName
mkOccNameFS :: NameSpace -> FastString -> OccName
mkOccNameFS NameSpace
occ_sp FastString
fs = NameSpace -> FastString -> OccName
OccName NameSpace
occ_sp FastString
fs

mkVarOcc :: String -> OccName
mkVarOcc :: [Char] -> OccName
mkVarOcc [Char]
s = NameSpace -> [Char] -> OccName
mkOccName NameSpace
varName [Char]
s

mkVarOccFS :: FastString -> OccName
mkVarOccFS :: FastString -> OccName
mkVarOccFS FastString
fs = NameSpace -> FastString -> OccName
mkOccNameFS NameSpace
varName FastString
fs

mkDataOcc :: String -> OccName
mkDataOcc :: [Char] -> OccName
mkDataOcc = NameSpace -> [Char] -> OccName
mkOccName NameSpace
dataName

mkDataOccFS :: FastString -> OccName
mkDataOccFS :: FastString -> OccName
mkDataOccFS = NameSpace -> FastString -> OccName
mkOccNameFS NameSpace
dataName

mkTyVarOcc :: String -> OccName
mkTyVarOcc :: [Char] -> OccName
mkTyVarOcc = NameSpace -> [Char] -> OccName
mkOccName NameSpace
tvName

mkTyVarOccFS :: FastString -> OccName
mkTyVarOccFS :: FastString -> OccName
mkTyVarOccFS FastString
fs = NameSpace -> FastString -> OccName
mkOccNameFS NameSpace
tvName FastString
fs

mkTcOcc :: String -> OccName
mkTcOcc :: [Char] -> OccName
mkTcOcc = NameSpace -> [Char] -> OccName
mkOccName NameSpace
tcName

mkTcOccFS :: FastString -> OccName
mkTcOccFS :: FastString -> OccName
mkTcOccFS = NameSpace -> FastString -> OccName
mkOccNameFS NameSpace
tcName

mkClsOcc :: String -> OccName
mkClsOcc :: [Char] -> OccName
mkClsOcc = NameSpace -> [Char] -> OccName
mkOccName NameSpace
clsName

mkClsOccFS :: FastString -> OccName
mkClsOccFS :: FastString -> OccName
mkClsOccFS = NameSpace -> FastString -> OccName
mkOccNameFS NameSpace
clsName

-- demoteOccName lowers the Namespace of OccName.
-- See Note [Demotion] in GHC.Rename.Env.
demoteOccName :: OccName -> Maybe OccName
demoteOccName :: OccName -> Maybe OccName
demoteOccName (OccName NameSpace
space FastString
name) = do
  NameSpace
space' <- NameSpace -> Maybe NameSpace
demoteNameSpace NameSpace
space
  OccName -> Maybe OccName
forall (m :: * -> *) a. Monad m => a -> m a
return (OccName -> Maybe OccName) -> OccName -> Maybe OccName
forall a b. (a -> b) -> a -> b
$ NameSpace -> FastString -> OccName
OccName NameSpace
space' FastString
name

-- promoteOccName promotes the NameSpace of OccName.
-- See Note [Promotion] in GHC.Rename.Env.
promoteOccName :: OccName -> Maybe OccName
promoteOccName :: OccName -> Maybe OccName
promoteOccName (OccName NameSpace
space FastString
name) = do
  NameSpace
space' <- NameSpace -> Maybe NameSpace
promoteNameSpace NameSpace
space
  OccName -> Maybe OccName
forall (m :: * -> *) a. Monad m => a -> m a
return (OccName -> Maybe OccName) -> OccName -> Maybe OccName
forall a b. (a -> b) -> a -> b
$ NameSpace -> FastString -> OccName
OccName NameSpace
space' FastString
name

-- Name spaces are related if there is a chance to mean the one when one writes
-- the other, i.e. variables <-> data constructors and type variables <-> type constructors
nameSpacesRelated :: NameSpace -> NameSpace -> Bool
nameSpacesRelated :: NameSpace -> NameSpace -> Bool
nameSpacesRelated NameSpace
ns1 NameSpace
ns2 = NameSpace
ns1 NameSpace -> NameSpace -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace
ns2 Bool -> Bool -> Bool
|| NameSpace -> NameSpace
otherNameSpace NameSpace
ns1 NameSpace -> NameSpace -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace
ns2

otherNameSpace :: NameSpace -> NameSpace
otherNameSpace :: NameSpace -> NameSpace
otherNameSpace NameSpace
VarName = NameSpace
DataName
otherNameSpace NameSpace
DataName = NameSpace
VarName
otherNameSpace NameSpace
TvName = NameSpace
TcClsName
otherNameSpace NameSpace
TcClsName = NameSpace
TvName



{- | Other names in the compiler add additional information to an OccName.
This class provides a consistent way to access the underlying OccName. -}
class HasOccName name where
  occName :: name -> OccName

{-
************************************************************************
*                                                                      *
                Environments
*                                                                      *
************************************************************************

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, 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 representing the name space.  This in turn makes it
easy to build an OccEnv.
-}

instance Uniquable OccName where
      -- See Note [The Unique of an OccName]
  getUnique :: OccName -> Unique
getUnique (OccName NameSpace
VarName   FastString
fs) = FastString -> Unique
mkVarOccUnique  FastString
fs
  getUnique (OccName NameSpace
DataName  FastString
fs) = FastString -> Unique
mkDataOccUnique FastString
fs
  getUnique (OccName NameSpace
TvName    FastString
fs) = FastString -> Unique
mkTvOccUnique   FastString
fs
  getUnique (OccName NameSpace
TcClsName FastString
fs) = FastString -> Unique
mkTcOccUnique   FastString
fs

newtype OccEnv a = A (UniqFM OccName a)
  deriving Typeable (OccEnv a)
Typeable (OccEnv a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> OccEnv a -> c (OccEnv a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (OccEnv a))
-> (OccEnv a -> Constr)
-> (OccEnv a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (OccEnv a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (OccEnv a)))
-> ((forall b. Data b => b -> b) -> OccEnv a -> OccEnv a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> OccEnv a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> OccEnv a -> r)
-> (forall u. (forall d. Data d => d -> u) -> OccEnv a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> OccEnv a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a))
-> Data (OccEnv a)
OccEnv a -> DataType
OccEnv a -> Constr
(forall b. Data b => b -> b) -> OccEnv a -> OccEnv a
forall {a}. Data a => Typeable (OccEnv a)
forall a. Data a => OccEnv a -> DataType
forall a. Data a => OccEnv a -> Constr
forall a.
Data a =>
(forall b. Data b => b -> b) -> OccEnv a -> OccEnv a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> OccEnv a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> OccEnv a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (OccEnv a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OccEnv a -> c (OccEnv a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (OccEnv a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (OccEnv a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> OccEnv a -> u
forall u. (forall d. Data d => d -> u) -> OccEnv a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (OccEnv a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OccEnv a -> c (OccEnv a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (OccEnv a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (OccEnv a))
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> OccEnv a -> m (OccEnv a)
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> OccEnv a -> u
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> OccEnv a -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> OccEnv a -> [u]
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> OccEnv a -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OccEnv a -> r
gmapT :: (forall b. Data b => b -> b) -> OccEnv a -> OccEnv a
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> OccEnv a -> OccEnv a
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (OccEnv a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (OccEnv a))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (OccEnv a))
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (OccEnv a))
dataTypeOf :: OccEnv a -> DataType
$cdataTypeOf :: forall a. Data a => OccEnv a -> DataType
toConstr :: OccEnv a -> Constr
$ctoConstr :: forall a. Data a => OccEnv a -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (OccEnv a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (OccEnv a)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OccEnv a -> c (OccEnv a)
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OccEnv a -> c (OccEnv a)
Data

emptyOccEnv :: OccEnv a
unitOccEnv  :: OccName -> a -> OccEnv a
extendOccEnv :: OccEnv a -> OccName -> a -> OccEnv a
extendOccEnvList :: OccEnv a -> [(OccName, a)] -> OccEnv a
lookupOccEnv :: OccEnv a -> OccName -> Maybe a
mkOccEnv     :: [(OccName,a)] -> OccEnv a
mkOccEnv_C   :: (a -> a -> a) -> [(OccName,a)] -> OccEnv a
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
delFromOccEnv      :: OccEnv a -> OccName -> OccEnv a
delListFromOccEnv :: OccEnv a -> [OccName] -> OccEnv a
filterOccEnv       :: (elt -> Bool) -> OccEnv elt -> OccEnv elt
alterOccEnv        :: (Maybe elt -> Maybe elt) -> OccEnv elt -> OccName -> OccEnv elt

emptyOccEnv :: forall a. OccEnv a
emptyOccEnv      = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A UniqFM OccName a
forall key elt. UniqFM key elt
emptyUFM
unitOccEnv :: forall a. OccName -> a -> OccEnv a
unitOccEnv OccName
x a
y = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ OccName -> a -> UniqFM OccName a
forall key elt. Uniquable key => key -> elt -> UniqFM key elt
unitUFM OccName
x a
y
extendOccEnv :: forall a. OccEnv a -> OccName -> a -> OccEnv a
extendOccEnv (A UniqFM OccName a
x) OccName
y a
z = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ UniqFM OccName a -> OccName -> a -> UniqFM OccName a
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM UniqFM OccName a
x OccName
y a
z
extendOccEnvList :: forall a. OccEnv a -> [(OccName, a)] -> OccEnv a
extendOccEnvList (A UniqFM OccName a
x) [(OccName, a)]
l = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ UniqFM OccName a -> [(OccName, a)] -> UniqFM OccName a
forall key elt.
Uniquable key =>
UniqFM key elt -> [(key, elt)] -> UniqFM key elt
addListToUFM UniqFM OccName a
x [(OccName, a)]
l
lookupOccEnv :: forall a. OccEnv a -> OccName -> Maybe a
lookupOccEnv (A UniqFM OccName a
x) OccName
y = UniqFM OccName a -> OccName -> Maybe a
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM UniqFM OccName a
x OccName
y
mkOccEnv :: forall a. [(OccName, a)] -> OccEnv a
mkOccEnv     [(OccName, a)]
l    = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ [(OccName, a)] -> UniqFM OccName a
forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
listToUFM [(OccName, a)]
l
elemOccEnv :: forall a. OccName -> OccEnv a -> Bool
elemOccEnv OccName
x (A UniqFM OccName a
y)       = OccName -> UniqFM OccName a -> Bool
forall key elt. Uniquable key => key -> UniqFM key elt -> Bool
elemUFM OccName
x UniqFM OccName a
y
foldOccEnv :: forall a b. (a -> b -> b) -> b -> OccEnv a -> b
foldOccEnv a -> b -> b
a b
b (A UniqFM OccName a
c)     = (a -> b -> b) -> b -> UniqFM OccName a -> b
forall elt a key. (elt -> a -> a) -> a -> UniqFM key elt -> a
foldUFM a -> b -> b
a b
b UniqFM OccName a
c
occEnvElts :: forall a. OccEnv a -> [a]
occEnvElts (A UniqFM OccName a
x)         = UniqFM OccName a -> [a]
forall key elt. UniqFM key elt -> [elt]
eltsUFM UniqFM OccName a
x
plusOccEnv :: forall a. OccEnv a -> OccEnv a -> OccEnv a
plusOccEnv (A UniqFM OccName a
x) (A UniqFM OccName a
y)   = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ UniqFM OccName a -> UniqFM OccName a -> UniqFM OccName a
forall key elt. UniqFM key elt -> UniqFM key elt -> UniqFM key elt
plusUFM UniqFM OccName a
x UniqFM OccName a
y
plusOccEnv_C :: forall a. (a -> a -> a) -> OccEnv a -> OccEnv a -> OccEnv a
plusOccEnv_C a -> a -> a
f (A UniqFM OccName a
x) (A UniqFM OccName a
y)       = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ (a -> a -> a)
-> UniqFM OccName a -> UniqFM OccName a -> UniqFM OccName a
forall elt key.
(elt -> elt -> elt)
-> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
plusUFM_C a -> a -> a
f UniqFM OccName a
x UniqFM OccName a
y
extendOccEnv_C :: forall a. (a -> a -> a) -> OccEnv a -> OccName -> a -> OccEnv a
extendOccEnv_C a -> a -> a
f (A UniqFM OccName a
x) OccName
y a
z   = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ (a -> a -> a)
-> UniqFM OccName a -> OccName -> a -> UniqFM OccName a
forall key elt.
Uniquable key =>
(elt -> elt -> elt)
-> UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM_C a -> a -> a
f UniqFM OccName a
x OccName
y a
z
extendOccEnv_Acc :: forall a b.
(a -> b -> b) -> (a -> b) -> OccEnv b -> OccName -> a -> OccEnv b
extendOccEnv_Acc a -> b -> b
f a -> b
g (A UniqFM OccName b
x) OccName
y a
z   = UniqFM OccName b -> OccEnv b
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName b -> OccEnv b) -> UniqFM OccName b -> OccEnv b
forall a b. (a -> b) -> a -> b
$ (a -> b -> b)
-> (a -> b) -> UniqFM OccName b -> OccName -> a -> UniqFM OccName b
forall key elt elts.
Uniquable key =>
(elt -> elts -> elts)
-> (elt -> elts)
-> UniqFM key elts
-> key
-> elt
-> UniqFM key elts
addToUFM_Acc a -> b -> b
f a -> b
g UniqFM OccName b
x OccName
y a
z
mapOccEnv :: forall a b. (a -> b) -> OccEnv a -> OccEnv b
mapOccEnv a -> b
f (A UniqFM OccName a
x)        = UniqFM OccName b -> OccEnv b
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName b -> OccEnv b) -> UniqFM OccName b -> OccEnv b
forall a b. (a -> b) -> a -> b
$ (a -> b) -> UniqFM OccName a -> UniqFM OccName b
forall elt1 elt2 key.
(elt1 -> elt2) -> UniqFM key elt1 -> UniqFM key elt2
mapUFM a -> b
f UniqFM OccName a
x
mkOccEnv_C :: forall a. (a -> a -> a) -> [(OccName, a)] -> OccEnv a
mkOccEnv_C a -> a -> a
comb [(OccName, a)]
l = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ (a -> a -> a)
-> UniqFM OccName a -> [(OccName, a)] -> UniqFM OccName a
forall key elt.
Uniquable key =>
(elt -> elt -> elt)
-> UniqFM key elt -> [(key, elt)] -> UniqFM key elt
addListToUFM_C a -> a -> a
comb UniqFM OccName a
forall key elt. UniqFM key elt
emptyUFM [(OccName, a)]
l
delFromOccEnv :: forall a. OccEnv a -> OccName -> OccEnv a
delFromOccEnv (A UniqFM OccName a
x) OccName
y    = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ UniqFM OccName a -> OccName -> UniqFM OccName a
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> UniqFM key elt
delFromUFM UniqFM OccName a
x OccName
y
delListFromOccEnv :: forall a. OccEnv a -> [OccName] -> OccEnv a
delListFromOccEnv (A UniqFM OccName a
x) [OccName]
y  = UniqFM OccName a -> OccEnv a
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName a -> OccEnv a) -> UniqFM OccName a -> OccEnv a
forall a b. (a -> b) -> a -> b
$ UniqFM OccName a -> [OccName] -> UniqFM OccName a
forall key elt.
Uniquable key =>
UniqFM key elt -> [key] -> UniqFM key elt
delListFromUFM UniqFM OccName a
x [OccName]
y
filterOccEnv :: forall elt. (elt -> Bool) -> OccEnv elt -> OccEnv elt
filterOccEnv elt -> Bool
x (A UniqFM OccName elt
y)       = UniqFM OccName elt -> OccEnv elt
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName elt -> OccEnv elt)
-> UniqFM OccName elt -> OccEnv elt
forall a b. (a -> b) -> a -> b
$ (elt -> Bool) -> UniqFM OccName elt -> UniqFM OccName elt
forall elt key. (elt -> Bool) -> UniqFM key elt -> UniqFM key elt
filterUFM elt -> Bool
x UniqFM OccName elt
y
alterOccEnv :: forall elt.
(Maybe elt -> Maybe elt) -> OccEnv elt -> OccName -> OccEnv elt
alterOccEnv Maybe elt -> Maybe elt
fn (A UniqFM OccName elt
y) OccName
k     = UniqFM OccName elt -> OccEnv elt
forall a. UniqFM OccName a -> OccEnv a
A (UniqFM OccName elt -> OccEnv elt)
-> UniqFM OccName elt -> OccEnv elt
forall a b. (a -> b) -> a -> b
$ (Maybe elt -> Maybe elt)
-> UniqFM OccName elt -> OccName -> UniqFM OccName elt
forall key elt.
Uniquable key =>
(Maybe elt -> Maybe elt) -> UniqFM key elt -> key -> UniqFM key elt
alterUFM Maybe elt -> Maybe elt
fn UniqFM OccName elt
y OccName
k

instance Outputable a => Outputable (OccEnv a) where
    ppr :: OccEnv a -> SDoc
ppr OccEnv a
x = (a -> SDoc) -> OccEnv a -> SDoc
forall a. (a -> SDoc) -> OccEnv a -> SDoc
pprOccEnv a -> SDoc
forall a. Outputable a => a -> SDoc
ppr OccEnv a
x

pprOccEnv :: (a -> SDoc) -> OccEnv a -> SDoc
pprOccEnv :: forall a. (a -> SDoc) -> OccEnv a -> SDoc
pprOccEnv a -> SDoc
ppr_elt (A UniqFM OccName a
env) = (a -> SDoc) -> UniqFM OccName a -> SDoc
forall a key. (a -> SDoc) -> UniqFM key a -> SDoc
pprUniqFM a -> SDoc
ppr_elt UniqFM OccName a
env

type OccSet = UniqSet OccName

emptyOccSet       :: OccSet
unitOccSet        :: OccName -> OccSet
mkOccSet          :: [OccName] -> OccSet
extendOccSet      :: OccSet -> OccName -> OccSet
extendOccSetList  :: OccSet -> [OccName] -> OccSet
unionOccSets      :: OccSet -> OccSet -> OccSet
unionManyOccSets  :: [OccSet] -> OccSet
minusOccSet       :: OccSet -> OccSet -> OccSet
elemOccSet        :: OccName -> OccSet -> Bool
isEmptyOccSet     :: OccSet -> Bool
intersectOccSet   :: OccSet -> OccSet -> OccSet
filterOccSet      :: (OccName -> Bool) -> OccSet -> OccSet

emptyOccSet :: OccSet
emptyOccSet       = OccSet
forall a. UniqSet a
emptyUniqSet
unitOccSet :: OccName -> OccSet
unitOccSet        = OccName -> OccSet
forall a. Uniquable a => a -> UniqSet a
unitUniqSet
mkOccSet :: [OccName] -> OccSet
mkOccSet          = [OccName] -> OccSet
forall a. Uniquable a => [a] -> UniqSet a
mkUniqSet
extendOccSet :: OccSet -> OccName -> OccSet
extendOccSet      = OccSet -> OccName -> OccSet
forall a. Uniquable a => UniqSet a -> a -> UniqSet a
addOneToUniqSet
extendOccSetList :: OccSet -> [OccName] -> OccSet
extendOccSetList  = OccSet -> [OccName] -> OccSet
forall a. Uniquable a => UniqSet a -> [a] -> UniqSet a
addListToUniqSet
unionOccSets :: OccSet -> OccSet -> OccSet
unionOccSets      = OccSet -> OccSet -> OccSet
forall a. UniqSet a -> UniqSet a -> UniqSet a
unionUniqSets
unionManyOccSets :: [OccSet] -> OccSet
unionManyOccSets  = [OccSet] -> OccSet
forall a. [UniqSet a] -> UniqSet a
unionManyUniqSets
minusOccSet :: OccSet -> OccSet -> OccSet
minusOccSet       = OccSet -> OccSet -> OccSet
forall a. UniqSet a -> UniqSet a -> UniqSet a
minusUniqSet
elemOccSet :: OccName -> OccSet -> Bool
elemOccSet        = OccName -> OccSet -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
elementOfUniqSet
isEmptyOccSet :: OccSet -> Bool
isEmptyOccSet     = OccSet -> Bool
forall a. UniqSet a -> Bool
isEmptyUniqSet
intersectOccSet :: OccSet -> OccSet -> OccSet
intersectOccSet   = OccSet -> OccSet -> OccSet
forall a. UniqSet a -> UniqSet a -> UniqSet a
intersectUniqSets
filterOccSet :: (OccName -> Bool) -> OccSet -> OccSet
filterOccSet      = (OccName -> Bool) -> OccSet -> OccSet
forall a. (a -> Bool) -> UniqSet a -> UniqSet a
filterUniqSet

{-
************************************************************************
*                                                                      *
\subsection{Predicates and taking them apart}
*                                                                      *
************************************************************************
-}

occNameString :: OccName -> String
occNameString :: OccName -> [Char]
occNameString (OccName NameSpace
_ FastString
s) = FastString -> [Char]
unpackFS FastString
s

setOccNameSpace :: NameSpace -> OccName -> OccName
setOccNameSpace :: NameSpace -> OccName -> OccName
setOccNameSpace NameSpace
sp (OccName NameSpace
_ FastString
occ) = NameSpace -> FastString -> OccName
OccName NameSpace
sp FastString
occ

isVarOcc, isTvOcc, isTcOcc, isDataOcc :: OccName -> Bool

isVarOcc :: OccName -> Bool
isVarOcc (OccName NameSpace
VarName FastString
_) = Bool
True
isVarOcc OccName
_                   = Bool
False

isTvOcc :: OccName -> Bool
isTvOcc (OccName NameSpace
TvName FastString
_) = Bool
True
isTvOcc OccName
_                  = Bool
False

isTcOcc :: OccName -> Bool
isTcOcc (OccName NameSpace
TcClsName FastString
_) = Bool
True
isTcOcc OccName
_                     = Bool
False

-- | /Value/ 'OccNames's are those that are either in
-- the variable or data constructor namespaces
isValOcc :: OccName -> Bool
isValOcc :: OccName -> Bool
isValOcc (OccName NameSpace
VarName  FastString
_) = Bool
True
isValOcc (OccName NameSpace
DataName FastString
_) = Bool
True
isValOcc OccName
_                    = Bool
False

isDataOcc :: OccName -> Bool
isDataOcc (OccName NameSpace
DataName FastString
_) = Bool
True
isDataOcc OccName
_                    = Bool
False

-- | Test if the 'OccName' is a data constructor that starts with
-- a symbol (e.g. @:@, or @[]@)
isDataSymOcc :: OccName -> Bool
isDataSymOcc :: OccName -> Bool
isDataSymOcc (OccName NameSpace
DataName FastString
s) = FastString -> Bool
isLexConSym FastString
s
isDataSymOcc OccName
_                    = Bool
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 -> Bool
isSymOcc (OccName NameSpace
DataName FastString
s)  = FastString -> Bool
isLexConSym FastString
s
isSymOcc (OccName NameSpace
TcClsName FastString
s) = FastString -> Bool
isLexSym FastString
s
isSymOcc (OccName NameSpace
VarName FastString
s)   = FastString -> Bool
isLexSym FastString
s
isSymOcc (OccName NameSpace
TvName FastString
s)    = FastString -> Bool
isLexSym FastString
s
-- Pretty inefficient!

parenSymOcc :: OccName -> SDoc -> SDoc
-- ^ Wrap parens around an operator
parenSymOcc :: OccName -> SDoc -> SDoc
parenSymOcc OccName
occ SDoc
doc | OccName -> Bool
isSymOcc OccName
occ = SDoc -> SDoc
parens SDoc
doc
                    | Bool
otherwise    = SDoc
doc

startsWithUnderscore :: OccName -> Bool
-- ^ Haskell 98 encourages compilers to suppress warnings about unused
-- names in a pattern if they start with @_@: this implements that test
startsWithUnderscore :: OccName -> Bool
startsWithUnderscore OccName
occ = FastString -> Char
headFS (OccName -> FastString
occNameFS OccName
occ) Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_'

{-
************************************************************************
*                                                                      *
\subsection{Making system names}
*                                                                      *
************************************************************************

Here's our convention for splitting up the interface file name space:

   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)
   $dmop        Default method for 'op'
   $pnC         n'th superclass selector for class C
   $wf          Worker for function 'f'
   $sf..        Specialised version of f
   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 representation type R

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!
-}

-- | Build an 'OccName' derived from another 'OccName'.
--
-- Note that the pieces of the name are passed in as a @[FastString]@ so that
-- the whole name can be constructed with a single 'concatFS', minimizing
-- unnecessary intermediate allocations.
mk_deriv :: NameSpace
         -> FastString      -- ^ A prefix which distinguishes one sort of
                            -- derived name from another
         -> [FastString]    -- ^ The name we are deriving from in pieces which
                            -- will be concatenated.
         -> OccName
mk_deriv :: NameSpace -> FastString -> [FastString] -> OccName
mk_deriv NameSpace
occ_sp FastString
sys_prefix [FastString]
str =
    NameSpace -> FastString -> OccName
mkOccNameFS NameSpace
occ_sp ([FastString] -> FastString
concatFS ([FastString] -> FastString) -> [FastString] -> FastString
forall a b. (a -> b) -> a -> b
$ FastString
sys_prefix FastString -> [FastString] -> [FastString]
forall a. a -> [a] -> [a]
: [FastString]
str)

isDerivedOccName :: OccName -> Bool
-- ^ Test for definitions internally generated by GHC.  This predicate
-- is used to suppress printing of internal definitions in some debug prints
isDerivedOccName :: OccName -> Bool
isDerivedOccName OccName
occ =
   case OccName -> [Char]
occNameString OccName
occ of
     Char
'$':Char
c:[Char]
_ | Char -> Bool
isAlphaNum Char
c -> Bool
True   -- E.g.  $wfoo
     Char
c:Char
':':[Char]
_ | Char -> Bool
isAlphaNum Char
c -> Bool
True   -- E.g.  N:blah   newtype coercions
     [Char]
_other                 -> Bool
False

isDefaultMethodOcc :: OccName -> Bool
isDefaultMethodOcc :: OccName -> Bool
isDefaultMethodOcc OccName
occ =
   case OccName -> [Char]
occNameString OccName
occ of
     Char
'$':Char
'd':Char
'm':[Char]
_ -> Bool
True
     [Char]
_ -> Bool
False

-- | Is an 'OccName' one of a Typeable @TyCon@ or @Module@ binding?
-- This is needed as these bindings are renamed differently.
-- See Note [Grand plan for Typeable] in "GHC.Tc.Instance.Typeable".
isTypeableBindOcc :: OccName -> Bool
isTypeableBindOcc :: OccName -> Bool
isTypeableBindOcc OccName
occ =
   case OccName -> [Char]
occNameString OccName
occ of
     Char
'$':Char
't':Char
'c':[Char]
_ -> Bool
True  -- mkTyConRepOcc
     Char
'$':Char
't':Char
'r':[Char]
_ -> Bool
True  -- Module binding
     [Char]
_ -> Bool
False

mkDataConWrapperOcc, mkWorkerOcc,
        mkMatcherOcc, mkBuilderOcc,
        mkDefaultMethodOcc,
        mkClassDataConOcc, mkDictOcc,
        mkIPOcc, mkSpecOcc, mkForeignExportOcc, mkRepEqOcc,
        mkGenR, mkGen1R,
        mkDataConWorkerOcc, mkNewTyCoOcc,
        mkInstTyCoOcc, mkEqPredCoOcc, mkClassOpAuxOcc,
        mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc, mkDataTOcc, mkDataCOcc,
        mkTyConRepOcc
   :: OccName -> OccName

-- These derived variables have a prefix that no Haskell value could have
mkDataConWrapperOcc :: OccName -> OccName
mkDataConWrapperOcc = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$W"
mkWorkerOcc :: OccName -> OccName
mkWorkerOcc         = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$w"
mkMatcherOcc :: OccName -> OccName
mkMatcherOcc        = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$m"
mkBuilderOcc :: OccName -> OccName
mkBuilderOcc        = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$b"
mkDefaultMethodOcc :: OccName -> OccName
mkDefaultMethodOcc  = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$dm"
mkClassOpAuxOcc :: OccName -> OccName
mkClassOpAuxOcc     = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$c"
mkDictOcc :: OccName -> OccName
mkDictOcc           = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$d"
mkIPOcc :: OccName -> OccName
mkIPOcc             = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$i"
mkSpecOcc :: OccName -> OccName
mkSpecOcc           = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$s"
mkForeignExportOcc :: OccName -> OccName
mkForeignExportOcc  = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$f"
mkRepEqOcc :: OccName -> OccName
mkRepEqOcc          = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
tvName   FastString
"$r"   -- In RULES involving Coercible
mkClassDataConOcc :: OccName -> OccName
mkClassDataConOcc   = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
dataName FastString
"C:"   -- Data con for a class
mkNewTyCoOcc :: OccName -> OccName
mkNewTyCoOcc        = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
tcName   FastString
"N:"   -- Coercion for newtypes
mkInstTyCoOcc :: OccName -> OccName
mkInstTyCoOcc       = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
tcName   FastString
"D:"   -- Coercion for type functions
mkEqPredCoOcc :: OccName -> OccName
mkEqPredCoOcc       = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
tcName   FastString
"$co"

-- Used in derived instances for the names of auxiliary bindings.
-- See Note [Auxiliary binders] in GHC.Tc.Deriv.Generate.
mkCon2TagOcc :: OccName -> OccName
mkCon2TagOcc        = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$con2tag_"
mkTag2ConOcc :: OccName -> OccName
mkTag2ConOcc        = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$tag2con_"
mkMaxTagOcc :: OccName -> OccName
mkMaxTagOcc         = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$maxtag_"
mkDataTOcc :: OccName -> OccName
mkDataTOcc          = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$t"
mkDataCOcc :: OccName -> OccName
mkDataCOcc          = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName  FastString
"$c"

-- TyConRepName stuff; see Note [Grand plan for Typeable] in GHC.Tc.Instance.Typeable
mkTyConRepOcc :: OccName -> OccName
mkTyConRepOcc OccName
occ = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName FastString
prefix OccName
occ
  where
    prefix :: FastString
prefix | OccName -> Bool
isDataOcc OccName
occ = FastString
"$tc'"
           | Bool
otherwise     = FastString
"$tc"

-- Generic deriving mechanism
mkGenR :: OccName -> OccName
mkGenR   = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
tcName FastString
"Rep_"
mkGen1R :: OccName -> OccName
mkGen1R  = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
tcName FastString
"Rep1_"

-- Overloaded record field selectors
mkRecFldSelOcc :: String -> OccName
mkRecFldSelOcc :: [Char] -> OccName
mkRecFldSelOcc [Char]
s = NameSpace -> FastString -> [FastString] -> OccName
mk_deriv NameSpace
varName FastString
"$sel" [[Char] -> FastString
fsLit [Char]
s]

mk_simple_deriv :: NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv :: NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
sp FastString
px OccName
occ = NameSpace -> FastString -> [FastString] -> OccName
mk_deriv NameSpace
sp FastString
px [OccName -> FastString
occNameFS OccName
occ]

-- Data constructor workers are made by setting the name space
-- of the data constructor OccName (which should be a DataName)
-- to VarName
mkDataConWorkerOcc :: OccName -> OccName
mkDataConWorkerOcc OccName
datacon_occ = NameSpace -> OccName -> OccName
setOccNameSpace NameSpace
varName OccName
datacon_occ

mkSuperDictAuxOcc :: Int -> OccName -> OccName
mkSuperDictAuxOcc :: Int -> OccName -> OccName
mkSuperDictAuxOcc Int
index OccName
cls_tc_occ
  = NameSpace -> FastString -> [FastString] -> OccName
mk_deriv NameSpace
varName FastString
"$cp" [[Char] -> FastString
fsLit ([Char] -> FastString) -> [Char] -> FastString
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
index, OccName -> FastString
occNameFS OccName
cls_tc_occ]

mkSuperDictSelOcc :: Int        -- ^ Index of superclass, e.g. 3
                  -> OccName    -- ^ Class, e.g. @Ord@
                  -> OccName    -- ^ Derived 'Occname', e.g. @$p3Ord@
mkSuperDictSelOcc :: Int -> OccName -> OccName
mkSuperDictSelOcc Int
index OccName
cls_tc_occ
  = NameSpace -> FastString -> [FastString] -> OccName
mk_deriv NameSpace
varName FastString
"$p" [[Char] -> FastString
fsLit ([Char] -> FastString) -> [Char] -> FastString
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
index, OccName -> FastString
occNameFS OccName
cls_tc_occ]

mkLocalOcc :: Unique            -- ^ Unique to combine with the 'OccName'
           -> OccName           -- ^ Local name, e.g. @sat@
           -> OccName           -- ^ Nice unique version, e.g. @$L23sat@
mkLocalOcc :: Unique -> OccName -> OccName
mkLocalOcc Unique
uniq OccName
occ
   = NameSpace -> FastString -> [FastString] -> OccName
mk_deriv NameSpace
varName FastString
"$L" [[Char] -> FastString
fsLit ([Char] -> FastString) -> [Char] -> FastString
forall a b. (a -> b) -> a -> b
$ Unique -> [Char]
forall a. Show a => a -> [Char]
show Unique
uniq, OccName -> FastString
occNameFS OccName
occ]
        -- The Unique might print with characters
        -- that need encoding (e.g. 'z'!)

-- | 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 :: [Char] -> OccSet -> OccName
mkInstTyTcOcc [Char]
str = NameSpace -> [Char] -> OccSet -> OccName
chooseUniqueOcc NameSpace
tcName (Char
'R' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
':' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
str)

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?
          -> 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 :: [Char] -> Bool -> OccSet -> OccName
mkDFunOcc [Char]
info_str Bool
is_boot OccSet
set
  = NameSpace -> [Char] -> OccSet -> OccName
chooseUniqueOcc NameSpace
VarName ([Char]
prefix [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
info_str) OccSet
set
  where
    prefix :: [Char]
prefix | Bool
is_boot   = [Char]
"$fx"
           | Bool
otherwise = [Char]
"$f"

{-
Sometimes we need to pick an OccName that has not already been used,
given a set of in-use OccNames.
-}

chooseUniqueOcc :: NameSpace -> String -> OccSet -> OccName
chooseUniqueOcc :: NameSpace -> [Char] -> OccSet -> OccName
chooseUniqueOcc NameSpace
ns [Char]
str OccSet
set = OccName -> Int -> OccName
loop (NameSpace -> [Char] -> OccName
mkOccName NameSpace
ns [Char]
str) (Int
0::Int)
  where
  loop :: OccName -> Int -> OccName
loop OccName
occ Int
n
   | OccName
occ OccName -> OccSet -> Bool
`elemOccSet` OccSet
set = OccName -> Int -> OccName
loop (NameSpace -> [Char] -> OccName
mkOccName NameSpace
ns ([Char]
str [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n)) (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
   | Bool
otherwise            = OccName
occ

{-
We used to add a '$m' to indicate a method, but that gives rise to bad
error messages from the type checker when we print the function name or pattern
of an instance-decl binding.  Why? Because the binding is zapped
to use the method name in place of the selector name.
(See GHC.Tc.TyCl.Class.tcMethodBind)

The way it is now, -ddump-xx output may look confusing, but
you can always say -dppr-debug to get the uniques.

However, we *do* have to zap the first character to be lower case,
because overloaded constructors (blarg) generate methods too.
And convert to VarName space

e.g. a call to constructor MkFoo where
        data (Ord a) => Foo a = MkFoo a

If this is necessary, we do it by prefixing '$m'.  These
guys never show up in error messages.  What a hack.
-}

mkMethodOcc :: OccName -> OccName
mkMethodOcc :: OccName -> OccName
mkMethodOcc occ :: OccName
occ@(OccName NameSpace
VarName FastString
_) = OccName
occ
mkMethodOcc OccName
occ                     = NameSpace -> FastString -> OccName -> OccName
mk_simple_deriv NameSpace
varName FastString
"$m" OccName
occ

{-
************************************************************************
*                                                                      *
\subsection{Tidying them up}
*                                                                      *
************************************************************************

Before we print chunks of code we like to rename it so that
we don't have to print lots of silly uniques in it.  But we mustn't
accidentally introduce name clashes!  So the idea is that we leave the
OccName alone unless it accidentally clashes with one that is already
in scope; if so, we tack on '1' at the end and try again, then '2', and
so on till we find a unique one.

There's a wrinkle for operators.  Consider '>>='.  We can't use '>>=1'
because that isn't a single lexeme.  So we encode it to 'lle' and *then*
tack on the '1', if necessary.

Note [TidyOccEnv]
~~~~~~~~~~~~~~~~~
type TidyOccEnv = UniqFM Int

* Domain = The OccName's FastString. These FastStrings are "taken";
           make sure that we don't re-use

* Int, n = A plausible starting point for new guesses
           There is no guarantee that "FSn" is available;
           you must look that up in the TidyOccEnv.  But
           it's a good place to start looking.

* When looking for a renaming for "foo2" we strip off the "2" and start
  with "foo".  Otherwise if we tidy twice we get silly names like foo23.

  However, if it started with digits at the end, we always make a name
  with digits at the end, rather than shortening "foo2" to just "foo",
  even if "foo" is unused.  Reasons:
     - Plain "foo" might be used later
     - We use trailing digits to subtly indicate a unification variable
       in typechecker error message; see TypeRep.tidyTyVarBndr

We have to take care though! Consider a machine-generated module (#10370)
  module Foo where
     a1 = e1
     a2 = e2
     ...
     a2000 = e2000
Then "a1", "a2" etc are all marked taken.  But now if we come across "a7" again,
we have to do a linear search to find a free one, "a2001".  That might just be
acceptable once.  But if we now come across "a8" again, we don't want to repeat
that search.

So we use the TidyOccEnv mapping for "a" (not "a7" or "a8") as our base for
starting the search; and we make sure to update the starting point for "a"
after we allocate a new one.


Note [Tidying multiple names at once]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Consider

    > :t (id,id,id)

Every id contributes a type variable to the type signature, and all of them are
"a". If we tidy them one by one, we get

    (id,id,id) :: (a2 -> a2, a1 -> a1, a -> a)

which is a bit unfortunate, as it unfairly renames only two of them. What we
would like to see is

    (id,id,id) :: (a3 -> a3, a2 -> a2, a1 -> a1)

To achieve this, the function avoidClashesOccEnv can be used to prepare the
TidyEnv, by “blocking” every name that occurs twice in the map. This way, none
of the "a"s will get the privilege of keeping this name, and all of them will
get a suitable number by tidyOccName.

This prepared TidyEnv can then be used with tidyOccName. See tidyTyCoVarBndrs
for an example where this is used.

This is #12382.

-}

type TidyOccEnv = UniqFM FastString Int    -- The in-scope OccNames
  -- See Note [TidyOccEnv]

emptyTidyOccEnv :: TidyOccEnv
emptyTidyOccEnv :: TidyOccEnv
emptyTidyOccEnv = TidyOccEnv
forall key elt. UniqFM key elt
emptyUFM

initTidyOccEnv :: [OccName] -> TidyOccEnv       -- Initialise with names to avoid!
initTidyOccEnv :: [OccName] -> TidyOccEnv
initTidyOccEnv = (TidyOccEnv -> OccName -> TidyOccEnv)
-> TidyOccEnv -> [OccName] -> TidyOccEnv
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' TidyOccEnv -> OccName -> TidyOccEnv
forall {elt}.
Num elt =>
UniqFM FastString elt -> OccName -> UniqFM FastString elt
add TidyOccEnv
forall key elt. UniqFM key elt
emptyUFM
  where
    add :: UniqFM FastString elt -> OccName -> UniqFM FastString elt
add UniqFM FastString elt
env (OccName NameSpace
_ FastString
fs) = UniqFM FastString elt -> FastString -> elt -> UniqFM FastString elt
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM UniqFM FastString elt
env FastString
fs elt
1

delTidyOccEnvList :: TidyOccEnv -> [FastString] -> TidyOccEnv
delTidyOccEnvList :: TidyOccEnv -> [FastString] -> TidyOccEnv
delTidyOccEnvList = TidyOccEnv -> [FastString] -> TidyOccEnv
forall key elt.
Uniquable key =>
UniqFM key elt -> [key] -> UniqFM key elt
delListFromUFM

-- see Note [Tidying multiple names at once]
avoidClashesOccEnv :: TidyOccEnv -> [OccName] -> TidyOccEnv
avoidClashesOccEnv :: TidyOccEnv -> [OccName] -> TidyOccEnv
avoidClashesOccEnv TidyOccEnv
env [OccName]
occs = TidyOccEnv -> UniqFM FastString () -> [OccName] -> TidyOccEnv
forall {elt}.
Num elt =>
UniqFM FastString elt
-> UniqFM FastString () -> [OccName] -> UniqFM FastString elt
go TidyOccEnv
env UniqFM FastString ()
forall key elt. UniqFM key elt
emptyUFM [OccName]
occs
  where
    go :: UniqFM FastString elt
-> UniqFM FastString () -> [OccName] -> UniqFM FastString elt
go UniqFM FastString elt
env UniqFM FastString ()
_        [] = UniqFM FastString elt
env
    go UniqFM FastString elt
env UniqFM FastString ()
seenOnce ((OccName NameSpace
_ FastString
fs):[OccName]
occs)
      | FastString
fs FastString -> UniqFM FastString elt -> Bool
forall key elt. Uniquable key => key -> UniqFM key elt -> Bool
`elemUFM` UniqFM FastString elt
env      = UniqFM FastString elt
-> UniqFM FastString () -> [OccName] -> UniqFM FastString elt
go UniqFM FastString elt
env UniqFM FastString ()
seenOnce                  [OccName]
occs
      | FastString
fs FastString -> UniqFM FastString () -> Bool
forall key elt. Uniquable key => key -> UniqFM key elt -> Bool
`elemUFM` UniqFM FastString ()
seenOnce = UniqFM FastString elt
-> UniqFM FastString () -> [OccName] -> UniqFM FastString elt
go (UniqFM FastString elt -> FastString -> elt -> UniqFM FastString elt
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM UniqFM FastString elt
env FastString
fs elt
1) UniqFM FastString ()
seenOnce  [OccName]
occs
      | Bool
otherwise             = UniqFM FastString elt
-> UniqFM FastString () -> [OccName] -> UniqFM FastString elt
go UniqFM FastString elt
env (UniqFM FastString () -> FastString -> () -> UniqFM FastString ()
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM UniqFM FastString ()
seenOnce FastString
fs ()) [OccName]
occs

tidyOccName :: TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
tidyOccName :: TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
tidyOccName TidyOccEnv
env occ :: OccName
occ@(OccName NameSpace
occ_sp FastString
fs)
  | Bool -> Bool
not (FastString
fs FastString -> TidyOccEnv -> Bool
forall key elt. Uniquable key => key -> UniqFM key elt -> Bool
`elemUFM` TidyOccEnv
env)
  = -- Desired OccName is free, so use it,
    -- and record in 'env' that it's no longer available
    (TidyOccEnv -> FastString -> Int -> TidyOccEnv
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM TidyOccEnv
env FastString
fs Int
1, OccName
occ)

  | Bool
otherwise
  = case TidyOccEnv -> FastString -> Maybe Int
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM TidyOccEnv
env FastString
base1 of
       Maybe Int
Nothing -> (TidyOccEnv -> FastString -> Int -> TidyOccEnv
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM TidyOccEnv
env FastString
base1 Int
2, NameSpace -> FastString -> OccName
OccName NameSpace
occ_sp FastString
base1)
       Just Int
n  -> Int -> Int -> (TidyOccEnv, OccName)
find Int
1 Int
n
  where
    base :: String  -- Drop trailing digits (see Note [TidyOccEnv])
    base :: [Char]
base  = (Char -> Bool) -> [Char] -> [Char]
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEndLE Char -> Bool
isDigit (FastString -> [Char]
unpackFS FastString
fs)
    base1 :: FastString
base1 = [Char] -> FastString
mkFastString ([Char]
base [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"1")

    find :: Int -> Int -> (TidyOccEnv, OccName)
find !Int
k !Int
n
      = case TidyOccEnv -> FastString -> Maybe Int
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM TidyOccEnv
env FastString
new_fs of
          Just {} -> Int -> Int -> (TidyOccEnv, OccName)
find (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1 :: Int) (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
k)
                       -- By using n+k, the n argument to find goes
                       --    1, add 1, add 2, add 3, etc which
                       -- moves at quadratic speed through a dense patch

          Maybe Int
Nothing -> (TidyOccEnv
new_env, NameSpace -> FastString -> OccName
OccName NameSpace
occ_sp FastString
new_fs)
       where
         new_fs :: FastString
new_fs = [Char] -> FastString
mkFastString ([Char]
base [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n)
         new_env :: TidyOccEnv
new_env = TidyOccEnv -> FastString -> Int -> TidyOccEnv
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM (TidyOccEnv -> FastString -> Int -> TidyOccEnv
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM TidyOccEnv
env FastString
new_fs Int
1) FastString
base1 (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
                     -- Update:  base1,  so that next time we'll start where we left off
                     --          new_fs, so that we know it is taken
                     -- If they are the same (n==1), the former wins
                     -- See Note [TidyOccEnv]


{-
************************************************************************
*                                                                      *
                Binary instance
    Here rather than in GHC.Iface.Binary because OccName is abstract
*                                                                      *
************************************************************************
-}

instance Binary NameSpace where
    put_ :: BinHandle -> NameSpace -> IO ()
put_ BinHandle
bh NameSpace
VarName =
            BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
    put_ BinHandle
bh NameSpace
DataName =
            BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
    put_ BinHandle
bh NameSpace
TvName =
            BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
2
    put_ BinHandle
bh NameSpace
TcClsName =
            BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
3
    get :: BinHandle -> IO NameSpace
get BinHandle
bh = do
            Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
            case Word8
h of
              Word8
0 -> NameSpace -> IO NameSpace
forall (m :: * -> *) a. Monad m => a -> m a
return NameSpace
VarName
              Word8
1 -> NameSpace -> IO NameSpace
forall (m :: * -> *) a. Monad m => a -> m a
return NameSpace
DataName
              Word8
2 -> NameSpace -> IO NameSpace
forall (m :: * -> *) a. Monad m => a -> m a
return NameSpace
TvName
              Word8
_ -> NameSpace -> IO NameSpace
forall (m :: * -> *) a. Monad m => a -> m a
return NameSpace
TcClsName

instance Binary OccName where
    put_ :: BinHandle -> OccName -> IO ()
put_ BinHandle
bh (OccName NameSpace
aa FastString
ab) = do
            BinHandle -> NameSpace -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh NameSpace
aa
            BinHandle -> FastString -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh FastString
ab
    get :: BinHandle -> IO OccName
get BinHandle
bh = do
          NameSpace
aa <- BinHandle -> IO NameSpace
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
          FastString
ab <- BinHandle -> IO FastString
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
          OccName -> IO OccName
forall (m :: * -> *) a. Monad m => a -> m a
return (NameSpace -> FastString -> OccName
OccName NameSpace
aa FastString
ab)