    {-
    (c) The AQUA Project, Glasgow University, 1994-1998

    Wired-in knowledge about primitive types
    -}

    {-# LANGUAGE CPP #-}
    {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}

    -- | This module defines TyCons that can't be expressed in Haskell.
    --   They are all, therefore, wired-in TyCons.  C.f module "GHC.Builtin.Types"
    module GHC.Builtin.Types.Prim(
            mkPrimTyConName, -- For implicit parameters in GHC.Builtin.Types only

            mkTemplateKindVars, mkTemplateTyVars, mkTemplateTyVarsFrom,
            mkTemplateKiTyVars, mkTemplateKiTyVar,

            mkTemplateTyConBinders, mkTemplateKindTyConBinders,
            mkTemplateAnonTyConBinders,

            alphaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
            alphaTys, alphaTy, betaTy, gammaTy, deltaTy,
            alphaTyVarsUnliftedRep, alphaTyVarUnliftedRep,
            alphaTysUnliftedRep, alphaTyUnliftedRep,
            runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep3TyVar,
            runtimeRep1Ty, runtimeRep2Ty, runtimeRep3Ty,

            openAlphaTyVar, openBetaTyVar, openGammaTyVar,
            openAlphaTy, openBetaTy, openGammaTy,

            multiplicityTyVar1, multiplicityTyVar2,

            -- Kind constructors...
            tYPETyCon, tYPETyConName,

            -- Kinds
            tYPE, primRepToRuntimeRep,

            functionWithMultiplicity,
            funTyCon, funTyConName,
            unexposedPrimTyCons, exposedPrimTyCons, primTyCons,

            charPrimTyCon,          charPrimTy, charPrimTyConName,
            intPrimTyCon,           intPrimTy, intPrimTyConName,
            wordPrimTyCon,          wordPrimTy, wordPrimTyConName,
            addrPrimTyCon,          addrPrimTy, addrPrimTyConName,
            floatPrimTyCon,         floatPrimTy, floatPrimTyConName,
            doublePrimTyCon,        doublePrimTy, doublePrimTyConName,

            statePrimTyCon,         mkStatePrimTy,
            realWorldTyCon,         realWorldTy, realWorldStatePrimTy,

            proxyPrimTyCon,         mkProxyPrimTy,

            arrayPrimTyCon, mkArrayPrimTy,
            byteArrayPrimTyCon,     byteArrayPrimTy,
            arrayArrayPrimTyCon, mkArrayArrayPrimTy,
            smallArrayPrimTyCon, mkSmallArrayPrimTy,
            mutableArrayPrimTyCon, mkMutableArrayPrimTy,
            mutableByteArrayPrimTyCon, mkMutableByteArrayPrimTy,
            mutableArrayArrayPrimTyCon, mkMutableArrayArrayPrimTy,
            smallMutableArrayPrimTyCon, mkSmallMutableArrayPrimTy,
            mutVarPrimTyCon, mkMutVarPrimTy,

            mVarPrimTyCon,                  mkMVarPrimTy,
            ioPortPrimTyCon,                mkIOPortPrimTy,
            tVarPrimTyCon,                  mkTVarPrimTy,
            stablePtrPrimTyCon,             mkStablePtrPrimTy,
            stableNamePrimTyCon,            mkStableNamePrimTy,
            compactPrimTyCon,               compactPrimTy,
            bcoPrimTyCon,                   bcoPrimTy,
            weakPrimTyCon,                  mkWeakPrimTy,
            threadIdPrimTyCon,              threadIdPrimTy,

            int8PrimTyCon,          int8PrimTy, int8PrimTyConName,
            word8PrimTyCon,         word8PrimTy, word8PrimTyConName,

            int16PrimTyCon,         int16PrimTy, int16PrimTyConName,
            word16PrimTyCon,        word16PrimTy, word16PrimTyConName,

            int32PrimTyCon,         int32PrimTy, int32PrimTyConName,
            word32PrimTyCon,        word32PrimTy, word32PrimTyConName,

            int64PrimTyCon,         int64PrimTy, int64PrimTyConName,
            word64PrimTyCon,        word64PrimTy, word64PrimTyConName,

            eqPrimTyCon,            -- ty1 ~# ty2
            eqReprPrimTyCon,        -- ty1 ~R# ty2  (at role Representational)
            eqPhantPrimTyCon,       -- ty1 ~P# ty2  (at role Phantom)
            equalityTyCon,

            -- * SIMD
    #include "primop-vector-tys-exports.hs-incl"
      ) where

    #include "HsVersions.h"

    import GHC.Prelude

    import {-# SOURCE #-} GHC.Builtin.Types
      ( runtimeRepTy, unboxedTupleKind, liftedTypeKind
      , vecRepDataConTyCon, tupleRepDataConTyCon
      , liftedRepTy, unliftedRepTy
      , intRepDataConTy
      , int8RepDataConTy, int16RepDataConTy, int32RepDataConTy, int64RepDataConTy
      , wordRepDataConTy
      , word16RepDataConTy, word8RepDataConTy, word32RepDataConTy, word64RepDataConTy
      , addrRepDataConTy
      , floatRepDataConTy, doubleRepDataConTy
      , vec2DataConTy, vec4DataConTy, vec8DataConTy, vec16DataConTy, vec32DataConTy
      , vec64DataConTy
      , int8ElemRepDataConTy, int16ElemRepDataConTy, int32ElemRepDataConTy
      , int64ElemRepDataConTy, word8ElemRepDataConTy, word16ElemRepDataConTy
      , word32ElemRepDataConTy, word64ElemRepDataConTy, floatElemRepDataConTy
      , doubleElemRepDataConTy
      , mkPromotedListTy, multiplicityTy )

    import GHC.Types.Var    ( TyVar, mkTyVar )
    import GHC.Types.Name
    import {-# SOURCE #-} GHC.Types.TyThing
    import GHC.Core.TyCon
    import GHC.Types.SrcLoc
    import GHC.Types.Unique
    import GHC.Builtin.Uniques
    import GHC.Builtin.Names
    import GHC.Data.FastString
    import GHC.Utils.Outputable
    import GHC.Utils.Panic
    import GHC.Core.TyCo.Rep -- Doesn't need special access, but this is easier to avoid
                             -- import loops which show up if you import Type instead
    import {-# SOURCE #-} GHC.Core.Type ( mkTyConTy, tYPE )

    import Data.Char

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Primitive type constructors}
    *                                                                      *
    ************************************************************************
    -}

    primTyCons :: [TyCon]
    primTyCons :: [TyCon]
    primTyCons = [TyCon]
    unexposedPrimTyCons [TyCon] -> [TyCon] -> [TyCon]
    forall a. [a] -> [a] -> [a]
    ++ [TyCon]
    exposedPrimTyCons

    -- | Primitive 'TyCon's that are defined in GHC.Prim but not exposed.
    -- It's important to keep these separate as we don't want users to be able to
    -- write them (see #15209) or see them in GHCi's @:browse@ output
    -- (see #12023).
    unexposedPrimTyCons :: [TyCon]
    unexposedPrimTyCons :: [TyCon]
    unexposedPrimTyCons
      = [ TyCon
    eqPrimTyCon
        , TyCon
    eqReprPrimTyCon
        , TyCon
    eqPhantPrimTyCon
        ]

    -- | Primitive 'TyCon's that are defined in, and exported from, GHC.Prim.
    exposedPrimTyCons :: [TyCon]
    exposedPrimTyCons :: [TyCon]
    exposedPrimTyCons
      = [ TyCon
    addrPrimTyCon
        , TyCon
    arrayPrimTyCon
        , TyCon
    byteArrayPrimTyCon
        , TyCon
    arrayArrayPrimTyCon
        , TyCon
    smallArrayPrimTyCon
        , TyCon
    charPrimTyCon
        , TyCon
    doublePrimTyCon
        , TyCon
    floatPrimTyCon
        , TyCon
    intPrimTyCon
        , TyCon
    int8PrimTyCon
        , TyCon
    int16PrimTyCon
        , TyCon
    int32PrimTyCon
        , TyCon
    int64PrimTyCon
        , TyCon
    bcoPrimTyCon
        , TyCon
    weakPrimTyCon
        , TyCon
    mutableArrayPrimTyCon
        , TyCon
    mutableByteArrayPrimTyCon
        , TyCon
    mutableArrayArrayPrimTyCon
        , TyCon
    smallMutableArrayPrimTyCon
        , TyCon
    mVarPrimTyCon
        , TyCon
    ioPortPrimTyCon
        , TyCon
    tVarPrimTyCon
        , TyCon
    mutVarPrimTyCon
        , TyCon
    realWorldTyCon
        , TyCon
    stablePtrPrimTyCon
        , TyCon
    stableNamePrimTyCon
        , TyCon
    compactPrimTyCon
        , TyCon
    statePrimTyCon
        , TyCon
    proxyPrimTyCon
        , TyCon
    threadIdPrimTyCon
        , TyCon
    wordPrimTyCon
        , TyCon
    word8PrimTyCon
        , TyCon
    word16PrimTyCon
        , TyCon
    word32PrimTyCon
        , TyCon
    word64PrimTyCon

        , TyCon
    tYPETyCon
        , TyCon
    funTyCon

    #include "primop-vector-tycons.hs-incl"
        ]

    mkPrimTc :: FastString -> Unique -> TyCon -> Name
    mkPrimTc :: FastString -> Unique -> TyCon -> Name
    mkPrimTc FastString
    fs Unique
    unique TyCon
    tycon
      = Module -> OccName -> Unique -> TyThing -> BuiltInSyntax -> Name
    mkWiredInName Module
    gHC_PRIM (FastString -> OccName
    mkTcOccFS FastString
    fs)
                      Unique
    unique
                      (TyCon -> TyThing
    mkATyCon TyCon
    tycon)        -- Relevant TyCon
                      BuiltInSyntax
    UserSyntax

    mkBuiltInPrimTc :: FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc :: FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc FastString
    fs Unique
    unique TyCon
    tycon
      = Module -> OccName -> Unique -> TyThing -> BuiltInSyntax -> Name
    mkWiredInName Module
    gHC_PRIM (FastString -> OccName
    mkTcOccFS FastString
    fs)
                      Unique
    unique
                      (TyCon -> TyThing
    mkATyCon TyCon
    tycon)        -- Relevant TyCon
                      BuiltInSyntax
    BuiltInSyntax

    charPrimTyConName, intPrimTyConName, int8PrimTyConName, int16PrimTyConName, int32PrimTyConName, int64PrimTyConName, wordPrimTyConName, word32PrimTyConName, word8PrimTyConName, word16PrimTyConName, word64PrimTyConName, addrPrimTyConName, floatPrimTyConName, doublePrimTyConName, statePrimTyConName, proxyPrimTyConName, realWorldTyConName, arrayPrimTyConName, arrayArrayPrimTyConName, smallArrayPrimTyConName, byteArrayPrimTyConName, mutableArrayPrimTyConName, mutableByteArrayPrimTyConName, mutableArrayArrayPrimTyConName, smallMutableArrayPrimTyConName, mutVarPrimTyConName, mVarPrimTyConName, ioPortPrimTyConName, tVarPrimTyConName, stablePtrPrimTyConName, stableNamePrimTyConName, compactPrimTyConName, bcoPrimTyConName, weakPrimTyConName, threadIdPrimTyConName, eqPrimTyConName, eqReprPrimTyConName, eqPhantPrimTyConName :: Name
    charPrimTyConName :: Name
    charPrimTyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Char#") Unique
    charPrimTyConKey TyCon
    charPrimTyCon
    intPrimTyConName :: Name
    intPrimTyConName              = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Int#") Unique
    intPrimTyConKey  TyCon
    intPrimTyCon
    int8PrimTyConName :: Name
    int8PrimTyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Int8#") Unique
    int8PrimTyConKey TyCon
    int8PrimTyCon
    int16PrimTyConName :: Name
    int16PrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Int16#") Unique
    int16PrimTyConKey TyCon
    int16PrimTyCon
    int32PrimTyConName :: Name
    int32PrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Int32#") Unique
    int32PrimTyConKey TyCon
    int32PrimTyCon
    int64PrimTyConName :: Name
    int64PrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Int64#") Unique
    int64PrimTyConKey TyCon
    int64PrimTyCon
    wordPrimTyConName :: Name
    wordPrimTyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Word#") Unique
    wordPrimTyConKey TyCon
    wordPrimTyCon
    word8PrimTyConName :: Name
    word8PrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Word8#") Unique
    word8PrimTyConKey TyCon
    word8PrimTyCon
    word16PrimTyConName :: Name
    word16PrimTyConName           = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Word16#") Unique
    word16PrimTyConKey TyCon
    word16PrimTyCon
    word32PrimTyConName :: Name
    word32PrimTyConName           = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Word32#") Unique
    word32PrimTyConKey TyCon
    word32PrimTyCon
    word64PrimTyConName :: Name
    word64PrimTyConName           = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Word64#") Unique
    word64PrimTyConKey TyCon
    word64PrimTyCon
    addrPrimTyConName :: Name
    addrPrimTyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Addr#") Unique
    addrPrimTyConKey TyCon
    addrPrimTyCon
    floatPrimTyConName :: Name
    floatPrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Float#") Unique
    floatPrimTyConKey TyCon
    floatPrimTyCon
    doublePrimTyConName :: Name
    doublePrimTyConName           = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Double#") Unique
    doublePrimTyConKey TyCon
    doublePrimTyCon
    statePrimTyConName :: Name
    statePrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "State#") Unique
    statePrimTyConKey TyCon
    statePrimTyCon
    proxyPrimTyConName :: Name
    proxyPrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Proxy#") Unique
    proxyPrimTyConKey TyCon
    proxyPrimTyCon
    eqPrimTyConName :: Name
    eqPrimTyConName               = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "~#") Unique
    eqPrimTyConKey TyCon
    eqPrimTyCon
    eqReprPrimTyConName :: Name
    eqReprPrimTyConName           = FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc (String -> FastString
    fsLit String
    "~R#") Unique
    eqReprPrimTyConKey TyCon
    eqReprPrimTyCon
    eqPhantPrimTyConName :: Name
    eqPhantPrimTyConName          = FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc (String -> FastString
    fsLit String
    "~P#") Unique
    eqPhantPrimTyConKey TyCon
    eqPhantPrimTyCon
    realWorldTyConName :: Name
    realWorldTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "RealWorld") Unique
    realWorldTyConKey TyCon
    realWorldTyCon
    arrayPrimTyConName :: Name
    arrayPrimTyConName            = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Array#") Unique
    arrayPrimTyConKey TyCon
    arrayPrimTyCon
    byteArrayPrimTyConName :: Name
    byteArrayPrimTyConName        = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "ByteArray#") Unique
    byteArrayPrimTyConKey TyCon
    byteArrayPrimTyCon
    arrayArrayPrimTyConName :: Name
    arrayArrayPrimTyConName       = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "ArrayArray#") Unique
    arrayArrayPrimTyConKey TyCon
    arrayArrayPrimTyCon
    smallArrayPrimTyConName :: Name
    smallArrayPrimTyConName       = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "SmallArray#") Unique
    smallArrayPrimTyConKey TyCon
    smallArrayPrimTyCon
    mutableArrayPrimTyConName :: Name
    mutableArrayPrimTyConName     = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "MutableArray#") Unique
    mutableArrayPrimTyConKey TyCon
    mutableArrayPrimTyCon
    mutableByteArrayPrimTyConName :: Name
    mutableByteArrayPrimTyConName = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "MutableByteArray#") Unique
    mutableByteArrayPrimTyConKey TyCon
    mutableByteArrayPrimTyCon
    mutableArrayArrayPrimTyConName :: Name
    mutableArrayArrayPrimTyConName= FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "MutableArrayArray#") Unique
    mutableArrayArrayPrimTyConKey TyCon
    mutableArrayArrayPrimTyCon
    smallMutableArrayPrimTyConName :: Name
    smallMutableArrayPrimTyConName= FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "SmallMutableArray#") Unique
    smallMutableArrayPrimTyConKey TyCon
    smallMutableArrayPrimTyCon
    mutVarPrimTyConName :: Name
    mutVarPrimTyConName           = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "MutVar#") Unique
    mutVarPrimTyConKey TyCon
    mutVarPrimTyCon
    ioPortPrimTyConName :: Name
    ioPortPrimTyConName           = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "IOPort#") Unique
    ioPortPrimTyConKey TyCon
    ioPortPrimTyCon
    mVarPrimTyConName :: Name
    mVarPrimTyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "MVar#") Unique
    mVarPrimTyConKey TyCon
    mVarPrimTyCon
    tVarPrimTyConName :: Name
    tVarPrimTyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "TVar#") Unique
    tVarPrimTyConKey TyCon
    tVarPrimTyCon
    stablePtrPrimTyConName :: Name
    stablePtrPrimTyConName        = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "StablePtr#") Unique
    stablePtrPrimTyConKey TyCon
    stablePtrPrimTyCon
    stableNamePrimTyConName :: Name
    stableNamePrimTyConName       = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "StableName#") Unique
    stableNamePrimTyConKey TyCon
    stableNamePrimTyCon
    compactPrimTyConName :: Name
    compactPrimTyConName          = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Compact#") Unique
    compactPrimTyConKey TyCon
    compactPrimTyCon
    bcoPrimTyConName :: Name
    bcoPrimTyConName              = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "BCO") Unique
    bcoPrimTyConKey TyCon
    bcoPrimTyCon
    weakPrimTyConName :: Name
    weakPrimTyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "Weak#") Unique
    weakPrimTyConKey TyCon
    weakPrimTyCon
    threadIdPrimTyConName :: Name
    threadIdPrimTyConName         = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "ThreadId#") Unique
    threadIdPrimTyConKey TyCon
    threadIdPrimTyCon

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Support code}
    *                                                                      *
    ************************************************************************

    alphaTyVars is a list of type variables for use in templates:
            ["a", "b", ..., "z", "t1", "t2", ... ]
    -}

    mkTemplateKindVar :: Kind -> TyVar
    mkTemplateKindVar :: Kind -> TyVar
    mkTemplateKindVar = Name -> Kind -> TyVar
    mkTyVar (Int -> String -> Name
    mk_tv_name Int
    0 String
    "k")

    mkTemplateKindVars :: [Kind] -> [TyVar]
    -- k0  with unique (mkAlphaTyVarUnique 0)
    -- k1  with unique (mkAlphaTyVarUnique 1)
    -- ... etc
    mkTemplateKindVars :: [Kind] -> [TyVar]
    mkTemplateKindVars [Kind
    kind] = [Kind -> TyVar
    mkTemplateKindVar Kind
    kind]
      -- Special case for one kind: just "k"
    mkTemplateKindVars [Kind]
    kinds
      = [ Name -> Kind -> TyVar
    mkTyVar (Int -> String -> Name
    mk_tv_name Int
    u (Char
    'k' Char -> String -> String
    forall a. a -> [a] -> [a]
    : Int -> String
    forall a. Show a => a -> String
    show Int
    u)) Kind
    kind
        | (Kind
    kind, Int
    u) <- [Kind]
    kinds [Kind] -> [Int] -> [(Kind, Int)]
    forall a b. [a] -> [b] -> [(a, b)]
    `zip` [Int
    0..] ]
    mk_tv_name :: Int -> String -> Name
    mk_tv_name :: Int -> String -> Name
    mk_tv_name Int
    u String
    s = Unique -> OccName -> SrcSpan -> Name
    mkInternalName (Int -> Unique
    mkAlphaTyVarUnique Int
    u)
                                    (FastString -> OccName
    mkTyVarOccFS (String -> FastString
    mkFastString String
    s))
                                    SrcSpan
    noSrcSpan

    mkTemplateTyVarsFrom :: Int -> [Kind] -> [TyVar]
    -- a  with unique (mkAlphaTyVarUnique n)
    -- b  with unique (mkAlphaTyVarUnique n+1)
    -- ... etc
    -- Typically called as
    --   mkTemplateTyVarsFrom (length kv_bndrs) kinds
    -- where kv_bndrs are the kind-level binders of a TyCon
    mkTemplateTyVarsFrom :: Int -> [Kind] -> [TyVar]
    mkTemplateTyVarsFrom Int
    n [Kind]
    kinds
      = [ Name -> Kind -> TyVar
    mkTyVar Name
    name Kind
    kind
        | (Kind
    kind, Int
    index) <- [Kind] -> [Int] -> [(Kind, Int)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Kind]
    kinds [Int
    0..],
          let ch_ord :: Int
    ch_ord = Int
    index Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Char -> Int
    ord Char
    'a'
              name_str :: String
    name_str | Int
    ch_ord Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char -> Int
    ord Char
    'z' = [Int -> Char
    chr Int
    ch_ord]
                       | Bool
    otherwise         = Char
    't'Char -> String -> String
    forall a. a -> [a] -> [a]
    :Int -> String
    forall a. Show a => a -> String
    show Int
    index
              name :: Name
    name = Int -> String -> Name
    mk_tv_name (Int
    index Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    n) String
    name_str
        ]

    mkTemplateTyVars :: [Kind] -> [TyVar]
    mkTemplateTyVars :: [Kind] -> [TyVar]
    mkTemplateTyVars = Int -> [Kind] -> [TyVar]
    mkTemplateTyVarsFrom Int
    1

    mkTemplateTyConBinders
        :: [Kind]                -- [k1, .., kn]   Kinds of kind-forall'd vars
        -> ([Kind] -> [Kind])    -- Arg is [kv1:k1, ..., kvn:kn]
                                 --     same length as first arg
                                 -- Result is anon arg kinds
        -> [TyConBinder]
    mkTemplateTyConBinders :: [Kind] -> ([Kind] -> [Kind]) -> [TyConBinder]
    mkTemplateTyConBinders [Kind]
    kind_var_kinds [Kind] -> [Kind]
    mk_anon_arg_kinds
      = [TyConBinder]
    kv_bndrs [TyConBinder] -> [TyConBinder] -> [TyConBinder]
    forall a. [a] -> [a] -> [a]
    ++ [TyConBinder]
    tv_bndrs
      where
        kv_bndrs :: [TyConBinder]
    kv_bndrs   = [Kind] -> [TyConBinder]
    mkTemplateKindTyConBinders [Kind]
    kind_var_kinds
        anon_kinds :: [Kind]
    anon_kinds = [Kind] -> [Kind]
    mk_anon_arg_kinds ([TyVar] -> [Kind]
    mkTyVarTys ([TyConBinder] -> [TyVar]
    forall tv argf. [VarBndr tv argf] -> [tv]
    binderVars [TyConBinder]
    kv_bndrs))
        tv_bndrs :: [TyConBinder]
    tv_bndrs   = Int -> [Kind] -> [TyConBinder]
    mkTemplateAnonTyConBindersFrom ([TyConBinder] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [TyConBinder]
    kv_bndrs) [Kind]
    anon_kinds

    mkTemplateKiTyVars
        :: [Kind]                -- [k1, .., kn]   Kinds of kind-forall'd vars
        -> ([Kind] -> [Kind])    -- Arg is [kv1:k1, ..., kvn:kn]
                                 --     same length as first arg
                                 -- Result is anon arg kinds [ak1, .., akm]
        -> [TyVar]   -- [kv1:k1, ..., kvn:kn, av1:ak1, ..., avm:akm]
    -- Example: if you want the tyvars for
    --   forall (r:RuntimeRep) (a:TYPE r) (b:*). blah
    -- call mkTemplateKiTyVars [RuntimeRep] (\[r] -> [TYPE r, *])
    mkTemplateKiTyVars :: [Kind] -> ([Kind] -> [Kind]) -> [TyVar]
    mkTemplateKiTyVars [Kind]
    kind_var_kinds [Kind] -> [Kind]
    mk_arg_kinds
      = [TyVar]
    kv_bndrs [TyVar] -> [TyVar] -> [TyVar]
    forall a. [a] -> [a] -> [a]
    ++ [TyVar]
    tv_bndrs
      where
        kv_bndrs :: [TyVar]
    kv_bndrs   = [Kind] -> [TyVar]
    mkTemplateKindVars [Kind]
    kind_var_kinds
        anon_kinds :: [Kind]
    anon_kinds = [Kind] -> [Kind]
    mk_arg_kinds ([TyVar] -> [Kind]
    mkTyVarTys [TyVar]
    kv_bndrs)
        tv_bndrs :: [TyVar]
    tv_bndrs   = Int -> [Kind] -> [TyVar]
    mkTemplateTyVarsFrom ([TyVar] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [TyVar]
    kv_bndrs) [Kind]
    anon_kinds

    mkTemplateKiTyVar
        :: Kind                  -- [k1, .., kn]   Kind of kind-forall'd var
        -> (Kind -> [Kind])      -- Arg is kv1:k1
                                 -- Result is anon arg kinds [ak1, .., akm]
        -> [TyVar]   -- [kv1:k1, ..., kvn:kn, av1:ak1, ..., avm:akm]
    -- Example: if you want the tyvars for
    --   forall (r:RuntimeRep) (a:TYPE r) (b:*). blah
    -- call mkTemplateKiTyVar RuntimeRep (\r -> [TYPE r, *])
    mkTemplateKiTyVar :: Kind -> (Kind -> [Kind]) -> [TyVar]
    mkTemplateKiTyVar Kind
    kind Kind -> [Kind]
    mk_arg_kinds
      = TyVar
    kv_bndr TyVar -> [TyVar] -> [TyVar]
    forall a. a -> [a] -> [a]
    : [TyVar]
    tv_bndrs
      where
        kv_bndr :: TyVar
    kv_bndr    = Kind -> TyVar
    mkTemplateKindVar Kind
    kind
        anon_kinds :: [Kind]
    anon_kinds = Kind -> [Kind]
    mk_arg_kinds (TyVar -> Kind
    mkTyVarTy TyVar
    kv_bndr)
        tv_bndrs :: [TyVar]
    tv_bndrs   = Int -> [Kind] -> [TyVar]
    mkTemplateTyVarsFrom Int
    1 [Kind]
    anon_kinds

    mkTemplateKindTyConBinders :: [Kind] -> [TyConBinder]
    -- Makes named, Specified binders
    mkTemplateKindTyConBinders :: [Kind] -> [TyConBinder]
    mkTemplateKindTyConBinders [Kind]
    kinds = [ArgFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ArgFlag
    Specified TyVar
    tv | TyVar
    tv <- [Kind] -> [TyVar]
    mkTemplateKindVars [Kind]
    kinds]

    mkTemplateAnonTyConBinders :: [Kind] -> [TyConBinder]
    mkTemplateAnonTyConBinders :: [Kind] -> [TyConBinder]
    mkTemplateAnonTyConBinders [Kind]
    kinds = AnonArgFlag -> [TyVar] -> [TyConBinder]
    mkAnonTyConBinders AnonArgFlag
    VisArg ([Kind] -> [TyVar]
    mkTemplateTyVars [Kind]
    kinds)

    mkTemplateAnonTyConBindersFrom :: Int -> [Kind] -> [TyConBinder]
    mkTemplateAnonTyConBindersFrom :: Int -> [Kind] -> [TyConBinder]
    mkTemplateAnonTyConBindersFrom Int
    n [Kind]
    kinds = AnonArgFlag -> [TyVar] -> [TyConBinder]
    mkAnonTyConBinders AnonArgFlag
    VisArg (Int -> [Kind] -> [TyVar]
    mkTemplateTyVarsFrom Int
    n [Kind]
    kinds)

    alphaTyVars :: [TyVar]
    alphaTyVars :: [TyVar]
    alphaTyVars = [Kind] -> [TyVar]
    mkTemplateTyVars ([Kind] -> [TyVar]) -> [Kind] -> [TyVar]
    forall a b. (a -> b) -> a -> b
    $ Kind -> [Kind]
    forall a. a -> [a]
    repeat Kind
    liftedTypeKind

    alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar :: TyVar
    (TyVar
    alphaTyVar:TyVar
    betaTyVar:TyVar
    gammaTyVar:TyVar
    deltaTyVar:[TyVar]
    _) = [TyVar]
    alphaTyVars

    alphaTys :: [Type]
    alphaTys :: [Kind]
    alphaTys = [TyVar] -> [Kind]
    mkTyVarTys [TyVar]
    alphaTyVars
    alphaTy, betaTy, gammaTy, deltaTy :: Type
    (Kind
    alphaTy:Kind
    betaTy:Kind
    gammaTy:Kind
    deltaTy:[Kind]
    _) = [Kind]
    alphaTys

    alphaTyVarsUnliftedRep :: [TyVar]
    alphaTyVarsUnliftedRep :: [TyVar]
    alphaTyVarsUnliftedRep = [Kind] -> [TyVar]
    mkTemplateTyVars ([Kind] -> [TyVar]) -> [Kind] -> [TyVar]
    forall a b. (a -> b) -> a -> b
    $ Kind -> [Kind]
    forall a. a -> [a]
    repeat (Kind -> Kind
    tYPE Kind
    unliftedRepTy)

    alphaTyVarUnliftedRep :: TyVar
    (TyVar
    alphaTyVarUnliftedRep:[TyVar]
    _) = [TyVar]
    alphaTyVarsUnliftedRep

    alphaTysUnliftedRep :: [Type]
    alphaTysUnliftedRep :: [Kind]
    alphaTysUnliftedRep = [TyVar] -> [Kind]
    mkTyVarTys [TyVar]
    alphaTyVarsUnliftedRep
    alphaTyUnliftedRep :: Type
    (Kind
    alphaTyUnliftedRep:[Kind]
    _) = [Kind]
    alphaTysUnliftedRep

    runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep3TyVar :: TyVar
    (TyVar
    runtimeRep1TyVar : TyVar
    runtimeRep2TyVar : TyVar
    runtimeRep3TyVar : [TyVar]
    _)
      = Int -> [TyVar] -> [TyVar]
    forall a. Int -> [a] -> [a]
    drop Int
    16 ([Kind] -> [TyVar]
    mkTemplateTyVars (Kind -> [Kind]
    forall a. a -> [a]
    repeat Kind
    runtimeRepTy))  -- selects 'q','r'

    runtimeRep1Ty, runtimeRep2Ty, runtimeRep3Ty :: Type
    runtimeRep1Ty :: Kind
    runtimeRep1Ty = TyVar -> Kind
    mkTyVarTy TyVar
    runtimeRep1TyVar
    runtimeRep2Ty :: Kind
    runtimeRep2Ty = TyVar -> Kind
    mkTyVarTy TyVar
    runtimeRep2TyVar
    runtimeRep3Ty :: Kind
    runtimeRep3Ty = TyVar -> Kind
    mkTyVarTy TyVar
    runtimeRep3TyVar

    openAlphaTyVar, openBetaTyVar, openGammaTyVar :: TyVar
    -- alpha :: TYPE r1
    -- beta  :: TYPE r2
    -- gamma :: TYPE r3
    [TyVar
    openAlphaTyVar,TyVar
    openBetaTyVar,TyVar
    openGammaTyVar]
      = [Kind] -> [TyVar]
    mkTemplateTyVars [Kind -> Kind
    tYPE Kind
    runtimeRep1Ty, Kind -> Kind
    tYPE Kind
    runtimeRep2Ty, Kind -> Kind
    tYPE Kind
    runtimeRep3Ty]

    openAlphaTy, openBetaTy, openGammaTy :: Type
    openAlphaTy :: Kind
    openAlphaTy = TyVar -> Kind
    mkTyVarTy TyVar
    openAlphaTyVar
    openBetaTy :: Kind
    openBetaTy  = TyVar -> Kind
    mkTyVarTy TyVar
    openBetaTyVar
    openGammaTy :: Kind
    openGammaTy = TyVar -> Kind
    mkTyVarTy TyVar
    openGammaTyVar

    multiplicityTyVar1, multiplicityTyVar2  :: TyVar
    (TyVar
    multiplicityTyVar1 : TyVar
    multiplicityTyVar2 : [TyVar]
    _)
       = Int -> [TyVar] -> [TyVar]
    forall a. Int -> [a] -> [a]
    drop Int
    13 ([Kind] -> [TyVar]
    mkTemplateTyVars (Kind -> [Kind]
    forall a. a -> [a]
    repeat Kind
    multiplicityTy))  -- selects 'n', 'm'

    {-
    ************************************************************************
    *                                                                      *
                    FunTyCon
    *                                                                      *
    ************************************************************************
    -}

    funTyConName :: Name
    funTyConName :: Name
    funTyConName = FastString -> Unique -> TyCon -> Name
    mkPrimTyConName (String -> FastString
    fsLit String
    "FUN") Unique
    funTyConKey TyCon
    funTyCon

    -- | The @FUN@ type constructor.
    --
    -- @
    -- FUN :: forall (m :: Multiplicity) ->
    --        forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
    --        TYPE rep1 -> TYPE rep2 -> *
    -- @
    --
    -- The runtime representations quantification is left inferred. This
    -- means they cannot be specified with @-XTypeApplications@.
    --
    -- This is a deliberate choice to allow future extensions to the
    -- function arrow. To allow visible application a type synonym can be
    -- defined:
    --
    -- @
    -- type Arr :: forall (rep1 :: RuntimeRep) (rep2 :: RuntimeRep).
    --             TYPE rep1 -> TYPE rep2 -> Type
    -- type Arr = FUN 'Many
    -- @
    --
    funTyCon :: TyCon
    funTyCon :: TyCon
    funTyCon = Name -> [TyConBinder] -> Name -> TyCon
    mkFunTyCon Name
    funTyConName [TyConBinder]
    tc_bndrs Name
    tc_rep_nm
      where
        -- See also unrestrictedFunTyCon
        tc_bndrs :: [TyConBinder]
    tc_bndrs = [ ArgFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ArgFlag
    Required TyVar
    multiplicityTyVar1
                   , ArgFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ArgFlag
    Inferred TyVar
    runtimeRep1TyVar
                   , ArgFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ArgFlag
    Inferred TyVar
    runtimeRep2TyVar ]
                   [TyConBinder] -> [TyConBinder] -> [TyConBinder]
    forall a. [a] -> [a] -> [a]
    ++ [Kind] -> [TyConBinder]
    mkTemplateAnonTyConBinders [ Kind -> Kind
    tYPE Kind
    runtimeRep1Ty
                                                 , Kind -> Kind
    tYPE Kind
    runtimeRep2Ty
                                                 ]
        tc_rep_nm :: Name
    tc_rep_nm = Name -> Name
    mkPrelTyConRepName Name
    funTyConName

    {-
    ************************************************************************
    *                                                                      *
                    Kinds
    *                                                                      *
    ************************************************************************

    Note [TYPE and RuntimeRep]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
    All types that classify values have a kind of the form (TYPE rr), where

        data RuntimeRep     -- Defined in ghc-prim:GHC.Types
          = BoxedRep Levity
          | IntRep
          | FloatRep
          .. etc ..

        data Levity = Lifted | Unlifted

        rr :: RuntimeRep

        TYPE :: RuntimeRep -> TYPE 'LiftedRep  -- Built in

    So for example:
        Int        :: TYPE ('BoxedRep 'Lifted)
        Array# Int :: TYPE ('BoxedRep 'Unlifted)
        Int#       :: TYPE 'IntRep
        Float#     :: TYPE 'FloatRep
        Maybe      :: TYPE ('BoxedRep 'Lifted) -> TYPE ('BoxedRep 'Lifted)
        (# , #)    :: TYPE r1 -> TYPE r2 -> TYPE (TupleRep [r1, r2])

    We abbreviate '*' specially:
        type LiftedRep = 'BoxedRep 'Lifted
        type * = TYPE LiftedRep

    The 'rr' parameter tells us how the value is represented at runtime.

    Generally speaking, you can't be polymorphic in 'rr'.  E.g
       f :: forall (rr:RuntimeRep) (a:TYPE rr). a -> [a]
       f = /\(rr:RuntimeRep) (a:rr) \(a:rr). ...
    This is no good: we could not generate code for 'f', because the
    calling convention for 'f' varies depending on whether the argument is
    a a Int, Int#, or Float#.  (You could imagine generating specialised
    code, one for each instantiation of 'rr', but we don't do that.)

    Certain functions CAN be runtime-rep-polymorphic, because the code
    generator never has to manipulate a value of type 'a :: TYPE rr'.

    * error :: forall (rr:RuntimeRep) (a:TYPE rr). String -> a
      Code generator never has to manipulate the return value.

    * unsafeCoerce#, defined in Desugar.mkUnsafeCoercePair:
      Always inlined to be a no-op
         unsafeCoerce# :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
                                 (a :: TYPE r1) (b :: TYPE r2).
                                 a -> b

    * Unboxed tuples, and unboxed sums, defined in GHC.Builtin.Types
      Always inlined, and hence specialised to the call site
         (#,#) :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
                         (a :: TYPE r1) (b :: TYPE r2).
                         a -> b -> TYPE ('TupleRep '[r1, r2])

    Note [PrimRep and kindPrimRep]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    As part of its source code, in GHC.Core.TyCon, GHC has
      data PrimRep = BoxedRep Levity | IntRep | FloatRep | ...etc...

    Notice that
     * RuntimeRep is part of the syntax tree of the program being compiled
         (defined in a library: ghc-prim:GHC.Types)
     * PrimRep is part of GHC's source code.
         (defined in GHC.Core.TyCon)

    We need to get from one to the other; that is what kindPrimRep does.
    Suppose we have a value
       (v :: t) where (t :: k)
    Given this kind
        k = TyConApp "TYPE" [rep]
    GHC needs to be able to figure out how 'v' is represented at runtime.
    It expects 'rep' to be form
        TyConApp rr_dc args
    where 'rr_dc' is a promoteed data constructor from RuntimeRep. So
    now we need to go from 'dc' to the corresponding PrimRep.  We store this
    PrimRep in the promoted data constructor itself: see TyCon.promDcRepInfo.

    -}

    tYPETyCon :: TyCon
    tYPETyConName :: Name

    tYPETyCon :: TyCon
    tYPETyCon = Name -> [TyConBinder] -> Kind -> [Role] -> Name -> TyCon
    mkKindTyCon Name
    tYPETyConName
                            ([Kind] -> [TyConBinder]
    mkTemplateAnonTyConBinders [Kind
    runtimeRepTy])
                            Kind
    liftedTypeKind
                            [Role
    Nominal]
                            (Name -> Name
    mkPrelTyConRepName Name
    tYPETyConName)

    --------------------------
    -- ... and now their names

    -- If you edit these, you may need to update the GHC formalism
    -- See Note [GHC Formalism] in GHC.Core.Lint
    tYPETyConName :: Name
    tYPETyConName             = FastString -> Unique -> TyCon -> Name
    mkPrimTyConName (String -> FastString
    fsLit String
    "TYPE") Unique
    tYPETyConKey TyCon
    tYPETyCon

    mkPrimTyConName :: FastString -> Unique -> TyCon -> Name
    mkPrimTyConName :: FastString -> Unique -> TyCon -> Name
    mkPrimTyConName = BuiltInSyntax -> FastString -> Unique -> TyCon -> Name
    mkPrimTcName BuiltInSyntax
    BuiltInSyntax
      -- All of the super kinds and kinds are defined in Prim,
      -- and use BuiltInSyntax, because they are never in scope in the source

    mkPrimTcName :: BuiltInSyntax -> FastString -> Unique -> TyCon -> Name
    mkPrimTcName :: BuiltInSyntax -> FastString -> Unique -> TyCon -> Name
    mkPrimTcName BuiltInSyntax
    built_in_syntax FastString
    occ Unique
    key TyCon
    tycon
      = Module -> OccName -> Unique -> TyThing -> BuiltInSyntax -> Name
    mkWiredInName Module
    gHC_PRIM (FastString -> OccName
    mkTcOccFS FastString
    occ) Unique
    key (TyCon -> TyThing
    mkATyCon TyCon
    tycon) BuiltInSyntax
    built_in_syntax

    -----------------------------

    -- Given a Multiplicity, applies FUN to it.
    functionWithMultiplicity :: Type -> Type
    functionWithMultiplicity :: Kind -> Kind
    functionWithMultiplicity Kind
    mul = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    funTyCon [Kind
    mul]

    {-
    ************************************************************************
    *                                                                      *
       Basic primitive types (@Char#@, @Int#@, etc.)
    *                                                                      *
    ************************************************************************
    -}

    -- only used herein
    pcPrimTyCon :: Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon :: Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    name [Role]
    roles PrimRep
    rep
      = Name -> [TyConBinder] -> Kind -> [Role] -> TyCon
    mkPrimTyCon Name
    name [TyConBinder]
    binders Kind
    result_kind [Role]
    roles
      where
        binders :: [TyConBinder]
    binders     = [Kind] -> [TyConBinder]
    mkTemplateAnonTyConBinders ((Role -> Kind) -> [Role] -> [Kind]
    forall a b. (a -> b) -> [a] -> [b]
    map (Kind -> Role -> Kind
    forall a b. a -> b -> a
    const Kind
    liftedTypeKind) [Role]
    roles)
        result_kind :: Kind
    result_kind = Kind -> Kind
    tYPE (PrimRep -> Kind
    primRepToRuntimeRep PrimRep
    rep)

    -- | Convert a 'PrimRep' to a 'Type' of kind RuntimeRep
    -- Defined here to avoid (more) module loops
    primRepToRuntimeRep :: PrimRep -> Type
    primRepToRuntimeRep :: PrimRep -> Kind
    primRepToRuntimeRep PrimRep
    rep = case PrimRep
    rep of
      PrimRep
    VoidRep       -> TyCon -> [Kind] -> Kind
    TyConApp TyCon
    tupleRepDataConTyCon [Kind -> [Kind] -> Kind
    mkPromotedListTy Kind
    runtimeRepTy []]
      PrimRep
    LiftedRep     -> Kind
    liftedRepTy
      PrimRep
    UnliftedRep   -> Kind
    unliftedRepTy
      PrimRep
    IntRep        -> Kind
    intRepDataConTy
      PrimRep
    Int8Rep       -> Kind
    int8RepDataConTy
      PrimRep
    Int16Rep      -> Kind
    int16RepDataConTy
      PrimRep
    Int32Rep      -> Kind
    int32RepDataConTy
      PrimRep
    Int64Rep      -> Kind
    int64RepDataConTy
      PrimRep
    WordRep       -> Kind
    wordRepDataConTy
      PrimRep
    Word8Rep      -> Kind
    word8RepDataConTy
      PrimRep
    Word16Rep     -> Kind
    word16RepDataConTy
      PrimRep
    Word32Rep     -> Kind
    word32RepDataConTy
      PrimRep
    Word64Rep     -> Kind
    word64RepDataConTy
      PrimRep
    AddrRep       -> Kind
    addrRepDataConTy
      PrimRep
    FloatRep      -> Kind
    floatRepDataConTy
      PrimRep
    DoubleRep     -> Kind
    doubleRepDataConTy
      VecRep Int
    n PrimElemRep
    elem -> TyCon -> [Kind] -> Kind
    TyConApp TyCon
    vecRepDataConTyCon [Kind
    n', Kind
    elem']
        where
          n' :: Kind
    n' = case Int
    n of
            Int
    2  -> Kind
    vec2DataConTy
            Int
    4  -> Kind
    vec4DataConTy
            Int
    8  -> Kind
    vec8DataConTy
            Int
    16 -> Kind
    vec16DataConTy
            Int
    32 -> Kind
    vec32DataConTy
            Int
    64 -> Kind
    vec64DataConTy
            Int
    _  -> String -> SDoc -> Kind
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "Disallowed VecCount" (Int -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Int
    n)

          elem' :: Kind
    elem' = case PrimElemRep
    elem of
            PrimElemRep
    Int8ElemRep   -> Kind
    int8ElemRepDataConTy
            PrimElemRep
    Int16ElemRep  -> Kind
    int16ElemRepDataConTy
            PrimElemRep
    Int32ElemRep  -> Kind
    int32ElemRepDataConTy
            PrimElemRep
    Int64ElemRep  -> Kind
    int64ElemRepDataConTy
            PrimElemRep
    Word8ElemRep  -> Kind
    word8ElemRepDataConTy
            PrimElemRep
    Word16ElemRep -> Kind
    word16ElemRepDataConTy
            PrimElemRep
    Word32ElemRep -> Kind
    word32ElemRepDataConTy
            PrimElemRep
    Word64ElemRep -> Kind
    word64ElemRepDataConTy
            PrimElemRep
    FloatElemRep  -> Kind
    floatElemRepDataConTy
            PrimElemRep
    DoubleElemRep -> Kind
    doubleElemRepDataConTy

    pcPrimTyCon0 :: Name -> PrimRep -> TyCon
    pcPrimTyCon0 :: Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    name PrimRep
    rep
      = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    name [] PrimRep
    rep

    charPrimTy :: Type
    charPrimTy :: Kind
    charPrimTy      = TyCon -> Kind
    mkTyConTy TyCon
    charPrimTyCon
    charPrimTyCon :: TyCon
    charPrimTyCon :: TyCon
    charPrimTyCon   = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    charPrimTyConName PrimRep
    WordRep

    intPrimTy :: Type
    intPrimTy :: Kind
    intPrimTy       = TyCon -> Kind
    mkTyConTy TyCon
    intPrimTyCon
    intPrimTyCon :: TyCon
    intPrimTyCon :: TyCon
    intPrimTyCon    = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    intPrimTyConName PrimRep
    IntRep

    int8PrimTy :: Type
    int8PrimTy :: Kind
    int8PrimTy     = TyCon -> Kind
    mkTyConTy TyCon
    int8PrimTyCon
    int8PrimTyCon :: TyCon
    int8PrimTyCon :: TyCon
    int8PrimTyCon  = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    int8PrimTyConName PrimRep
    Int8Rep

    int16PrimTy :: Type
    int16PrimTy :: Kind
    int16PrimTy    = TyCon -> Kind
    mkTyConTy TyCon
    int16PrimTyCon
    int16PrimTyCon :: TyCon
    int16PrimTyCon :: TyCon
    int16PrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    int16PrimTyConName PrimRep
    Int16Rep

    int32PrimTy :: Type
    int32PrimTy :: Kind
    int32PrimTy     = TyCon -> Kind
    mkTyConTy TyCon
    int32PrimTyCon
    int32PrimTyCon :: TyCon
    int32PrimTyCon :: TyCon
    int32PrimTyCon  = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    int32PrimTyConName PrimRep
    Int32Rep

    int64PrimTy :: Type
    int64PrimTy :: Kind
    int64PrimTy     = TyCon -> Kind
    mkTyConTy TyCon
    int64PrimTyCon
    int64PrimTyCon :: TyCon
    int64PrimTyCon :: TyCon
    int64PrimTyCon  = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    int64PrimTyConName PrimRep
    Int64Rep

    wordPrimTy :: Type
    wordPrimTy :: Kind
    wordPrimTy      = TyCon -> Kind
    mkTyConTy TyCon
    wordPrimTyCon
    wordPrimTyCon :: TyCon
    wordPrimTyCon :: TyCon
    wordPrimTyCon   = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    wordPrimTyConName PrimRep
    WordRep

    word8PrimTy :: Type
    word8PrimTy :: Kind
    word8PrimTy     = TyCon -> Kind
    mkTyConTy TyCon
    word8PrimTyCon
    word8PrimTyCon :: TyCon
    word8PrimTyCon :: TyCon
    word8PrimTyCon  = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    word8PrimTyConName PrimRep
    Word8Rep

    word16PrimTy :: Type
    word16PrimTy :: Kind
    word16PrimTy    = TyCon -> Kind
    mkTyConTy TyCon
    word16PrimTyCon
    word16PrimTyCon :: TyCon
    word16PrimTyCon :: TyCon
    word16PrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    word16PrimTyConName PrimRep
    Word16Rep

    word32PrimTy :: Type
    word32PrimTy :: Kind
    word32PrimTy    = TyCon -> Kind
    mkTyConTy TyCon
    word32PrimTyCon
    word32PrimTyCon :: TyCon
    word32PrimTyCon :: TyCon
    word32PrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    word32PrimTyConName PrimRep
    Word32Rep

    word64PrimTy :: Type
    word64PrimTy :: Kind
    word64PrimTy    = TyCon -> Kind
    mkTyConTy TyCon
    word64PrimTyCon
    word64PrimTyCon :: TyCon
    word64PrimTyCon :: TyCon
    word64PrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    word64PrimTyConName PrimRep
    Word64Rep

    addrPrimTy :: Type
    addrPrimTy :: Kind
    addrPrimTy      = TyCon -> Kind
    mkTyConTy TyCon
    addrPrimTyCon
    addrPrimTyCon :: TyCon
    addrPrimTyCon :: TyCon
    addrPrimTyCon   = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    addrPrimTyConName PrimRep
    AddrRep

    floatPrimTy     :: Type
    floatPrimTy :: Kind
    floatPrimTy     = TyCon -> Kind
    mkTyConTy TyCon
    floatPrimTyCon
    floatPrimTyCon :: TyCon
    floatPrimTyCon :: TyCon
    floatPrimTyCon  = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    floatPrimTyConName PrimRep
    FloatRep

    doublePrimTy :: Type
    doublePrimTy :: Kind
    doublePrimTy    = TyCon -> Kind
    mkTyConTy TyCon
    doublePrimTyCon
    doublePrimTyCon :: TyCon
    doublePrimTyCon :: TyCon
    doublePrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    doublePrimTyConName PrimRep
    DoubleRep

    {-
    ************************************************************************
    *                                                                      *
       The @State#@ type (and @_RealWorld@ types)
    *                                                                      *
    ************************************************************************

    Note [The equality types story]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    GHC sports a veritable menagerie of equality types:

             Type or  Lifted?  Hetero?  Role      Built in         Defining module
             class?    L/U                        TyCon
    -----------------------------------------------------------------------------------------
    ~#         T        U      hetero   nominal   eqPrimTyCon      GHC.Prim
    ~~         C        L      hetero   nominal   heqTyCon         GHC.Types
    ~          C        L      homo     nominal   eqTyCon          GHC.Types
    :~:        T        L      homo     nominal   (not built-in)   Data.Type.Equality
    :~~:       T        L      hetero   nominal   (not built-in)   Data.Type.Equality

    ~R#        T        U      hetero   repr      eqReprPrimTy     GHC.Prim
    Coercible  C        L      homo     repr      coercibleTyCon   GHC.Types
    Coercion   T        L      homo     repr      (not built-in)   Data.Type.Coercion
    ~P#        T        U      hetero   phantom   eqPhantPrimTyCon GHC.Prim

    Recall that "hetero" means the equality can related types of different
    kinds. Knowing that (t1 ~# t2) or (t1 ~R# t2) or even that (t1 ~P# t2)
    also means that (k1 ~# k2), where (t1 :: k1) and (t2 :: k2).

    To produce less confusion for end users, when not dumping and without
    -fprint-equality-relations, each of these groups is printed as the bottommost
    listed equality. That is, (~#) and (~~) are both rendered as (~) in
    error messages, and (~R#) is rendered as Coercible.

    Let's take these one at a time:

        --------------------------
        (~#) :: forall k1 k2. k1 -> k2 -> #
        --------------------------
    This is The Type Of Equality in GHC. It classifies nominal coercions.
    This type is used in the solver for recording equality constraints.
    It responds "yes" to Type.isEqPrimPred and classifies as an EqPred in
    Type.classifyPredType.

    All wanted constraints of this type are built with coercion holes.
    (See Note [Coercion holes] in GHC.Core.TyCo.Rep.) But see also
    Note [Deferred errors for coercion holes] in GHC.Tc.Errors to see how
    equality constraints are deferred.

    Within GHC, ~# is called eqPrimTyCon, and it is defined in GHC.Builtin.Types.Prim.

        --------------------------
        (~~) :: forall k1 k2. k1 -> k2 -> Constraint
        --------------------------
    This is (almost) an ordinary class, defined as if by
      class a ~# b => a ~~ b
      instance a ~# b => a ~~ b
    Here's what's unusual about it:

     * We can't actually declare it that way because we don't have syntax for ~#.
       And ~# isn't a constraint, so even if we could write it, it wouldn't kind
       check.

     * Users cannot write instances of it.

     * It is "naturally coherent". This means that the solver won't hesitate to
       solve a goal of type (a ~~ b) even if there is, say (Int ~~ c) in the
       context. (Normally, it waits to learn more, just in case the given
       influences what happens next.) See Note [Naturally coherent classes]
       in GHC.Tc.Solver.Interact.

     * It always terminates. That is, in the UndecidableInstances checks, we
       don't worry if a (~~) constraint is too big, as we know that solving
       equality terminates.

    On the other hand, this behaves just like any class w.r.t. eager superclass
    unpacking in the solver. So a lifted equality given quickly becomes an unlifted
    equality given. This is good, because the solver knows all about unlifted
    equalities. There is some special-casing in GHC.Tc.Solver.Interact.matchClassInst to
    pretend that there is an instance of this class, as we can't write the instance
    in Haskell.

    Within GHC, ~~ is called heqTyCon, and it is defined in GHC.Builtin.Types.

        --------------------------
        (~) :: forall k. k -> k -> Constraint
        --------------------------
    This is /exactly/ like (~~), except with a homogeneous kind.
    It is an almost-ordinary class defined as if by
      class a ~# b => (a :: k) ~ (b :: k)
      instance a ~# b => a ~ b

     * All the bullets for (~~) apply

     * In addition (~) is magical syntax, as ~ is a reserved symbol.
       It cannot be exported or imported.

    Within GHC, ~ is called eqTyCon, and it is defined in GHC.Builtin.Types.

    Historical note: prior to July 18 (~) was defined as a
      more-ordinary class with (~~) as a superclass.  But that made it
      special in different ways; and the extra superclass selections to
      get from (~) to (~#) via (~~) were tiresome.  Now it's defined
      uniformly with (~~) and Coercible; much nicer.)

        --------------------------
        (:~:) :: forall k. k -> k -> *
        (:~~:) :: forall k1 k2. k1 -> k2 -> *
        --------------------------
    These are perfectly ordinary GADTs, wrapping (~) and (~~) resp.
    They are not defined within GHC at all.

        --------------------------
        (~R#) :: forall k1 k2. k1 -> k2 -> #
        --------------------------
    The is the representational analogue of ~#. This is the type of representational
    equalities that the solver works on. All wanted constraints of this type are
    built with coercion holes.

    Within GHC, ~R# is called eqReprPrimTyCon, and it is defined in GHC.Builtin.Types.Prim.

        --------------------------
        Coercible :: forall k. k -> k -> Constraint
        --------------------------
    This is quite like (~~) in the way it's defined and treated within GHC, but
    it's homogeneous. Homogeneity helps with type inference (as GHC can solve one
    kind from the other) and, in my (Richard's) estimation, will be more intuitive
    for users.

    An alternative design included HCoercible (like (~~)) and Coercible (like (~)).
    One annoyance was that we want `coerce :: Coercible a b => a -> b`, and
    we need the type of coerce to be fully wired-in. So the HCoercible/Coercible
    split required that both types be fully wired-in. Instead of doing this,
    I just got rid of HCoercible, as I'm not sure who would use it, anyway.

    Within GHC, Coercible is called coercibleTyCon, and it is defined in
    GHC.Builtin.Types.

        --------------------------
        Coercion :: forall k. k -> k -> *
        --------------------------
    This is a perfectly ordinary GADT, wrapping Coercible. It is not defined
    within GHC at all.

        --------------------------
        (~P#) :: forall k1 k2. k1 -> k2 -> #
        --------------------------
    This is the phantom analogue of ~# and it is barely used at all.
    (The solver has no idea about this one.) Here is the motivation:

        data Phant a = MkPhant
        type role Phant phantom

        Phant <Int, Bool>_P :: Phant Int ~P# Phant Bool

    We just need to have something to put on that last line. You probably
    don't need to worry about it.

    Note [The State# TyCon]
    ~~~~~~~~~~~~~~~~~~~~~~~
    State# is the primitive, unlifted type of states.  It has one type parameter,
    thus
            State# RealWorld
    or
            State# s

    where s is a type variable. The only purpose of the type parameter is to
    keep different state threads separate.  It is represented by nothing at all.

    The type parameter to State# is intended to keep separate threads separate.
    Even though this parameter is not used in the definition of State#, it is
    given role Nominal to enforce its intended use.
    -}

    mkStatePrimTy :: Type -> Type
    mkStatePrimTy :: Kind -> Kind
    mkStatePrimTy Kind
    ty = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    statePrimTyCon [Kind
    ty]

    statePrimTyCon :: TyCon   -- See Note [The State# TyCon]
    statePrimTyCon :: TyCon
    statePrimTyCon   = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    statePrimTyConName [Role
    Nominal] PrimRep
    VoidRep

    {-
    RealWorld is deeply magical.  It is *primitive*, but it is not
    *unlifted* (hence ptrArg).  We never manipulate values of type
    RealWorld; it's only used in the type system, to parameterise State#.
    -}

    realWorldTyCon :: TyCon
    realWorldTyCon :: TyCon
    realWorldTyCon = Name -> [TyConBinder] -> Kind -> [Role] -> TyCon
    mkLiftedPrimTyCon Name
    realWorldTyConName [] Kind
    liftedTypeKind []
    realWorldTy :: Type
    realWorldTy :: Kind
    realWorldTy          = TyCon -> Kind
    mkTyConTy TyCon
    realWorldTyCon
    realWorldStatePrimTy :: Type
    realWorldStatePrimTy :: Kind
    realWorldStatePrimTy = Kind -> Kind
    mkStatePrimTy Kind
    realWorldTy        -- State# RealWorld

    -- Note: the ``state-pairing'' types are not truly primitive,
    -- so they are defined in \tr{GHC.Builtin.Types}, not here.

    mkProxyPrimTy :: Type -> Type -> Type
    mkProxyPrimTy :: Kind -> Kind -> Kind
    mkProxyPrimTy Kind
    k Kind
    ty = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    proxyPrimTyCon [Kind
    k, Kind
    ty]

    proxyPrimTyCon :: TyCon
    proxyPrimTyCon :: TyCon
    proxyPrimTyCon = Name -> [TyConBinder] -> Kind -> [Role] -> TyCon
    mkPrimTyCon Name
    proxyPrimTyConName [TyConBinder]
    binders Kind
    res_kind [Role
    Nominal,Role
    Phantom]
      where
         -- Kind: forall k. k -> TYPE (Tuple '[])
         binders :: [TyConBinder]
    binders = [Kind] -> ([Kind] -> [Kind]) -> [TyConBinder]
    mkTemplateTyConBinders [Kind
    liftedTypeKind] [Kind] -> [Kind]
    forall a. a -> a
    id
         res_kind :: Kind
    res_kind = [Kind] -> Kind
    unboxedTupleKind []

    {- *********************************************************************
    *                                                                      *
                    Primitive equality constraints
        See Note [The equality types story]
    *                                                                      *
    ********************************************************************* -}

    eqPrimTyCon :: TyCon  -- The representation type for equality predicates
                          -- See Note [The equality types story]
    eqPrimTyCon :: TyCon
    eqPrimTyCon  = Name -> [TyConBinder] -> Kind -> [Role] -> TyCon
    mkPrimTyCon Name
    eqPrimTyConName [TyConBinder]
    binders Kind
    res_kind [Role]
    roles
      where
        -- Kind :: forall k1 k2. k1 -> k2 -> TYPE (Tuple '[])
        binders :: [TyConBinder]
    binders  = [Kind] -> ([Kind] -> [Kind]) -> [TyConBinder]
    mkTemplateTyConBinders [Kind
    liftedTypeKind, Kind
    liftedTypeKind] [Kind] -> [Kind]
    forall a. a -> a
    id
        res_kind :: Kind
    res_kind = [Kind] -> Kind
    unboxedTupleKind []
        roles :: [Role]
    roles    = [Role
    Nominal, Role
    Nominal, Role
    Nominal, Role
    Nominal]

    -- like eqPrimTyCon, but the type for *Representational* coercions
    -- this should only ever appear as the type of a covar. Its role is
    -- interpreted in coercionRole
    eqReprPrimTyCon :: TyCon   -- See Note [The equality types story]
    eqReprPrimTyCon :: TyCon
    eqReprPrimTyCon = Name -> [TyConBinder] -> Kind -> [Role] -> TyCon
    mkPrimTyCon Name
    eqReprPrimTyConName [TyConBinder]
    binders Kind
    res_kind [Role]
    roles
      where
        -- Kind :: forall k1 k2. k1 -> k2 -> TYPE (Tuple '[])
        binders :: [TyConBinder]
    binders  = [Kind] -> ([Kind] -> [Kind]) -> [TyConBinder]
    mkTemplateTyConBinders [Kind
    liftedTypeKind, Kind
    liftedTypeKind] [Kind] -> [Kind]
    forall a. a -> a
    id
        res_kind :: Kind
    res_kind = [Kind] -> Kind
    unboxedTupleKind []
        roles :: [Role]
    roles    = [Role
    Nominal, Role
    Nominal, Role
    Representational, Role
    Representational]

    -- like eqPrimTyCon, but the type for *Phantom* coercions.
    -- This is only used to make higher-order equalities. Nothing
    -- should ever actually have this type!
    eqPhantPrimTyCon :: TyCon
    eqPhantPrimTyCon :: TyCon
    eqPhantPrimTyCon = Name -> [TyConBinder] -> Kind -> [Role] -> TyCon
    mkPrimTyCon Name
    eqPhantPrimTyConName [TyConBinder]
    binders Kind
    res_kind [Role]
    roles
      where
        -- Kind :: forall k1 k2. k1 -> k2 -> TYPE (Tuple '[])
        binders :: [TyConBinder]
    binders  = [Kind] -> ([Kind] -> [Kind]) -> [TyConBinder]
    mkTemplateTyConBinders [Kind
    liftedTypeKind, Kind
    liftedTypeKind] [Kind] -> [Kind]
    forall a. a -> a
    id
        res_kind :: Kind
    res_kind = [Kind] -> Kind
    unboxedTupleKind []
        roles :: [Role]
    roles    = [Role
    Nominal, Role
    Nominal, Role
    Phantom, Role
    Phantom]

    -- | Given a Role, what TyCon is the type of equality predicates at that role?
    equalityTyCon :: Role -> TyCon
    equalityTyCon :: Role -> TyCon
    equalityTyCon Role
    Nominal          = TyCon
    eqPrimTyCon
    equalityTyCon Role
    Representational = TyCon
    eqReprPrimTyCon
    equalityTyCon Role
    Phantom          = TyCon
    eqPhantPrimTyCon

    {- *********************************************************************
    *                                                                      *
                 The primitive array types
    *                                                                      *
    ********************************************************************* -}

    arrayPrimTyCon, mutableArrayPrimTyCon, mutableByteArrayPrimTyCon,
        byteArrayPrimTyCon, arrayArrayPrimTyCon, mutableArrayArrayPrimTyCon,
        smallArrayPrimTyCon, smallMutableArrayPrimTyCon :: TyCon
    arrayPrimTyCon :: TyCon
    arrayPrimTyCon             = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    arrayPrimTyConName             [Role
    Representational] PrimRep
    UnliftedRep
    mutableArrayPrimTyCon :: TyCon
    mutableArrayPrimTyCon      = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon  Name
    mutableArrayPrimTyConName     [Role
    Nominal, Role
    Representational] PrimRep
    UnliftedRep
    mutableByteArrayPrimTyCon :: TyCon
    mutableByteArrayPrimTyCon  = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    mutableByteArrayPrimTyConName  [Role
    Nominal] PrimRep
    UnliftedRep
    byteArrayPrimTyCon :: TyCon
    byteArrayPrimTyCon         = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    byteArrayPrimTyConName        PrimRep
    UnliftedRep
    arrayArrayPrimTyCon :: TyCon
    arrayArrayPrimTyCon        = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    arrayArrayPrimTyConName       PrimRep
    UnliftedRep
    mutableArrayArrayPrimTyCon :: TyCon
    mutableArrayArrayPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    mutableArrayArrayPrimTyConName [Role
    Nominal] PrimRep
    UnliftedRep
    smallArrayPrimTyCon :: TyCon
    smallArrayPrimTyCon        = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    smallArrayPrimTyConName        [Role
    Representational] PrimRep
    UnliftedRep
    smallMutableArrayPrimTyCon :: TyCon
    smallMutableArrayPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    smallMutableArrayPrimTyConName [Role
    Nominal, Role
    Representational] PrimRep
    UnliftedRep

    mkArrayPrimTy :: Type -> Type
    mkArrayPrimTy :: Kind -> Kind
    mkArrayPrimTy Kind
    elt           = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    arrayPrimTyCon [Kind
    elt]
    byteArrayPrimTy :: Type
    byteArrayPrimTy :: Kind
    byteArrayPrimTy             = TyCon -> Kind
    mkTyConTy TyCon
    byteArrayPrimTyCon
    mkArrayArrayPrimTy :: Type
    mkArrayArrayPrimTy :: Kind
    mkArrayArrayPrimTy = TyCon -> Kind
    mkTyConTy TyCon
    arrayArrayPrimTyCon
    mkSmallArrayPrimTy :: Type -> Type
    mkSmallArrayPrimTy :: Kind -> Kind
    mkSmallArrayPrimTy Kind
    elt = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    smallArrayPrimTyCon [Kind
    elt]
    mkMutableArrayPrimTy :: Type -> Type -> Type
    mkMutableArrayPrimTy :: Kind -> Kind -> Kind
    mkMutableArrayPrimTy Kind
    s Kind
    elt  = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    mutableArrayPrimTyCon [Kind
    s, Kind
    elt]
    mkMutableByteArrayPrimTy :: Type -> Type
    mkMutableByteArrayPrimTy :: Kind -> Kind
    mkMutableByteArrayPrimTy Kind
    s  = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    mutableByteArrayPrimTyCon [Kind
    s]
    mkMutableArrayArrayPrimTy :: Type -> Type
    mkMutableArrayArrayPrimTy :: Kind -> Kind
    mkMutableArrayArrayPrimTy Kind
    s = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    mutableArrayArrayPrimTyCon [Kind
    s]
    mkSmallMutableArrayPrimTy :: Type -> Type -> Type
    mkSmallMutableArrayPrimTy :: Kind -> Kind -> Kind
    mkSmallMutableArrayPrimTy Kind
    s Kind
    elt = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    smallMutableArrayPrimTyCon [Kind
    s, Kind
    elt]

    {- *********************************************************************
    *                                                                      *
                    The mutable variable type
    *                                                                      *
    ********************************************************************* -}

    mutVarPrimTyCon :: TyCon
    mutVarPrimTyCon :: TyCon
    mutVarPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    mutVarPrimTyConName [Role
    Nominal, Role
    Representational] PrimRep
    UnliftedRep

    mkMutVarPrimTy :: Type -> Type -> Type
    mkMutVarPrimTy :: Kind -> Kind -> Kind
    mkMutVarPrimTy Kind
    s Kind
    elt        = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    mutVarPrimTyCon [Kind
    s, Kind
    elt]

    {-
    ************************************************************************
    *                                                                      *
    \subsection[TysPrim-io-port-var]{The synchronizing I/O Port type}
    *                                                                      *
    ************************************************************************
    -}

    ioPortPrimTyCon :: TyCon
    ioPortPrimTyCon :: TyCon
    ioPortPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    ioPortPrimTyConName [Role
    Nominal, Role
    Representational] PrimRep
    UnliftedRep

    mkIOPortPrimTy :: Type -> Type -> Type
    mkIOPortPrimTy :: Kind -> Kind -> Kind
    mkIOPortPrimTy Kind
    s Kind
    elt          = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    ioPortPrimTyCon [Kind
    s, Kind
    elt]

    {-
    ************************************************************************
    *                                                                      *
       The synchronizing variable type
    \subsection[TysPrim-synch-var]{The synchronizing variable type}
    *                                                                      *
    ************************************************************************
    -}

    mVarPrimTyCon :: TyCon
    mVarPrimTyCon :: TyCon
    mVarPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    mVarPrimTyConName [Role
    Nominal, Role
    Representational] PrimRep
    UnliftedRep

    mkMVarPrimTy :: Type -> Type -> Type
    mkMVarPrimTy :: Kind -> Kind -> Kind
    mkMVarPrimTy Kind
    s Kind
    elt          = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    mVarPrimTyCon [Kind
    s, Kind
    elt]

    {-
    ************************************************************************
    *                                                                      *
       The transactional variable type
    *                                                                      *
    ************************************************************************
    -}

    tVarPrimTyCon :: TyCon
    tVarPrimTyCon :: TyCon
    tVarPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    tVarPrimTyConName [Role
    Nominal, Role
    Representational] PrimRep
    UnliftedRep

    mkTVarPrimTy :: Type -> Type -> Type
    mkTVarPrimTy :: Kind -> Kind -> Kind
    mkTVarPrimTy Kind
    s Kind
    elt = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    tVarPrimTyCon [Kind
    s, Kind
    elt]

    {-
    ************************************************************************
    *                                                                      *
       The stable-pointer type
    *                                                                      *
    ************************************************************************
    -}

    stablePtrPrimTyCon :: TyCon
    stablePtrPrimTyCon :: TyCon
    stablePtrPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    stablePtrPrimTyConName [Role
    Representational] PrimRep
    AddrRep

    mkStablePtrPrimTy :: Type -> Type
    mkStablePtrPrimTy :: Kind -> Kind
    mkStablePtrPrimTy Kind
    ty = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    stablePtrPrimTyCon [Kind
    ty]

    {-
    ************************************************************************
    *                                                                      *
       The stable-name type
    *                                                                      *
    ************************************************************************
    -}

    stableNamePrimTyCon :: TyCon
    stableNamePrimTyCon :: TyCon
    stableNamePrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    stableNamePrimTyConName [Role
    Phantom] PrimRep
    UnliftedRep

    mkStableNamePrimTy :: Type -> Type
    mkStableNamePrimTy :: Kind -> Kind
    mkStableNamePrimTy Kind
    ty = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    stableNamePrimTyCon [Kind
    ty]

    {-
    ************************************************************************
    *                                                                      *
       The Compact NFData (CNF) type
    *                                                                      *
    ************************************************************************
    -}

    compactPrimTyCon :: TyCon
    compactPrimTyCon :: TyCon
    compactPrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    compactPrimTyConName PrimRep
    UnliftedRep

    compactPrimTy :: Type
    compactPrimTy :: Kind
    compactPrimTy = TyCon -> Kind
    mkTyConTy TyCon
    compactPrimTyCon

    {-
    ************************************************************************
    *                                                                      *
       The ``bytecode object'' type
    *                                                                      *
    ************************************************************************
    -}

    -- Unlike most other primitive types, BCO is lifted. This is because in
    -- general a BCO may be a thunk for the reasons given in Note [Updatable CAF
    -- BCOs] in GHCi.CreateBCO.
    bcoPrimTy    :: Type
    bcoPrimTy :: Kind
    bcoPrimTy    = TyCon -> Kind
    mkTyConTy TyCon
    bcoPrimTyCon
    bcoPrimTyCon :: TyCon
    bcoPrimTyCon :: TyCon
    bcoPrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    bcoPrimTyConName PrimRep
    LiftedRep

    {-
    ************************************************************************
    *                                                                      *
       The ``weak pointer'' type
    *                                                                      *
    ************************************************************************
    -}

    weakPrimTyCon :: TyCon
    weakPrimTyCon :: TyCon
    weakPrimTyCon = Name -> [Role] -> PrimRep -> TyCon
    pcPrimTyCon Name
    weakPrimTyConName [Role
    Representational] PrimRep
    UnliftedRep

    mkWeakPrimTy :: Type -> Type
    mkWeakPrimTy :: Kind -> Kind
    mkWeakPrimTy Kind
    v = TyCon -> [Kind] -> Kind
    TyConApp TyCon
    weakPrimTyCon [Kind
    v]

    {-
    ************************************************************************
    *                                                                      *
       The ``thread id'' type
    *                                                                      *
    ************************************************************************

    A thread id is represented by a pointer to the TSO itself, to ensure
    that they are always unique and we can always find the TSO for a given
    thread id.  However, this has the unfortunate consequence that a
    ThreadId# for a given thread is treated as a root by the garbage
    collector and can keep TSOs around for too long.

    Hence the programmer API for thread manipulation uses a weak pointer
    to the thread id internally.
    -}

    threadIdPrimTy :: Type
    threadIdPrimTy :: Kind
    threadIdPrimTy    = TyCon -> Kind
    mkTyConTy TyCon
    threadIdPrimTyCon
    threadIdPrimTyCon :: TyCon
    threadIdPrimTyCon :: TyCon
    threadIdPrimTyCon = Name -> PrimRep -> TyCon
    pcPrimTyCon0 Name
    threadIdPrimTyConName PrimRep
    UnliftedRep

    {-
    ************************************************************************
    *                                                                      *
    \subsection{SIMD vector types}
    *                                                                      *
    ************************************************************************
    -}

    #include "primop-vector-tys.hs-incl"