    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE RecordWildCards   #-}
    {-# LANGUAGE TypeFamilies      #-}

    {-# OPTIONS_GHC -Wno-orphans #-} -- instance NFData FieldLabel

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

    \section[Name]{@Name@: to transmit name info from renamer to typechecker}
    -}

    -- |
    -- #name_types#
    -- GHC uses several kinds of name internally:
    --
    -- * 'GHC.Types.Name.Occurrence.OccName': see "GHC.Types.Name.Occurrence#name_types"
    --
    -- * 'GHC.Types.Name.Reader.RdrName': see "GHC.Types.Name.Reader#name_types"
    --
    -- * 'GHC.Types.Name.Name' is the type of names that have had their scoping and
    --   binding resolved. They have an 'OccName' but also a 'GHC.Types.Unique.Unique'
    --   that disambiguates Names that have the same 'OccName' and indeed is used for all
    --   'Name' comparison. Names also contain information about where they originated
    --   from, see "GHC.Types.Name#name_sorts"
    --
    -- * 'GHC.Types.Id.Id': see "GHC.Types.Id#name_types"
    --
    -- * 'GHC.Types.Var.Var': see "GHC.Types.Var#name_types"
    --
    -- #name_sorts#
    -- Names are one of:
    --
    --  * External, if they name things declared in other modules. Some external
    --    Names are wired in, i.e. they name primitives defined in the compiler itself
    --
    --  * Internal, if they name things in the module being compiled. Some internal
    --    Names are system names, if they are names manufactured by the compiler

    module GHC.Types.Name (
            -- * The main types
            Name,                                   -- Abstract
            BuiltInSyntax(..),

            -- ** Creating 'Name's
            mkSystemName, mkSystemNameAt,
            mkInternalName, mkClonedInternalName, mkDerivedInternalName,
            mkSystemVarName, mkSysTvName,
            mkFCallName,
            mkExternalName, mkWiredInName,

            -- ** Manipulating and deconstructing 'Name's
            nameUnique, setNameUnique,
            nameOccName, nameNameSpace, nameModule, nameModule_maybe,
            setNameLoc,
            tidyNameOcc,
            localiseName,
            namePun_maybe,

            pprName,
            nameSrcLoc, nameSrcSpan, pprNameDefnLoc, pprDefinedAt,
            pprFullName, pprTickyName,

            -- ** Predicates on 'Name's
            isSystemName, isInternalName, isExternalName,
            isTyVarName, isTyConName, isDataConName,
            isValName, isVarName, isDynLinkName, isFieldName,
            isWiredInName, isWiredIn, isBuiltInSyntax, isTupleTyConName,
            isSumTyConName,
            isUnboxedTupleDataConLikeName,
            isHoleName,
            wiredInNameTyThing_maybe,
            nameIsLocalOrFrom, nameIsExternalOrFrom, nameIsHomePackage,
            nameIsHomePackageImport, nameIsFromExternalPackage,
            stableNameCmp,

            -- * Class 'NamedThing' and overloaded friends
            NamedThing(..),
            getSrcLoc, getSrcSpan, getOccString, getOccFS,

            pprInfixName, pprPrefixName, pprModulePrefix, pprNameUnqualified,
            nameStableString,

            -- Re-export the OccName stuff
            module GHC.Types.Name.Occurrence
        ) where

    import GHC.Prelude

    import {-# SOURCE #-} GHC.Types.TyThing ( TyThing )
    import {-# SOURCE #-} GHC.Builtin.Types ( listTyCon )

    import GHC.Platform
    import GHC.Types.Name.Occurrence
    import GHC.Unit.Module
    import GHC.Unit.Home
    import GHC.Types.FieldLabel
    import GHC.Types.SrcLoc
    import GHC.Types.Unique
    import GHC.Utils.Misc
    import GHC.Data.Maybe
    import GHC.Utils.Binary
    import GHC.Data.FastString
    import GHC.Utils.Outputable
    import GHC.Utils.Panic
    import GHC.OldList (intersperse)

    import Control.DeepSeq
    import Data.Data
    import qualified Data.Semigroup as S
    import GHC.Types.Basic (Boxity(Boxed, Unboxed))
    import GHC.Builtin.Uniques (isTupleTyConUnique, isSumTyConUnique, isTupleDataConLikeUnique)

    {-
    ************************************************************************
    *                                                                      *
    \subsection[Name-datatype]{The @Name@ datatype, and name construction}
    *                                                                      *
    ************************************************************************
    -}

    -- | A unique, unambiguous name for something, containing information about where
    -- that thing originated.
    data Name = Name
      { Name -> NameSort
    n_sort :: NameSort
        -- ^ What sort of name it is

      , Name -> OccName
    n_occ  :: OccName
        -- ^ Its occurrence name.
        --
        -- NOTE: kept lazy to allow known names to be known constructor applications
        -- and to inline better. See Note [Fast comparison for built-in Names]

      , Name -> Unique
    n_uniq :: {-# UNPACK #-} !Unique
        -- ^ Its unique.

      , Name -> SrcSpan
    n_loc  :: !SrcSpan
        -- ^ Definition site
        --
        -- NOTE: we make the n_loc field strict to eliminate some potential
        -- (and real!) space leaks, due to the fact that we don't look at
        -- the SrcLoc in a Name all that often.
      }

    -- See Note [About the NameSorts]
    data NameSort
      = External Module
            -- Either an import from another module
            -- or a top-level name
            -- See Note [About the NameSorts]

      | WiredIn Module TyThing BuiltInSyntax
            -- A variant of External, for wired-in things

      | Internal            -- A user-defined local Id or TyVar
                            -- defined in the module being compiled
                            -- See Note [About the NameSorts]

      | System              -- A system-defined Id or TyVar.  Typically the
                            -- OccName is very uninformative (like 's')

    instance Outputable NameSort where
      ppr :: NameSort -> SDoc
    ppr (External Module
    _)    = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "external"
      ppr (WiredIn Module
    _ TyThing
    _ BuiltInSyntax
    _) = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "wired-in"
      ppr  NameSort
    Internal       = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "internal"
      ppr  NameSort
    System         = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "system"

    instance NFData Name where
      rnf :: Name -> ()
    rnf Name{OccName
    Unique
    SrcSpan
    NameSort
    n_sort :: Name -> NameSort
    n_occ :: Name -> OccName
    n_uniq :: Name -> Unique
    n_loc :: Name -> SrcSpan
    n_sort :: NameSort
    n_occ :: OccName
    n_uniq :: Unique
    n_loc :: SrcSpan
    ..} = NameSort -> ()
    forall a. NFData a => a -> ()
    rnf NameSort
    n_sort () -> () -> ()
    forall a b. a -> b -> b
    `seq` OccName -> ()
    forall a. NFData a => a -> ()
    rnf OccName
    n_occ () -> () -> ()
    forall a b. a -> b -> b
    `seq` Unique
    n_uniq Unique -> () -> ()
    forall a b. a -> b -> b
    `seq` SrcSpan -> ()
    forall a. NFData a => a -> ()
    rnf SrcSpan
    n_loc

    -- Needs NFData Name, so the instance is here to avoid cyclic imports.
    instance NFData FieldLabel where
      rnf :: FieldLabel -> ()
    rnf (FieldLabel DuplicateRecordFields
    a FieldSelectors
    b Name
    c) = DuplicateRecordFields -> ()
    forall a. NFData a => a -> ()
    rnf DuplicateRecordFields
    a () -> () -> ()
    forall a b. a -> b -> b
    `seq` FieldSelectors -> ()
    forall a. NFData a => a -> ()
    rnf FieldSelectors
    b () -> () -> ()
    forall a b. a -> b -> b
    `seq` Name -> ()
    forall a. NFData a => a -> ()
    rnf Name
    c

    instance NFData NameSort where
      rnf :: NameSort -> ()
    rnf (External Module
    m) = Module -> ()
    forall a. NFData a => a -> ()
    rnf Module
    m
      rnf (WiredIn Module
    m TyThing
    t BuiltInSyntax
    b) = Module -> ()
    forall a. NFData a => a -> ()
    rnf Module
    m () -> () -> ()
    forall a b. a -> b -> b
    `seq` TyThing
    t TyThing -> () -> ()
    forall a b. a -> b -> b
    `seq` BuiltInSyntax
    b BuiltInSyntax -> () -> ()
    forall a b. a -> b -> b
    `seq` ()
        -- XXX this is a *lie*, we're not going to rnf the TyThing, but
        -- since the TyThings for WiredIn Names are all static they can't
        -- be hiding space leaks or errors.
      rnf NameSort
    Internal = ()
      rnf NameSort
    System = ()

    -- | BuiltInSyntax is for things like @(:)@, @[]@ and tuples,
    -- which have special syntactic forms.  They aren't in scope
    -- as such.
    data BuiltInSyntax = BuiltInSyntax | UserSyntax

    {-
    Note [Fast comparison for built-in Names]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider this wired-in Name in GHC.Builtin.Names:

       int8TyConName = tcQual gHC_INTERNAL_INT  (fsLit "Int8")  int8TyConKey

    Ultimately this turns into something like:

       int8TyConName = Name gHC_INTERNAL_INT (mkOccName ..."Int8") int8TyConKey

    So a comparison like `x == int8TyConName` will turn into `getUnique x ==
    int8TyConKey`, nice and efficient.  But if the `n_occ` field is strict, that
    definition will look like:

       int8TyConName = case (mkOccName..."Int8") of occ ->
                       Name gHC_INTERNAL_INT occ int8TyConKey

    and now the comparison will not optimise.  This matters even more when there are
    numerous comparisons (see #19386):

    if | tc == int8TyCon  -> ...
       | tc == int16TyCon -> ...
       ...etc...

    when we would like to get a single multi-branched case.

    TL;DR: we make the `n_occ` field lazy.
    -}

    {-
    Note [About the NameSorts]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
    1.  Initially:
        * All types, classes, data constructors get Extenal Names
        * Top-level Ids (including locally-defined ones) get External Names,
        * All other local (non-top-level) Ids get Internal names

    2.  In the Tidy phase (GHC.Iface.Tidy):
          * An Id that is "externally-visible" is given an External Name,
            even if the name was Internal up to that point
          * An Id that is not externally visible is given an Internal Name.
            even if the name was External up to that point
        See GHC.Iface.Tidy.tidyTopName

        An Id is externally visible if it is mentioned in the interface file; e.g.
            - it is exported
            - it is mentioned in an unfolding
        See GHC.Iface.Tidy.chooseExternalIds

    3.  In any invocation of GHC, an External Name for "M.x" has one and only one
        unique.  This unique association is ensured via the Name Cache;
        see Note [The Name Cache] in GHC.Iface.Env.

    4.  In code generation, things with a External name are given C static
        labels, so they finally appear in the .o file's symbol table.  They
        appear in the symbol table in the form M.n. That is why
        externally-visible things are made External (see (2) above).

    5.  A System Name differs in the following ways:
            a) has unique attached when printing dumps
            b) unifier eliminates sys tyvars in favour of user provs where possible

        Before anything gets printed in interface files or output code, it's
        fed through a 'tidy' processor, which zaps the OccNames to have
        unique names; and converts all sys-locals to user locals
        If any desugarer sys-locals have survived that far, they get changed to
        "ds1", "ds2", etc.

    6. A WiredIn Name is used for things (Id, TyCon) that are fully known to the compiler,
       not read from an interface file. E.g. Bool, True, Int, Float, and many others.

       A WiredIn Name contains contains a TyThing, so we don't have to look it up.

       The BuiltInSyntax flag => It's a syntactic form, not "in scope" (e.g. [])
       All built-in syntax thigs are WiredIn.
    -}

    instance HasOccName Name where
      occName :: Name -> OccName
    occName = Name -> OccName
    nameOccName

    nameUnique              :: Name -> Unique
    nameOccName             :: Name -> OccName
    nameNameSpace           :: Name -> NameSpace
    nameModule              :: HasDebugCallStack => Name -> Module
    nameSrcLoc              :: Name -> SrcLoc
    nameSrcSpan             :: Name -> SrcSpan

    nameUnique :: Name -> Unique
    nameUnique    Name
    name = Name -> Unique
    n_uniq Name
    name
    nameOccName :: Name -> OccName
    nameOccName   Name
    name = Name -> OccName
    n_occ  Name
    name
    nameNameSpace :: Name -> NameSpace
    nameNameSpace Name
    name = OccName -> NameSpace
    occNameSpace (Name -> OccName
    n_occ Name
    name)
    nameSrcLoc :: Name -> SrcLoc
    nameSrcLoc    Name
    name = SrcSpan -> SrcLoc
    srcSpanStart (Name -> SrcSpan
    n_loc Name
    name)
    nameSrcSpan :: Name -> SrcSpan
    nameSrcSpan   Name
    name = Name -> SrcSpan
    n_loc  Name
    name

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Predicates on names}
    *                                                                      *
    ************************************************************************
    -}

    isInternalName    :: Name -> Bool
    isExternalName    :: Name -> Bool
    isSystemName      :: Name -> Bool
    isWiredInName     :: Name -> Bool

    isWiredInName :: Name -> Bool
    isWiredInName (Name {n_sort :: Name -> NameSort
    n_sort = WiredIn Module
    _ TyThing
    _ BuiltInSyntax
    _}) = Bool
    True
    isWiredInName Name
    _                               = Bool
    False

    isWiredIn :: NamedThing thing => thing -> Bool
    isWiredIn :: forall thing. NamedThing thing => thing -> Bool
    isWiredIn = Name -> Bool
    isWiredInName (Name -> Bool) -> (thing -> Name) -> thing -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . thing -> Name
    forall a. NamedThing a => a -> Name
    getName

    wiredInNameTyThing_maybe :: Name -> Maybe TyThing
    wiredInNameTyThing_maybe :: Name -> Maybe TyThing
    wiredInNameTyThing_maybe (Name {n_sort :: Name -> NameSort
    n_sort = WiredIn Module
    _ TyThing
    thing BuiltInSyntax
    _}) = TyThing -> Maybe TyThing
    forall a. a -> Maybe a
    Just TyThing
    thing
    wiredInNameTyThing_maybe Name
    _                                   = Maybe TyThing
    forall a. Maybe a
    Nothing

    isBuiltInSyntax :: Name -> Bool
    isBuiltInSyntax :: Name -> Bool
    isBuiltInSyntax (Name {n_sort :: Name -> NameSort
    n_sort = WiredIn Module
    _ TyThing
    _ BuiltInSyntax
    BuiltInSyntax}) = Bool
    True
    isBuiltInSyntax Name
    _                                           = Bool
    False

    isTupleTyConName :: Name -> Bool
    isTupleTyConName :: Name -> Bool
    isTupleTyConName = Maybe (Boxity, Arity) -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe (Boxity, Arity) -> Bool)
    -> (Name -> Maybe (Boxity, Arity)) -> Name -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Unique -> Maybe (Boxity, Arity)
    isTupleTyConUnique (Unique -> Maybe (Boxity, Arity))
    -> (Name -> Unique) -> Name -> Maybe (Boxity, Arity)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique

    isSumTyConName :: Name -> Bool
    isSumTyConName :: Name -> Bool
    isSumTyConName = Maybe Arity -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe Arity -> Bool) -> (Name -> Maybe Arity) -> Name -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Unique -> Maybe Arity
    isSumTyConUnique (Unique -> Maybe Arity) -> (Name -> Unique) -> Name -> Maybe Arity
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique

    -- | This matches a datacon as well as its worker and promoted tycon.
    isUnboxedTupleDataConLikeName :: Name -> Bool
    isUnboxedTupleDataConLikeName :: Name -> Bool
    isUnboxedTupleDataConLikeName Name
    n
      | Just (Boxity
    Unboxed, Arity
    _) <- Unique -> Maybe (Boxity, Arity)
    isTupleDataConLikeUnique (Name -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique Name
    n) = Bool
    True
      | Bool
    otherwise = Bool
    False

    isExternalName :: Name -> Bool
    isExternalName (Name {n_sort :: Name -> NameSort
    n_sort = External Module
    _})    = Bool
    True
    isExternalName (Name {n_sort :: Name -> NameSort
    n_sort = WiredIn Module
    _ TyThing
    _ BuiltInSyntax
    _}) = Bool
    True
    isExternalName Name
    _                               = Bool
    False

    isInternalName :: Name -> Bool
    isInternalName Name
    name = Bool -> Bool
    not (Name -> Bool
    isExternalName Name
    name)

    isHoleName :: Name -> Bool
    isHoleName :: Name -> Bool
    isHoleName = Module -> Bool
    forall u. GenModule (GenUnit u) -> Bool
    isHoleModule (Module -> Bool) -> (Name -> Module) -> Name -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HasDebugCallStack => Name -> Module
    Name -> Module
    nameModule

    -- | Will the 'Name' come from a dynamically linked package?
    isDynLinkName :: Platform -> Module -> Name -> Bool
    isDynLinkName :: Platform -> Module -> Name -> Bool
    isDynLinkName Platform
    platform Module
    this_mod Name
    name
      | Just Module
    mod <- Name -> Maybe Module
    nameModule_maybe Name
    name
        -- Issue #8696 - when GHC is dynamically linked, it will attempt
        -- to load the dynamic dependencies of object files at compile
        -- time for things like QuasiQuotes or
        -- TemplateHaskell. Unfortunately, this interacts badly with
        -- intra-package linking, because we don't generate indirect
        -- (dynamic) symbols for intra-package calls. This means that if a
        -- module with an intra-package call is loaded without its
        -- dependencies, then GHC fails to link.
        --
        -- In the mean time, always force dynamic indirections to be
        -- generated: when the module name isn't the module being
        -- compiled, references are dynamic.
        = case Platform -> OS
    platformOS Platform
    platform of
            -- On Windows the hack for #8696 makes it unlinkable.
            -- As the entire setup of the code from Cmm down to the RTS expects
            -- the use of trampolines for the imported functions only when
            -- doing intra-package linking, e.g. referring to a symbol defined in the same
            -- package should not use a trampoline.
            -- I much rather have dynamic TH not supported than the entire Dynamic linking
            -- not due to a hack.
            -- Also not sure this would break on Windows anyway.
            OS
    OSMinGW32 -> Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    mod Unit -> Unit -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    this_mod

            -- For the other platforms, still perform the hack
            OS
    _         -> Module
    mod Module -> Module -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Module
    this_mod

      | Bool
    otherwise = Bool
    False  -- no, it is not even an external name

    nameModule :: HasDebugCallStack => Name -> Module
    nameModule Name
    name =
      Name -> Maybe Module
    nameModule_maybe Name
    name Maybe Module -> Module -> Module
    forall a. Maybe a -> a -> a
    `orElse`
      String -> SDoc -> Module
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "nameModule" (NameSort -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (Name -> NameSort
    n_sort Name
    name) SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    name)

    nameModule_maybe :: Name -> Maybe Module
    nameModule_maybe :: Name -> Maybe Module
    nameModule_maybe (Name { n_sort :: Name -> NameSort
    n_sort = External Module
    mod})    = Module -> Maybe Module
    forall a. a -> Maybe a
    Just Module
    mod
    nameModule_maybe (Name { n_sort :: Name -> NameSort
    n_sort = WiredIn Module
    mod TyThing
    _ BuiltInSyntax
    _}) = Module -> Maybe Module
    forall a. a -> Maybe a
    Just Module
    mod
    nameModule_maybe Name
    _                                  = Maybe Module
    forall a. Maybe a
    Nothing

    is_interactive_or_from :: Module -> Module -> Bool
    is_interactive_or_from :: Module -> Module -> Bool
    is_interactive_or_from Module
    from Module
    mod = Module
    from Module -> Module -> Bool
    forall a. Eq a => a -> a -> Bool
    == Module
    mod Bool -> Bool -> Bool
    || Module -> Bool
    isInteractiveModule Module
    mod

    -- Return the pun for a name if available.
    -- Used for pretty-printing under ListTuplePuns.
    -- Arity 1 is skipped here because unary tuples have no prefix representation,
    -- since that is occupied by the unit tuple.
    namePun_maybe :: Name -> Maybe FastString
    namePun_maybe :: Name -> Maybe FastString
    namePun_maybe Name
    name
      | Name -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique Name
    name Unique -> Unique -> Bool
    forall a. Eq a => a -> a -> Bool
    == TyCon -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique TyCon
    listTyCon = FastString -> Maybe FastString
    forall a. a -> Maybe a
    Just (String -> FastString
    fsLit String
    "[]")

      | Just (Boxity
    boxity, Arity
    ar) <- Unique -> Maybe (Boxity, Arity)
    isTupleTyConUnique (Name -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique Name
    name)
      , Arity
    ar Arity -> Arity -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Arity
    1 =
        let
          (String
    lpar, String
    rpar) =
            case Boxity
    boxity of
              Boxity
    Boxed -> (String
    "(", String
    ")")
              Boxity
    Unboxed -> (String
    "(#", String
    "#)")
        in FastString -> Maybe FastString
    forall a. a -> Maybe a
    Just (String -> FastString
    fsLit (String -> FastString) -> String -> FastString
    forall a b. (a -> b) -> a -> b
    $ String
    lpar String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Arity -> String
    commas Arity
    ar String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    rpar)

      | Just Arity
    ar <- Unique -> Maybe Arity
    isSumTyConUnique (Name -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique Name
    name)
      = FastString -> Maybe FastString
    forall a. a -> Maybe a
    Just (String -> FastString
    fsLit (String -> FastString) -> String -> FastString
    forall a b. (a -> b) -> a -> b
    $ String
    "(# " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Arity -> String
    bars Arity
    ar String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " #)")
      where
        commas :: Arity -> String
    commas Arity
    ar = Arity -> Char -> String
    forall a. Arity -> a -> [a]
    replicate (Arity
    arArity -> Arity -> Arity
    forall a. Num a => a -> a -> a
    -Arity
    1) Char
    ','
        bars :: Arity -> String
    bars Arity
    ar = Char -> String -> String
    forall a. a -> [a] -> [a]
    intersperse Char
    ' ' (Arity -> Char -> String
    forall a. Arity -> a -> [a]
    replicate (Arity
    arArity -> Arity -> Arity
    forall a. Num a => a -> a -> a
    -Arity
    1) Char
    '|')

    namePun_maybe Name
    _ = Maybe FastString
    forall a. Maybe a
    Nothing

    nameIsLocalOrFrom :: Module -> Name -> Bool
    -- ^ Returns True if the name is
    --   (a) Internal
    --   (b) External but from the specified module
    --   (c) External but from the 'interactive' package
    --
    -- The key idea is that
    --    False means: the entity is defined in some other module
    --                 you can find the details (type, fixity, instances)
    --                     in some interface file
    --                 those details will be stored in the EPT or HPT
    --
    --    True means:  the entity is defined in this module or earlier in
    --                     the GHCi session
    --                 you can find details (type, fixity, instances) in the
    --                     TcGblEnv or TcLclEnv
    --
    -- The isInteractiveModule part is because successive interactions of a GHCi session
    -- each give rise to a fresh module (Ghci1, Ghci2, etc), but they all come
    -- from the magic 'interactive' package; and all the details are kept in the
    -- TcLclEnv, TcGblEnv, NOT in the HPT or EPT.
    -- See Note [The interactive package] in "GHC.Runtime.Context"

    nameIsLocalOrFrom :: Module -> Name -> Bool
    nameIsLocalOrFrom Module
    from Name
    name
      | Just Module
    mod <- Name -> Maybe Module
    nameModule_maybe Name
    name = Module -> Module -> Bool
    is_interactive_or_from Module
    from Module
    mod
      | Bool
    otherwise                         = Bool
    True

    nameIsExternalOrFrom :: Module -> Name -> Bool
    -- ^ Returns True if the name is external or from the 'interactive' package
    -- See documentation of `nameIsLocalOrFrom` function
    nameIsExternalOrFrom :: Module -> Name -> Bool
    nameIsExternalOrFrom Module
    from Name
    name
      | Just Module
    mod <- Name -> Maybe Module
    nameModule_maybe Name
    name = Module -> Module -> Bool
    is_interactive_or_from Module
    from Module
    mod
      | Bool
    otherwise                         = Bool
    False

    nameIsHomePackage :: Module -> Name -> Bool
    -- True if the Name is defined in module of this package
    nameIsHomePackage :: Module -> Name -> Bool
    nameIsHomePackage Module
    this_mod
      = \Name
    nm -> case Name -> NameSort
    n_sort Name
    nm of
                  External Module
    nm_mod    -> Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    nm_mod Unit -> Unit -> Bool
    forall a. Eq a => a -> a -> Bool
    == Unit
    this_pkg
                  WiredIn Module
    nm_mod TyThing
    _ BuiltInSyntax
    _ -> Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    nm_mod Unit -> Unit -> Bool
    forall a. Eq a => a -> a -> Bool
    == Unit
    this_pkg
                  NameSort
    Internal -> Bool
    True
                  NameSort
    System   -> Bool
    False
      where
        this_pkg :: Unit
    this_pkg = Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    this_mod

    nameIsHomePackageImport :: Module -> Name -> Bool
    -- True if the Name is defined in module of this package
    -- /other than/ the this_mod
    nameIsHomePackageImport :: Module -> Name -> Bool
    nameIsHomePackageImport Module
    this_mod
      = \Name
    nm -> case Name -> Maybe Module
    nameModule_maybe Name
    nm of
                  Maybe Module
    Nothing -> Bool
    False
                  Just Module
    nm_mod -> Module
    nm_mod Module -> Module -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Module
    this_mod
                              Bool -> Bool -> Bool
    && Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    nm_mod Unit -> Unit -> Bool
    forall a. Eq a => a -> a -> Bool
    == Unit
    this_pkg
      where
        this_pkg :: Unit
    this_pkg = Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    this_mod

    -- | Returns True if the Name comes from some other package: neither this
    -- package nor the interactive package.
    nameIsFromExternalPackage :: HomeUnit -> Name -> Bool
    nameIsFromExternalPackage :: HomeUnit -> Name -> Bool
    nameIsFromExternalPackage HomeUnit
    home_unit Name
    name
      | Just Module
    mod <- Name -> Maybe Module
    nameModule_maybe Name
    name
      , HomeUnit -> Module -> Bool
    notHomeModule HomeUnit
    home_unit Module
    mod   -- Not the current unit
      , Bool -> Bool
    not (Module -> Bool
    isInteractiveModule Module
    mod) -- Not the 'interactive' package
      = Bool
    True
      | Bool
    otherwise
      = Bool
    False

    isTyVarName :: Name -> Bool
    isTyVarName :: Name -> Bool
    isTyVarName Name
    name = OccName -> Bool
    isTvOcc (Name -> OccName
    nameOccName Name
    name)

    isTyConName :: Name -> Bool
    isTyConName :: Name -> Bool
    isTyConName Name
    name = OccName -> Bool
    isTcOcc (Name -> OccName
    nameOccName Name
    name)

    isDataConName :: Name -> Bool
    isDataConName :: Name -> Bool
    isDataConName Name
    name = OccName -> Bool
    isDataOcc (Name -> OccName
    nameOccName Name
    name)

    isValName :: Name -> Bool
    isValName :: Name -> Bool
    isValName Name
    name = OccName -> Bool
    isValOcc (Name -> OccName
    nameOccName Name
    name)

    isVarName :: Name -> Bool
    isVarName :: Name -> Bool
    isVarName = OccName -> Bool
    isVarOcc (OccName -> Bool) -> (Name -> OccName) -> Name -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> OccName
    nameOccName

    isFieldName :: Name -> Bool
    isFieldName :: Name -> Bool
    isFieldName = OccName -> Bool
    isFieldOcc (OccName -> Bool) -> (Name -> OccName) -> Name -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Name -> OccName
    nameOccName

    isSystemName :: Name -> Bool
    isSystemName (Name {n_sort :: Name -> NameSort
    n_sort = NameSort
    System}) = Bool
    True
    isSystemName Name
    _                        = Bool
    False

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

    -- | Create a name which is (for now at least) local to the current module and hence
    -- does not need a 'Module' to disambiguate it from other 'Name's
    mkInternalName :: Unique -> OccName -> SrcSpan -> Name
    mkInternalName :: Unique -> OccName -> SrcSpan -> Name
    mkInternalName Unique
    uniq OccName
    occ SrcSpan
    loc = Name { n_uniq :: Unique
    n_uniq = Unique
    uniq
                                       , n_sort :: NameSort
    n_sort = NameSort
    Internal
                                       , n_occ :: OccName
    n_occ = OccName
    occ
                                       , n_loc :: SrcSpan
    n_loc = SrcSpan
    loc }
            -- NB: You might worry that after lots of huffing and
            -- puffing we might end up with two local names with distinct
            -- uniques, but the same OccName.  Indeed we can, but that's ok
            --      * the insides of the compiler don't care: they use the Unique
            --      * when printing for -ddump-xxx you can switch on -dppr-debug to get the
            --        uniques if you get confused
            --      * for interface files we tidyCore first, which makes
            --        the OccNames distinct when they need to be

    mkClonedInternalName :: Unique -> Name -> Name
    mkClonedInternalName :: Unique -> Name -> Name
    mkClonedInternalName Unique
    uniq (Name { n_occ :: Name -> OccName
    n_occ = OccName
    occ, n_loc :: Name -> SrcSpan
    n_loc = SrcSpan
    loc })
      = Name { n_uniq :: Unique
    n_uniq = Unique
    uniq, n_sort :: NameSort
    n_sort = NameSort
    Internal
             , n_occ :: OccName
    n_occ = OccName
    occ, n_loc :: SrcSpan
    n_loc = SrcSpan
    loc }

    mkDerivedInternalName :: (OccName -> OccName) -> Unique -> Name -> Name
    mkDerivedInternalName :: (OccName -> OccName) -> Unique -> Name -> Name
    mkDerivedInternalName OccName -> OccName
    derive_occ Unique
    uniq (Name { n_occ :: Name -> OccName
    n_occ = OccName
    occ, n_loc :: Name -> SrcSpan
    n_loc = SrcSpan
    loc })
      = Name { n_uniq :: Unique
    n_uniq = Unique
    uniq, n_sort :: NameSort
    n_sort = NameSort
    Internal
             , n_occ :: OccName
    n_occ = OccName -> OccName
    derive_occ OccName
    occ, n_loc :: SrcSpan
    n_loc = SrcSpan
    loc }

    -- | Create a name which definitely originates in the given module
    mkExternalName :: Unique -> Module -> OccName -> SrcSpan -> Name
    {-# INLINE mkExternalName #-}
    -- WATCH OUT! External Names should be in the Name Cache
    -- (see Note [The Name Cache] in GHC.Iface.Env), so don't just call mkExternalName
    -- with some fresh unique without populating the Name Cache
    mkExternalName :: Unique -> Module -> OccName -> SrcSpan -> Name
    mkExternalName Unique
    uniq Module
    mod OccName
    occ SrcSpan
    loc
      = Name { n_uniq :: Unique
    n_uniq = Unique
    uniq, n_sort :: NameSort
    n_sort = Module -> NameSort
    External Module
    mod,
               n_occ :: OccName
    n_occ = OccName
    occ, n_loc :: SrcSpan
    n_loc = SrcSpan
    loc }

    -- | Create a name which is actually defined by the compiler itself
    mkWiredInName :: Module -> OccName -> Unique -> TyThing -> BuiltInSyntax -> Name
    {-# INLINE mkWiredInName #-}
    mkWiredInName :: Module -> OccName -> Unique -> TyThing -> BuiltInSyntax -> Name
    mkWiredInName Module
    mod OccName
    occ Unique
    uniq TyThing
    thing BuiltInSyntax
    built_in
      = Name { n_uniq :: Unique
    n_uniq = Unique
    uniq,
               n_sort :: NameSort
    n_sort = Module -> TyThing -> BuiltInSyntax -> NameSort
    WiredIn Module
    mod TyThing
    thing BuiltInSyntax
    built_in,
               n_occ :: OccName
    n_occ = OccName
    occ, n_loc :: SrcSpan
    n_loc = SrcSpan
    wiredInSrcSpan }

    -- | Create a name brought into being by the compiler
    mkSystemName :: Unique -> OccName -> Name
    mkSystemName :: Unique -> OccName -> Name
    mkSystemName Unique
    uniq OccName
    occ = Unique -> OccName -> SrcSpan -> Name
    mkSystemNameAt Unique
    uniq OccName
    occ SrcSpan
    noSrcSpan

    mkSystemNameAt :: Unique -> OccName -> SrcSpan -> Name
    mkSystemNameAt :: Unique -> OccName -> SrcSpan -> Name
    mkSystemNameAt Unique
    uniq OccName
    occ SrcSpan
    loc = Name { n_uniq :: Unique
    n_uniq = Unique
    uniq, n_sort :: NameSort
    n_sort = NameSort
    System
                                       , n_occ :: OccName
    n_occ = OccName
    occ, n_loc :: SrcSpan
    n_loc = SrcSpan
    loc }

    mkSystemVarName :: Unique -> FastString -> Name
    mkSystemVarName :: Unique -> FastString -> Name
    mkSystemVarName Unique
    uniq FastString
    fs = Unique -> OccName -> Name
    mkSystemName Unique
    uniq (FastString -> OccName
    mkVarOccFS FastString
    fs)

    mkSysTvName :: Unique -> FastString -> Name
    mkSysTvName :: Unique -> FastString -> Name
    mkSysTvName Unique
    uniq FastString
    fs = Unique -> OccName -> Name
    mkSystemName Unique
    uniq (FastString -> OccName
    mkTyVarOccFS FastString
    fs)

    -- | Make a name for a foreign call
    mkFCallName :: Unique -> FastString -> Name
    mkFCallName :: Unique -> FastString -> Name
    mkFCallName Unique
    uniq FastString
    str = Unique -> OccName -> SrcSpan -> Name
    mkInternalName Unique
    uniq (FastString -> OccName
    mkVarOccFS FastString
    str) SrcSpan
    noSrcSpan
       -- The encoded string completely describes the ccall

    -- When we renumber/rename things, we need to be
    -- able to change a Name's Unique to match the cached
    -- one in the thing it's the name of.  If you know what I mean.
    setNameUnique :: Name -> Unique -> Name
    setNameUnique :: Name -> Unique -> Name
    setNameUnique Name
    name Unique
    uniq = Name
    name {n_uniq = uniq}

    -- This is used for hsigs: we want to use the name of the originally exported
    -- entity, but edit the location to refer to the reexport site
    setNameLoc :: Name -> SrcSpan -> Name
    setNameLoc :: Name -> SrcSpan -> Name
    setNameLoc Name
    name SrcSpan
    loc = Name
    name {n_loc = loc}

    tidyNameOcc :: Name -> OccName -> Name
    -- We set the OccName of a Name when tidying
    -- In doing so, we change System --> Internal, so that when we print
    -- it we don't get the unique by default.  It's tidy now!
    tidyNameOcc :: Name -> OccName -> Name
    tidyNameOcc name :: Name
    name@(Name { n_sort :: Name -> NameSort
    n_sort = NameSort
    System }) OccName
    occ = Name
    name { n_occ = occ, n_sort = Internal}
    tidyNameOcc Name
    name                            OccName
    occ = Name
    name { n_occ = occ }

    -- | Make the 'Name' into an internal name, regardless of what it was to begin with
    localiseName :: Name -> Name
    localiseName :: Name -> Name
    localiseName Name
    n = Name
    n { n_sort = Internal }

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Hashing and comparison}
    *                                                                      *
    ************************************************************************
    -}

    cmpName :: Name -> Name -> Ordering
    cmpName :: Name -> Name -> Ordering
    cmpName Name
    n1 Name
    n2 = Name -> Unique
    n_uniq Name
    n1 Unique -> Unique -> Ordering
    `nonDetCmpUnique` Name -> Unique
    n_uniq Name
    n2

    -- | Compare Names lexicographically
    -- This only works for Names that originate in the source code or have been
    -- tidied.
    stableNameCmp :: Name -> Name -> Ordering
    stableNameCmp :: Name -> Name -> Ordering
    stableNameCmp (Name { n_sort :: Name -> NameSort
    n_sort = NameSort
    s1, n_occ :: Name -> OccName
    n_occ = OccName
    occ1 })
                  (Name { n_sort :: Name -> NameSort
    n_sort = NameSort
    s2, n_occ :: Name -> OccName
    n_occ = OccName
    occ2 })
      = NameSort -> NameSort -> Ordering
    sort_cmp NameSort
    s1 NameSort
    s2 Ordering -> Ordering -> Ordering
    forall a. Semigroup a => a -> a -> a
    S.<> OccName -> OccName -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare OccName
    occ1 OccName
    occ2
        -- The ordinary compare on OccNames is lexicographic
      where
        -- Later constructors are bigger
        sort_cmp :: NameSort -> NameSort -> Ordering
    sort_cmp (External Module
    m1) (External Module
    m2)       = Module
    m1 Module -> Module -> Ordering
    `stableModuleCmp` Module
    m2
        sort_cmp (External {}) NameSort
    _                   = Ordering
    LT
        sort_cmp (WiredIn {}) (External {})        = Ordering
    GT
        sort_cmp (WiredIn Module
    m1 TyThing
    _ BuiltInSyntax
    _) (WiredIn Module
    m2 TyThing
    _ BuiltInSyntax
    _) = Module
    m1 Module -> Module -> Ordering
    `stableModuleCmp` Module
    m2
        sort_cmp (WiredIn {})     NameSort
    _                = Ordering
    LT
        sort_cmp NameSort
    Internal         (External {})    = Ordering
    GT
        sort_cmp NameSort
    Internal         (WiredIn {})     = Ordering
    GT
        sort_cmp NameSort
    Internal         NameSort
    Internal         = Ordering
    EQ
        sort_cmp NameSort
    Internal         NameSort
    System           = Ordering
    LT
        sort_cmp NameSort
    System           NameSort
    System           = Ordering
    EQ
        sort_cmp NameSort
    System           NameSort
    _                = Ordering
    GT

    {-
    ************************************************************************
    *                                                                      *
    \subsection[Name-instances]{Instance declarations}
    *                                                                      *
    ************************************************************************
    -}

    -- | The same comments as for `Name`'s `Ord` instance apply.
    instance Eq Name where
        Name
    a == :: Name -> Name -> Bool
    == Name
    b = case (Name
    a Name -> Name -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` Name
    b) of { Ordering
    EQ -> Bool
    True;  Ordering
    _ -> Bool
    False }
        Name
    a /= :: Name -> Name -> Bool
    /= Name
    b = case (Name
    a Name -> Name -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` Name
    b) of { Ordering
    EQ -> Bool
    False; Ordering
    _ -> Bool
    True }

    -- | __Caution__: This instance is implemented via `nonDetCmpUnique`, which
    -- means that the ordering is not stable across deserialization or rebuilds.
    --
    -- See `nonDetCmpUnique` for further information, and #15240 for a bug
    -- caused by improper use of this instance.

    -- For a deterministic lexicographic ordering, use `stableNameCmp`.
    instance Ord Name where
        compare :: Name -> Name -> Ordering
    compare = Name -> Name -> Ordering
    cmpName

    instance Uniquable Name where
        getUnique :: Name -> Unique
    getUnique = Name -> Unique
    nameUnique

    instance NamedThing Name where
        getName :: Name -> Name
    getName Name
    n = Name
    n

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

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Binary}
    *                                                                      *
    ************************************************************************
    -}

    -- | Assumes that the 'Name' is a non-binding one. See
    -- 'GHC.Iface.Syntax.putIfaceTopBndr' and 'GHC.Iface.Syntax.getIfaceTopBndr' for
    -- serializing binding 'Name's. See 'UserData' for the rationale for this
    -- distinction.
    instance Binary Name where
       put_ :: WriteBinHandle -> Name -> IO ()
    put_ WriteBinHandle
    bh Name
    name =
          case Proxy Name -> WriteBinHandle -> BinaryWriter Name
    forall a. Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a
    findUserDataWriter Proxy Name
    forall {k} (t :: k). Proxy t
    Proxy WriteBinHandle
    bh of
            BinaryWriter Name
    tbl -> BinaryWriter Name -> WriteBinHandle -> Name -> IO ()
    forall s. BinaryWriter s -> WriteBinHandle -> s -> IO ()
    putEntry BinaryWriter Name
    tbl WriteBinHandle
    bh Name
    name

       get :: ReadBinHandle -> IO Name
    get ReadBinHandle
    bh =
          case Proxy Name -> ReadBinHandle -> BinaryReader Name
    forall a. Typeable a => Proxy a -> ReadBinHandle -> BinaryReader a
    findUserDataReader Proxy Name
    forall {k} (t :: k). Proxy t
    Proxy ReadBinHandle
    bh of
            BinaryReader Name
    tbl -> BinaryReader Name -> ReadBinHandle -> IO Name
    forall s. BinaryReader s -> ReadBinHandle -> IO s
    getEntry BinaryReader Name
    tbl ReadBinHandle
    bh

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Pretty printing}
    *                                                                      *
    ************************************************************************
    -}

    instance Outputable Name where
        ppr :: Name -> SDoc
    ppr Name
    name = Name -> SDoc
    forall doc. IsLine doc => Name -> doc
    pprName Name
    name

    instance OutputableBndr Name where
        pprBndr :: BindingSite -> Name -> SDoc
    pprBndr BindingSite
    _ Name
    name = Name -> SDoc
    forall doc. IsLine doc => Name -> doc
    pprName Name
    name
        pprInfixOcc :: Name -> SDoc
    pprInfixOcc  = Name -> SDoc
    forall a. (Outputable a, NamedThing a) => a -> SDoc
    pprInfixName
        pprPrefixOcc :: Name -> SDoc
    pprPrefixOcc = Name -> SDoc
    forall a. NamedThing a => a -> SDoc
    pprPrefixName

    pprName :: forall doc. IsLine doc => Name -> doc
    pprName :: forall doc. IsLine doc => Name -> doc
    pprName name :: Name
    name@(Name {n_sort :: Name -> NameSort
    n_sort = NameSort
    sort, n_uniq :: Name -> Unique
    n_uniq = Unique
    uniq, n_occ :: Name -> OccName
    n_occ = OccName
    occ})
      = doc -> (PprStyle -> SDoc) -> doc
    forall doc. IsOutput doc => doc -> (PprStyle -> SDoc) -> doc
    docWithStyle doc
    codeDoc PprStyle -> SDoc
    normalDoc
      where
       codeDoc :: doc
    codeDoc = case NameSort
    sort of
                   WiredIn Module
    mod TyThing
    _ BuiltInSyntax
    _ -> Module -> doc
    forall doc. IsLine doc => Module -> doc
    pprModule Module
    mod doc -> doc -> doc
    forall doc. IsLine doc => doc -> doc -> doc
    <> Char -> doc
    forall doc. IsLine doc => Char -> doc
    char Char
    '_' doc -> doc -> doc
    forall doc. IsLine doc => doc -> doc -> doc
    <> doc
    z_occ
                   External Module
    mod    -> Module -> doc
    forall doc. IsLine doc => Module -> doc
    pprModule Module
    mod doc -> doc -> doc
    forall doc. IsLine doc => doc -> doc -> doc
    <> Char -> doc
    forall doc. IsLine doc => Char -> doc
    char Char
    '_' doc -> doc -> doc
    forall doc. IsLine doc => doc -> doc -> doc
    <> doc
    z_occ
                                      -- In code style, always qualify
                                      -- ToDo: maybe we could print all wired-in things unqualified
                                      --       in code style, to reduce symbol table bloat?
                   NameSort
    System          -> Unique -> doc
    forall doc. IsLine doc => Unique -> doc
    pprUniqueAlways Unique
    uniq
                   NameSort
    Internal        -> Unique -> doc
    forall doc. IsLine doc => Unique -> doc
    pprUniqueAlways Unique
    uniq
       z_occ :: doc
    z_occ = FastZString -> doc
    forall doc. IsLine doc => FastZString -> doc
    ztext (FastZString -> doc) -> FastZString -> doc
    forall a b. (a -> b) -> a -> b
    $ FastString -> FastZString
    zEncodeFS (FastString -> FastZString) -> FastString -> FastZString
    forall a b. (a -> b) -> a -> b
    $ OccName -> FastString
    occNameMangledFS OccName
    occ

       normalDoc :: PprStyle -> SDoc
    normalDoc PprStyle
    sty =
         (Bool -> SDoc) -> SDoc
    forall doc. IsOutput doc => (Bool -> doc) -> doc
    getPprDebug ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
    forall a b. (a -> b) -> a -> b
    $ \Bool
    debug ->
         (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
    forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
    sdocOption SDocContext -> Bool
    sdocListTuplePuns ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
    forall a b. (a -> b) -> a -> b
    $ \Bool
    listTuplePuns ->
           Bool -> Maybe FastString -> SDoc -> SDoc
    handlePuns Bool
    listTuplePuns (Name -> Maybe FastString
    namePun_maybe Name
    name) (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
           case NameSort
    sort of
             WiredIn Module
    mod TyThing
    _ BuiltInSyntax
    builtin   -> Bool
    -> PprStyle
    -> Unique
    -> Module
    -> OccName
    -> Bool
    -> BuiltInSyntax
    -> SDoc
    pprExternal Bool
    debug PprStyle
    sty Unique
    uniq Module
    mod OccName
    occ Bool
    True  BuiltInSyntax
    builtin
             External Module
    mod            -> Bool
    -> PprStyle
    -> Unique
    -> Module
    -> OccName
    -> Bool
    -> BuiltInSyntax
    -> SDoc
    pprExternal Bool
    debug PprStyle
    sty Unique
    uniq Module
    mod OccName
    occ Bool
    False BuiltInSyntax
    UserSyntax
             NameSort
    System                  -> Bool -> PprStyle -> Unique -> OccName -> SDoc
    pprSystem   Bool
    debug PprStyle
    sty Unique
    uniq OccName
    occ
             NameSort
    Internal                -> Bool -> PprStyle -> Unique -> OccName -> SDoc
    pprInternal Bool
    debug PprStyle
    sty Unique
    uniq OccName
    occ

       handlePuns :: Bool -> Maybe FastString -> SDoc -> SDoc
       handlePuns :: Bool -> Maybe FastString -> SDoc -> SDoc
    handlePuns Bool
    True (Just FastString
    pun) SDoc
    _ = FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext FastString
    pun
       handlePuns Bool
    _    Maybe FastString
    _          SDoc
    r = SDoc
    r
    {-# SPECIALISE pprName :: Name -> SDoc #-}
    {-# SPECIALISE pprName :: Name -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

    -- | Print fully qualified name (with unit-id and module, but no unique)
    pprFullName :: Module -> Name -> SDoc
    pprFullName :: Module -> Name -> SDoc
    pprFullName Module
    this_mod Name{n_sort :: Name -> NameSort
    n_sort = NameSort
    sort, n_occ :: Name -> OccName
    n_occ = OccName
    occ} =
      let mod :: Module
    mod = case NameSort
    sort of
            WiredIn  Module
    m TyThing
    _ BuiltInSyntax
    _ -> Module
    m
            External Module
    m     -> Module
    m
            NameSort
    System         -> Module
    this_mod
            NameSort
    Internal       -> Module
    this_mod
          in FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext (UnitId -> FastString
    unitIdFS (Module -> UnitId
    moduleUnitId Module
    mod))
             SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    colon    SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext (ModuleName -> FastString
    moduleNameFS (ModuleName -> FastString) -> ModuleName -> FastString
    forall a b. (a -> b) -> a -> b
    $ Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    mod)
             SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    dot      SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext (OccName -> FastString
    occNameFS OccName
    occ)

    -- | Print a ticky ticky styled name
    --
    -- Module argument is the module to use for internal and system names. When
    -- printing the name in a ticky profile, the module name is included even for
    -- local things. However, ticky uses the format "x (M)" rather than "M.x".
    -- Hence, this function provides a separation from normal styling.
    pprTickyName :: Module -> Name -> SDoc
    pprTickyName :: Module -> Name -> SDoc
    pprTickyName Module
    this_mod Name
    name
      | Name -> Bool
    isInternalName Name
    name = Name -> SDoc
    forall doc. IsLine doc => Name -> doc
    pprName Name
    name SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    parens (Module -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Module
    this_mod)
      | Bool
    otherwise           = Name -> SDoc
    forall doc. IsLine doc => Name -> doc
    pprName Name
    name

    -- | Print the string of Name unqualifiedly directly.
    pprNameUnqualified :: Name -> SDoc
    pprNameUnqualified :: Name -> SDoc
    pprNameUnqualified Name { n_occ :: Name -> OccName
    n_occ = OccName
    occ } = OccName -> SDoc
    ppr_occ_name OccName
    occ

    pprExternal :: Bool -> PprStyle -> Unique -> Module -> OccName -> Bool -> BuiltInSyntax -> SDoc
    pprExternal :: Bool
    -> PprStyle
    -> Unique
    -> Module
    -> OccName
    -> Bool
    -> BuiltInSyntax
    -> SDoc
    pprExternal Bool
    debug PprStyle
    sty Unique
    uniq Module
    mod OccName
    occ Bool
    is_wired BuiltInSyntax
    is_builtin
      | Bool
    debug         = SDoc
    pp_mod SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> OccName -> SDoc
    ppr_occ_name OccName
    occ
                         SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    braces ([SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep [if Bool
    is_wired then String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "(w)" else SDoc
    forall doc. IsOutput doc => doc
    empty,
                                          NameSpace -> SDoc
    pprNameSpaceBrief (OccName -> NameSpace
    occNameSpace OccName
    occ),
                                          Unique -> SDoc
    pprUnique Unique
    uniq])
      | BuiltInSyntax
    BuiltInSyntax <- BuiltInSyntax
    is_builtin = OccName -> SDoc
    ppr_occ_name OccName
    occ  -- Never qualify builtin syntax
      | Bool
    otherwise                   =
            if Module -> Bool
    forall u. GenModule (GenUnit u) -> Bool
    isHoleModule Module
    mod
                then case PprStyle -> QueryQualifyName
    qualName PprStyle
    sty Module
    mod OccName
    occ of
                        QualifyName
    NameUnqual -> OccName -> SDoc
    ppr_occ_name OccName
    occ
                        QualifyName
    _ -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    braces (ModuleName -> SDoc
    forall doc. IsLine doc => ModuleName -> doc
    pprModuleName (Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    mod) SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    dot SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> OccName -> SDoc
    ppr_occ_name OccName
    occ)
                else PprStyle -> Module -> OccName -> SDoc
    pprModulePrefix PprStyle
    sty Module
    mod OccName
    occ SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> OccName -> SDoc
    ppr_occ_name OccName
    occ
      where
        pp_mod :: SDoc
    pp_mod = (SDocContext -> Bool) -> SDoc -> SDoc
    ppUnlessOption SDocContext -> Bool
    sdocSuppressModulePrefixes
                   (Module -> SDoc
    forall doc. IsLine doc => Module -> doc
    pprModule Module
    mod SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    dot)

    pprInternal :: Bool -> PprStyle -> Unique -> OccName -> SDoc
    pprInternal :: Bool -> PprStyle -> Unique -> OccName -> SDoc
    pprInternal Bool
    debug PprStyle
    sty Unique
    uniq OccName
    occ
      | Bool
    debug          = OccName -> SDoc
    ppr_occ_name OccName
    occ SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    braces ([SDoc] -> SDoc
    forall doc. IsLine doc => [doc] -> doc
    hsep [NameSpace -> SDoc
    pprNameSpaceBrief (OccName -> NameSpace
    occNameSpace OccName
    occ),
                                                           Unique -> SDoc
    pprUnique Unique
    uniq])
      | PprStyle -> Bool
    dumpStyle PprStyle
    sty  = OccName -> SDoc
    ppr_occ_name OccName
    occ SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> Unique -> SDoc
    ppr_underscore_unique Unique
    uniq
                            -- For debug dumps, we're not necessarily dumping
                            -- tidied code, so we need to print the uniques.
      | Bool
    otherwise      = OccName -> SDoc
    ppr_occ_name OccName
    occ   -- User style

    -- Like Internal, except that we only omit the unique in Iface style
    pprSystem :: Bool -> PprStyle -> Unique -> OccName -> SDoc
    pprSystem :: Bool -> PprStyle -> Unique -> OccName -> SDoc
    pprSystem Bool
    debug PprStyle
    _sty Unique
    uniq OccName
    occ
      | Bool
    debug          = OccName -> SDoc
    ppr_occ_name OccName
    occ SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> Unique -> SDoc
    ppr_underscore_unique Unique
    uniq
                         SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc
    braces (NameSpace -> SDoc
    pprNameSpaceBrief (OccName -> NameSpace
    occNameSpace OccName
    occ))
      | Bool
    otherwise      = OccName -> SDoc
    ppr_occ_name OccName
    occ SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> Unique -> SDoc
    ppr_underscore_unique Unique
    uniq
                                    -- If the tidy phase hasn't run, the OccName
                                    -- is unlikely to be informative (like 's'),
                                    -- so print the unique

    pprModulePrefix :: PprStyle -> Module -> OccName -> SDoc
    -- Print the "M." part of a name, based on whether it's in scope or not
    -- See Note [Printing original names] in GHC.Types.Name.Ppr
    pprModulePrefix :: PprStyle -> Module -> OccName -> SDoc
    pprModulePrefix PprStyle
    sty Module
    mod OccName
    occ = (SDocContext -> Bool) -> SDoc -> SDoc
    ppUnlessOption SDocContext -> Bool
    sdocSuppressModulePrefixes (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
        case PprStyle -> QueryQualifyName
    qualName PprStyle
    sty Module
    mod OccName
    occ of              -- See Outputable.QualifyName:
          NameQual ModuleName
    modname -> ModuleName -> SDoc
    forall doc. IsLine doc => ModuleName -> doc
    pprModuleName ModuleName
    modname SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    dot       -- Name is in scope
          QualifyName
    NameNotInScope1  -> Module -> SDoc
    forall doc. IsLine doc => Module -> doc
    pprModule Module
    mod SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    dot               -- Not in scope
          QualifyName
    NameNotInScope2  -> Unit -> SDoc
    pprUnit (Module -> Unit
    forall unit. GenModule unit -> unit
    moduleUnit Module
    mod) SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    colon           -- Module not in
                              SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> ModuleName -> SDoc
    forall doc. IsLine doc => ModuleName -> doc
    pprModuleName (Module -> ModuleName
    forall unit. GenModule unit -> ModuleName
    moduleName Module
    mod) SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> SDoc
    forall doc. IsLine doc => doc
    dot    -- scope either
          QualifyName
    NameUnqual       -> SDoc
    forall doc. IsOutput doc => doc
    empty                   -- In scope unqualified

    pprUnique :: Unique -> SDoc
    -- Print a unique unless we are suppressing them
    pprUnique :: Unique -> SDoc
    pprUnique Unique
    uniq
      = (SDocContext -> Bool) -> SDoc -> SDoc
    ppUnlessOption SDocContext -> Bool
    sdocSuppressUniques (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
          Unique -> SDoc
    forall doc. IsLine doc => Unique -> doc
    pprUniqueAlways Unique
    uniq

    ppr_underscore_unique :: Unique -> SDoc
    -- Print an underscore separating the name from its unique
    -- But suppress it if we aren't printing the uniques anyway
    ppr_underscore_unique :: Unique -> SDoc
    ppr_underscore_unique Unique
    uniq
      = (SDocContext -> Bool) -> SDoc -> SDoc
    ppUnlessOption SDocContext -> Bool
    sdocSuppressUniques (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $
          Char -> SDoc
    forall doc. IsLine doc => Char -> doc
    char Char
    '_' SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <> Unique -> SDoc
    forall doc. IsLine doc => Unique -> doc
    pprUniqueAlways Unique
    uniq

    ppr_occ_name :: OccName -> SDoc
    ppr_occ_name :: OccName -> SDoc
    ppr_occ_name OccName
    occ = FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext (OccName -> FastString
    occNameFS OccName
    occ)
            -- Don't use pprOccName; instead, just print the string of the OccName;
            -- we print the namespace in the debug stuff above

    -- Prints (if mod information is available) "Defined at <loc>" or
    --  "Defined in <mod>" information for a Name.
    pprDefinedAt :: Name -> SDoc
    pprDefinedAt :: Name -> SDoc
    pprDefinedAt Name
    name = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Defined" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> Name -> SDoc
    pprNameDefnLoc Name
    name

    pprNameDefnLoc :: Name -> SDoc
    -- Prints "at <loc>" or
    --     or "in <mod>" depending on what info is available
    pprNameDefnLoc :: Name -> SDoc
    pprNameDefnLoc Name
    name
      = case Name -> SrcLoc
    nameSrcLoc Name
    name of
             -- nameSrcLoc rather than nameSrcSpan
             -- It seems less cluttered to show a location
             -- rather than a span for the definition point
           RealSrcLoc RealSrcLoc
    s Maybe BufPos
    _ -> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "at" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> RealSrcLoc -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr RealSrcLoc
    s
           UnhelpfulLoc FastString
    s
             | Name -> Bool
    isInternalName Name
    name Bool -> Bool -> Bool
    || Name -> Bool
    isSystemName Name
    name
             -> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "at" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext FastString
    s
             | Bool
    otherwise
             -> String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "in" SDoc -> SDoc -> SDoc
    forall doc. IsLine doc => doc -> doc -> doc
    <+> SDoc -> SDoc
    quotes (Module -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (HasDebugCallStack => Name -> Module
    Name -> Module
    nameModule Name
    name))

    -- | Get a string representation of a 'Name' that's unique and stable
    -- across recompilations. Used for deterministic generation of binds for
    -- derived instances.
    -- eg. "$aeson_70dylHtv1FFGeai1IoxcQr$Data.Aeson.Types.Internal$String"
    nameStableString :: Name -> String
    nameStableString :: Name -> String
    nameStableString Name{OccName
    Unique
    SrcSpan
    NameSort
    n_sort :: Name -> NameSort
    n_occ :: Name -> OccName
    n_uniq :: Name -> Unique
    n_loc :: Name -> SrcSpan
    n_sort :: NameSort
    n_occ :: OccName
    n_uniq :: Unique
    n_loc :: SrcSpan
    ..} =
      NameSort -> String
    nameSortStableString NameSort
    n_sort String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "$" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ OccName -> String
    occNameString OccName
    n_occ

    nameSortStableString :: NameSort -> String
    nameSortStableString :: NameSort -> String
    nameSortStableString NameSort
    System = String
    "$_sys"
    nameSortStableString NameSort
    Internal = String
    "$_in"
    nameSortStableString (External Module
    mod) = Module -> String
    moduleStableString Module
    mod
    nameSortStableString (WiredIn Module
    mod TyThing
    _ BuiltInSyntax
    _) = Module -> String
    moduleStableString Module
    mod

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Overloaded functions related to Names}
    *                                                                      *
    ************************************************************************
    -}

    -- | A class allowing convenient access to the 'Name' of various datatypes
    class NamedThing a where
        getOccName :: a -> OccName
        getName    :: a -> Name

        getOccName a
    n = Name -> OccName
    nameOccName (a -> Name
    forall a. NamedThing a => a -> Name
    getName a
    n)      -- Default method

    instance NamedThing e => NamedThing (Located e) where
        getName :: Located e -> Name
    getName = e -> Name
    forall a. NamedThing a => a -> Name
    getName (e -> Name) -> (Located e -> e) -> Located e -> Name
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Located e -> e
    forall l e. GenLocated l e -> e
    unLoc

    getSrcLoc           :: NamedThing a => a -> SrcLoc
    getSrcSpan          :: NamedThing a => a -> SrcSpan
    getOccString        :: NamedThing a => a -> String
    getOccFS            :: NamedThing a => a -> FastString

    getSrcLoc :: forall a. NamedThing a => a -> SrcLoc
    getSrcLoc           = Name -> SrcLoc
    nameSrcLoc           (Name -> SrcLoc) -> (a -> Name) -> a -> SrcLoc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Name
    forall a. NamedThing a => a -> Name
    getName
    getSrcSpan :: forall a. NamedThing a => a -> SrcSpan
    getSrcSpan          = Name -> SrcSpan
    nameSrcSpan          (Name -> SrcSpan) -> (a -> Name) -> a -> SrcSpan
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Name
    forall a. NamedThing a => a -> Name
    getName
    getOccString :: forall a. NamedThing a => a -> String
    getOccString        = OccName -> String
    occNameString        (OccName -> String) -> (a -> OccName) -> a -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> OccName
    forall a. NamedThing a => a -> OccName
    getOccName
    getOccFS :: forall a. NamedThing a => a -> FastString
    getOccFS            = OccName -> FastString
    occNameFS            (OccName -> FastString) -> (a -> OccName) -> a -> FastString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> OccName
    forall a. NamedThing a => a -> OccName
    getOccName

    pprInfixName :: (Outputable a, NamedThing a) => a -> SDoc
    -- See Outputable.pprPrefixVar, pprInfixVar;
    -- add parens or back-quotes as appropriate
    pprInfixName :: forall a. (Outputable a, NamedThing a) => a -> SDoc
    pprInfixName  a
    n = Bool -> SDoc -> SDoc
    pprInfixVar (OccName -> Bool
    isSymOcc (a -> OccName
    forall a. NamedThing a => a -> OccName
    getOccName a
    n)) (a -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr a
    n)

    pprPrefixName :: NamedThing a => a -> SDoc
    pprPrefixName :: forall a. NamedThing a => a -> SDoc
    pprPrefixName a
    thing = Bool -> SDoc -> SDoc
    pprPrefixVar (OccName -> Bool
    isSymOcc (Name -> OccName
    nameOccName Name
    name)) (Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    name)
     where
       name :: Name
    name = a -> Name
    forall a. NamedThing a => a -> Name
    getName a
    thing