    {-
    (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(
            mkTemplateKindVar, mkTemplateKindVars,
            mkTemplateTyVars, mkTemplateTyVarsFrom,
            mkTemplateKiTyVars, mkTemplateKiTyVar,

            mkTemplateTyConBinders, mkTemplateKindTyConBinders,
            mkTemplateAnonTyConBinders,

            alphaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
            alphaTyVarSpec, betaTyVarSpec, gammaTyVarSpec, deltaTyVarSpec,
            alphaTys, alphaTy, betaTy, gammaTy, deltaTy,
            alphaTyVarsUnliftedRep, alphaTyVarUnliftedRep,
            alphaTysUnliftedRep, alphaTyUnliftedRep,
            runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep3TyVar,
            runtimeRep1TyVarInf, runtimeRep2TyVarInf,
            runtimeRep1Ty, runtimeRep2Ty, runtimeRep3Ty,
            levity1TyVar, levity2TyVar,
            levity1TyVarInf, levity2TyVarInf,
            levity1Ty, levity2Ty,

            alphaConstraintTyVar, alphaConstraintTy,

            openAlphaTyVar, openBetaTyVar, openGammaTyVar,
            openAlphaTyVarSpec, openBetaTyVarSpec, openGammaTyVarSpec,
            openAlphaTy, openBetaTy, openGammaTy,

            levPolyAlphaTyVar, levPolyBetaTyVar,
            levPolyAlphaTyVarSpec, levPolyBetaTyVarSpec,
            levPolyAlphaTy, levPolyBetaTy,

            multiplicityTyVar1, multiplicityTyVar2,

            -- Kind constructors...
            tYPETyCon, tYPETyConName, tYPEKind,
            cONSTRAINTTyCon, cONSTRAINTTyConName, cONSTRAINTKind,

            -- Arrows
            funTyFlagTyCon, isArrowTyCon,
            fUNTyCon,       fUNTyConName,
            ctArrowTyCon, ctArrowTyConName,
            ccArrowTyCon, ccArrowTyConName,
            tcArrowTyCon, tcArrowTyConName,

            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,   realWorldMutableByteArrayPrimTy,

            proxyPrimTyCon,         mkProxyPrimTy,

            arrayPrimTyCon, mkArrayPrimTy,
            byteArrayPrimTyCon,     byteArrayPrimTy,
            smallArrayPrimTyCon, mkSmallArrayPrimTy,
            mutableArrayPrimTyCon, mkMutableArrayPrimTy,
            mutableByteArrayPrimTyCon, mkMutableByteArrayPrimTy,
            smallMutableArrayPrimTyCon, mkSmallMutableArrayPrimTy,
            mutVarPrimTyCon, mkMutVarPrimTy,

            mVarPrimTyCon,                  mkMVarPrimTy,
            tVarPrimTyCon,                  mkTVarPrimTy,
            stablePtrPrimTyCon,             mkStablePtrPrimTy,
            stableNamePrimTyCon,            mkStableNamePrimTy,
            compactPrimTyCon,               compactPrimTy,
            bcoPrimTyCon,                   bcoPrimTy,
            weakPrimTyCon,                  mkWeakPrimTy,
            threadIdPrimTyCon,              threadIdPrimTy,
            stackSnapshotPrimTyCon,         stackSnapshotPrimTy,
            promptTagPrimTyCon,             mkPromptTagPrimTy,

            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

    import GHC.Prelude

    import {-# SOURCE #-} GHC.Builtin.Types
      ( runtimeRepTy, levityTy, unboxedTupleKind, liftedTypeKind, unliftedTypeKind
      , boxedRepDataConTyCon, vecRepDataConTyCon
      , liftedRepTy, unliftedRepTy, zeroBitRepTy
      , 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
      , multiplicityTy
      , constraintKind )

    import {-# SOURCE #-} GHC.Types.TyThing( mkATyCon )
    import {-# SOURCE #-} GHC.Core.Type ( mkTyConApp, getLevity )

    import GHC.Core.TyCon
    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 GHC.Types.Var    ( TyVarBinder, TyVar,binderVar, binderVars
                            , mkTyVar, mkTyVarBinder, mkTyVarBinders )
    import GHC.Types.Name
    import GHC.Types.SrcLoc
    import GHC.Types.Unique

    import GHC.Builtin.Uniques
    import GHC.Builtin.Names
    import GHC.Utils.Misc ( changeLast )
    import GHC.Utils.Panic ( assertPpr )
    import GHC.Utils.Outputable

    import GHC.Data.FastString
    import Data.Char

    {- *********************************************************************
    *                                                                      *
                 Building blocks
    *                                                                      *
    ********************************************************************* -}

    mk_TYPE_app :: Type -> Type
    mk_TYPE_app :: Type -> Type
    mk_TYPE_app Type
    rep = TyCon -> [Type] -> Type
    mkTyConApp TyCon
    tYPETyCon [Type
    rep]

    mk_CONSTRAINT_app :: Type -> Type
    mk_CONSTRAINT_app :: Type -> Type
    mk_CONSTRAINT_app Type
    rep = TyCon -> [Type] -> Type
    mkTyConApp TyCon
    cONSTRAINTTyCon [Type
    rep]

    mkPrimTc :: FastString -> Unique -> TyCon -> Name
    mkPrimTc :: FastString -> Unique -> TyCon -> Name
    mkPrimTc = BuiltInSyntax -> FastString -> Unique -> TyCon -> Name
    mkGenPrimTc BuiltInSyntax
    UserSyntax

    mkBuiltInPrimTc :: FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc :: FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc = BuiltInSyntax -> FastString -> Unique -> TyCon -> Name
    mkGenPrimTc BuiltInSyntax
    BuiltInSyntax

    mkGenPrimTc :: BuiltInSyntax -> FastString -> Unique -> TyCon -> Name
    mkGenPrimTc :: BuiltInSyntax -> FastString -> Unique -> TyCon -> Name
    mkGenPrimTc 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

    -- | Create a primitive 'TyCon' with the given 'Name',
    -- arguments of kind 'Type` with the given 'Role's,
    -- and the given result kind representation.
    --
    -- Only use this in "GHC.Builtin.Types.Prim".
    pcPrimTyCon :: Name
                -> [Role] -> RuntimeRepType -> TyCon
    pcPrimTyCon :: Name -> [Role] -> Type -> TyCon
    pcPrimTyCon Name
    name [Role]
    roles Type
    res_rep
      = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    name [TyConBinder]
    binders Type
    result_kind [Role]
    roles
      where
        bndr_kis :: [Type]
    bndr_kis    = Type
    liftedTypeKind Type -> [Role] -> [Type]
    forall a b. a -> [b] -> [a]
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Role]
    roles
        binders :: [TyConBinder]
    binders     = [Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [Type]
    bndr_kis
        result_kind :: Type
    result_kind = Type -> Type
    mk_TYPE_app Type
    res_rep

    -- | Create a primitive nullary 'TyCon' with the given 'Name'
    -- and result kind representation.
    --
    -- Only use this in "GHC.Builtin.Types.Prim".
    pcPrimTyCon0 :: Name -> RuntimeRepType -> TyCon
    pcPrimTyCon0 :: Name -> Type -> TyCon
    pcPrimTyCon0 Name
    name Type
    res_rep
      = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon Name
    name [] Type
    res_rep

    -- | Create a primitive 'TyCon' like 'pcPrimTyCon', except the last
    -- argument is levity-polymorphic, where the levity argument is
    -- implicit and comes before other arguments
    --
    -- Only use this in "GHC.Builtin.Types.Prim".
    pcPrimTyCon_LevPolyLastArg :: Name
                               -> [Role] -- ^ roles of the arguments (must be non-empty),
                                         -- not including the implicit argument of kind 'Levity',
                                         -- which always has 'Nominal' role
                               -> RuntimeRepType  -- ^ representation of the fully-applied type
                               -> TyCon
    pcPrimTyCon_LevPolyLastArg :: Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    name [Role]
    roles Type
    res_rep
      = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    name [TyConBinder]
    binders Type
    result_kind (Role
    Nominal Role -> [Role] -> [Role]
    forall a. a -> [a] -> [a]
    : [Role]
    roles)
        where
          result_kind :: Type
    result_kind = Type -> Type
    mk_TYPE_app Type
    res_rep
          lev_bndr :: TyConBinder
    lev_bndr = ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    levity1TyVar
          binders :: [TyConBinder]
    binders  = TyConBinder
    lev_bndr TyConBinder -> [TyConBinder] -> [TyConBinder]
    forall a. a -> [a] -> [a]
    : [Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [Type]
    anon_bndr_kis
          lev_tv :: Type
    lev_tv   = TyVar -> Type
    mkTyVarTy (TyConBinder -> TyVar
    forall tv argf. VarBndr tv argf -> tv
    binderVar TyConBinder
    lev_bndr)

          -- [ Type, ..., Type, TYPE (BoxedRep l) ]
          anon_bndr_kis :: [Type]
    anon_bndr_kis = [Type] -> Type -> [Type]
    forall a. [a] -> a -> [a]
    changeLast (Type
    liftedTypeKind Type -> [Role] -> [Type]
    forall a b. a -> [b] -> [a]
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Role]
    roles) (Type -> [Type]) -> Type -> [Type]
    forall a b. (a -> b) -> a -> b
    $
                          Type -> Type
    mk_TYPE_app (Type -> Type) -> Type -> Type
    forall a b. (a -> b) -> a -> b
    $
                          TyCon -> [Type] -> Type
    mkTyConApp TyCon
    boxedRepDataConTyCon [Type
    lev_tv]

    {- *********************************************************************
    *                                                                      *
               Primitive type constructors
    *                                                                      *
    ********************************************************************* -}

    {- Note Note [Unexposed TyCons]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    A few primitive TyCons are "unexposed", meaning:
    * We don't want users to be able to write them (see #15209);
      i.e. they aren't in scope, ever.  In particular they do not
      appear in the exports of GHC.Prim: see GHC.Builtin.Utils.ghcPrimExports

    * We don't want users to see them in GHCi's @:browse@ output (see #12023).
    -}

    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".
    -- See Note [Unexposed TyCons]
    unexposedPrimTyCons :: [TyCon]
    unexposedPrimTyCons :: [TyCon]
    unexposedPrimTyCons
      = [ TyCon
    eqPrimTyCon      -- (~#)
        , TyCon
    eqReprPrimTyCon  -- (~R#)
        , TyCon
    eqPhantPrimTyCon -- (~P#)

        -- These arrows are un-exposed for now
        , TyCon
    ctArrowTyCon  -- (=>)
        , TyCon
    ccArrowTyCon  -- (==>)
        , TyCon
    tcArrowTyCon  -- (-=>)
        ]

    -- | Primitive 'TyCon's that are defined in, and exported from, GHC.Prim.
    exposedPrimTyCons :: [TyCon]
    exposedPrimTyCons :: [TyCon]
    exposedPrimTyCons
      = [ TyCon
    addrPrimTyCon
        , TyCon
    arrayPrimTyCon
        , TyCon
    byteArrayPrimTyCon
        , 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
    smallMutableArrayPrimTyCon
        , TyCon
    mVarPrimTyCon
        , 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
    stackSnapshotPrimTyCon
        , TyCon
    promptTagPrimTyCon

        , TyCon
    fUNTyCon
        , TyCon
    tYPETyCon
        , TyCon
    cONSTRAINTTyCon

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

    charPrimTyConName, intPrimTyConName, int8PrimTyConName, int16PrimTyConName, int32PrimTyConName, int64PrimTyConName,
      wordPrimTyConName, word32PrimTyConName, word8PrimTyConName, word16PrimTyConName, word64PrimTyConName,
      addrPrimTyConName, floatPrimTyConName, doublePrimTyConName,
      statePrimTyConName, proxyPrimTyConName, realWorldTyConName,
      arrayPrimTyConName, smallArrayPrimTyConName, byteArrayPrimTyConName,
      mutableArrayPrimTyConName, mutableByteArrayPrimTyConName,
      smallMutableArrayPrimTyConName, mutVarPrimTyConName, mVarPrimTyConName,
      tVarPrimTyConName, stablePtrPrimTyConName,
      stableNamePrimTyConName, compactPrimTyConName, bcoPrimTyConName,
      weakPrimTyConName, threadIdPrimTyConName,
      eqPrimTyConName, eqReprPrimTyConName, eqPhantPrimTyConName,
      stackSnapshotPrimTyConName, promptTagPrimTyConName :: 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
    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
    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
    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
    stackSnapshotPrimTyConName :: Name
    stackSnapshotPrimTyConName    = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "StackSnapshot#") Unique
    stackSnapshotPrimTyConKey TyCon
    stackSnapshotPrimTyCon
    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
    promptTagPrimTyConName :: Name
    promptTagPrimTyConName        = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "PromptTag#") Unique
    promptTagPrimTyConKey TyCon
    promptTagPrimTyCon

    {- *********************************************************************
    *                                                                      *
                    Type variables
    *                                                                      *
    ********************************************************************* -}

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

    mkTemplateKindVar :: Kind -> TyVar
    mkTemplateKindVar :: Type -> TyVar
    mkTemplateKindVar = Name -> Type -> 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 :: [Type] -> [TyVar]
    mkTemplateKindVars [Type
    kind] = [Type -> TyVar
    mkTemplateKindVar Type
    kind]
      -- Special case for one kind: just "k"
    mkTemplateKindVars [Type]
    kinds
      = [ Name -> Type -> 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)) Type
    kind
        | (Type
    kind, Int
    u) <- [Type]
    kinds [Type] -> [Int] -> [(Type, 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 -> [Type] -> [TyVar]
    mkTemplateTyVarsFrom Int
    n [Type]
    kinds
      = [ Name -> Type -> TyVar
    mkTyVar Name
    name Type
    kind
        | (Type
    kind, Int
    index) <- [Type] -> [Int] -> [(Type, Int)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Type]
    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 :: [Type] -> [TyVar]
    mkTemplateTyVars = Int -> [Type] -> [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 :: [Type] -> ([Type] -> [Type]) -> [TyConBinder]
    mkTemplateTyConBinders [Type]
    kind_var_kinds [Type] -> [Type]
    mk_anon_arg_kinds
      = [TyConBinder]
    kv_bndrs [TyConBinder] -> [TyConBinder] -> [TyConBinder]
    forall a. [a] -> [a] -> [a]
    ++ [TyConBinder]
    tv_bndrs
      where
        kv_bndrs :: [TyConBinder]
    kv_bndrs   = [Type] -> [TyConBinder]
    mkTemplateKindTyConBinders [Type]
    kind_var_kinds
        anon_kinds :: [Type]
    anon_kinds = [Type] -> [Type]
    mk_anon_arg_kinds ([TyVar] -> [Type]
    mkTyVarTys ([TyConBinder] -> [TyVar]
    forall tv argf. [VarBndr tv argf] -> [tv]
    binderVars [TyConBinder]
    kv_bndrs))
        tv_bndrs :: [TyConBinder]
    tv_bndrs   = Int -> [Type] -> [TyConBinder]
    mkTemplateAnonTyConBindersFrom ([TyConBinder] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [TyConBinder]
    kv_bndrs) [Type]
    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::Type). blah
    -- call mkTemplateKiTyVars [RuntimeRep] (\[r] -> [TYPE r, Type])
    mkTemplateKiTyVars :: [Type] -> ([Type] -> [Type]) -> [TyVar]
    mkTemplateKiTyVars [Type]
    kind_var_kinds [Type] -> [Type]
    mk_arg_kinds
      = [TyVar]
    kv_bndrs [TyVar] -> [TyVar] -> [TyVar]
    forall a. [a] -> [a] -> [a]
    ++ [TyVar]
    tv_bndrs
      where
        kv_bndrs :: [TyVar]
    kv_bndrs   = [Type] -> [TyVar]
    mkTemplateKindVars [Type]
    kind_var_kinds
        anon_kinds :: [Type]
    anon_kinds = [Type] -> [Type]
    mk_arg_kinds ([TyVar] -> [Type]
    mkTyVarTys [TyVar]
    kv_bndrs)
        tv_bndrs :: [TyVar]
    tv_bndrs   = Int -> [Type] -> [TyVar]
    mkTemplateTyVarsFrom ([TyVar] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [TyVar]
    kv_bndrs) [Type]
    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::Type). blah
    -- call mkTemplateKiTyVar RuntimeRep (\r -> [TYPE r, Type])
    mkTemplateKiTyVar :: Type -> (Type -> [Type]) -> [TyVar]
    mkTemplateKiTyVar Type
    kind Type -> [Type]
    mk_arg_kinds
      = TyVar
    kv_bndr TyVar -> [TyVar] -> [TyVar]
    forall a. a -> [a] -> [a]
    : [TyVar]
    tv_bndrs
      where
        kv_bndr :: TyVar
    kv_bndr    = Type -> TyVar
    mkTemplateKindVar Type
    kind
        anon_kinds :: [Type]
    anon_kinds = Type -> [Type]
    mk_arg_kinds (TyVar -> Type
    mkTyVarTy TyVar
    kv_bndr)
        tv_bndrs :: [TyVar]
    tv_bndrs   = Int -> [Type] -> [TyVar]
    mkTemplateTyVarsFrom Int
    1 [Type]
    anon_kinds

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

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

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

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

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

    alphaTyVarSpec, betaTyVarSpec, gammaTyVarSpec, deltaTyVarSpec :: TyVarBinder
    (TyVarBinder
    alphaTyVarSpec:TyVarBinder
    betaTyVarSpec:TyVarBinder
    gammaTyVarSpec:TyVarBinder
    deltaTyVarSpec:[TyVarBinder]
    _) = ForAllTyFlag -> [TyVar] -> [TyVarBinder]
    forall vis. vis -> [TyVar] -> [VarBndr TyVar vis]
    mkTyVarBinders ForAllTyFlag
    Specified [TyVar]
    alphaTyVars

    alphaConstraintTyVars :: [TyVar]
    alphaConstraintTyVars :: [TyVar]
    alphaConstraintTyVars = [Type] -> [TyVar]
    mkTemplateTyVars ([Type] -> [TyVar]) -> [Type] -> [TyVar]
    forall a b. (a -> b) -> a -> b
    $ Type -> [Type]
    forall a. a -> [a]
    repeat Type
    constraintKind

    alphaConstraintTyVar :: TyVar
    (TyVar
    alphaConstraintTyVar:[TyVar]
    _) = [TyVar]
    alphaConstraintTyVars

    alphaConstraintTy :: Type
    alphaConstraintTy :: Type
    alphaConstraintTy = TyVar -> Type
    mkTyVarTy TyVar
    alphaConstraintTyVar

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

    alphaTyVarsUnliftedRep :: [TyVar]
    alphaTyVarsUnliftedRep :: [TyVar]
    alphaTyVarsUnliftedRep = [Type] -> [TyVar]
    mkTemplateTyVars ([Type] -> [TyVar]) -> [Type] -> [TyVar]
    forall a b. (a -> b) -> a -> b
    $ Type -> [Type]
    forall a. a -> [a]
    repeat Type
    unliftedTypeKind

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

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

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

    runtimeRep1TyVarInf, runtimeRep2TyVarInf :: TyVarBinder
    runtimeRep1TyVarInf :: TyVarBinder
    runtimeRep1TyVarInf = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep1TyVar
    runtimeRep2TyVarInf :: TyVarBinder
    runtimeRep2TyVarInf = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep2TyVar

    runtimeRep1Ty, runtimeRep2Ty, runtimeRep3Ty :: RuntimeRepType
    runtimeRep1Ty :: Type
    runtimeRep1Ty = TyVar -> Type
    mkTyVarTy TyVar
    runtimeRep1TyVar
    runtimeRep2Ty :: Type
    runtimeRep2Ty = TyVar -> Type
    mkTyVarTy TyVar
    runtimeRep2TyVar
    runtimeRep3Ty :: Type
    runtimeRep3Ty = TyVar -> Type
    mkTyVarTy TyVar
    runtimeRep3TyVar
    openAlphaTyVar, openBetaTyVar, openGammaTyVar :: TyVar
    -- alpha :: TYPE r1
    -- beta  :: TYPE r2
    -- gamma :: TYPE r3
    [TyVar
    openAlphaTyVar,TyVar
    openBetaTyVar,TyVar
    openGammaTyVar]
      = [Type] -> [TyVar]
    mkTemplateTyVars [ Type -> Type
    mk_TYPE_app Type
    runtimeRep1Ty
                         , Type -> Type
    mk_TYPE_app Type
    runtimeRep2Ty
                         , Type -> Type
    mk_TYPE_app Type
    runtimeRep3Ty]

    openAlphaTyVarSpec, openBetaTyVarSpec, openGammaTyVarSpec :: TyVarBinder
    openAlphaTyVarSpec :: TyVarBinder
    openAlphaTyVarSpec = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Specified TyVar
    openAlphaTyVar
    openBetaTyVarSpec :: TyVarBinder
    openBetaTyVarSpec  = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Specified TyVar
    openBetaTyVar
    openGammaTyVarSpec :: TyVarBinder
    openGammaTyVarSpec = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Specified TyVar
    openGammaTyVar

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

    levity1TyVar, levity2TyVar :: TyVar
    (TyVar
    levity2TyVar : TyVar
    levity1TyVar : [TyVar]
    _) -- NB: levity2TyVar before levity1TyVar
      = Int -> [TyVar] -> [TyVar]
    forall a. Int -> [a] -> [a]
    drop Int
    10 ([Type] -> [TyVar]
    mkTemplateTyVars (Type -> [Type]
    forall a. a -> [a]
    repeat Type
    levityTy)) -- selects 'k', 'l'
    -- The ordering of levity2TyVar before levity1TyVar is chosen so that
    -- the more common levity1TyVar uses the levity variable 'l'.

    levity1TyVarInf, levity2TyVarInf :: TyVarBinder
    levity1TyVarInf :: TyVarBinder
    levity1TyVarInf = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Inferred TyVar
    levity1TyVar
    levity2TyVarInf :: TyVarBinder
    levity2TyVarInf = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Inferred TyVar
    levity2TyVar

    levity1Ty, levity2Ty :: Type
    levity1Ty :: Type
    levity1Ty = TyVar -> Type
    mkTyVarTy TyVar
    levity1TyVar
    levity2Ty :: Type
    levity2Ty = TyVar -> Type
    mkTyVarTy TyVar
    levity2TyVar

    levPolyAlphaTyVar, levPolyBetaTyVar :: TyVar
    [TyVar
    levPolyAlphaTyVar, TyVar
    levPolyBetaTyVar] =
      [Type] -> [TyVar]
    mkTemplateTyVars
        [ Type -> Type
    mk_TYPE_app (TyCon -> [Type] -> Type
    mkTyConApp TyCon
    boxedRepDataConTyCon [Type
    levity1Ty])
        , Type -> Type
    mk_TYPE_app (TyCon -> [Type] -> Type
    mkTyConApp TyCon
    boxedRepDataConTyCon [Type
    levity2Ty])]
    -- alpha :: TYPE ('BoxedRep l)
    -- beta  :: TYPE ('BoxedRep k)

    levPolyAlphaTyVarSpec, levPolyBetaTyVarSpec :: TyVarBinder
    levPolyAlphaTyVarSpec :: TyVarBinder
    levPolyAlphaTyVarSpec = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Specified TyVar
    levPolyAlphaTyVar
    levPolyBetaTyVarSpec :: TyVarBinder
    levPolyBetaTyVarSpec  = ForAllTyFlag -> TyVar -> TyVarBinder
    forall vis. vis -> TyVar -> VarBndr TyVar vis
    mkTyVarBinder ForAllTyFlag
    Specified TyVar
    levPolyBetaTyVar

    levPolyAlphaTy, levPolyBetaTy :: Type
    levPolyAlphaTy :: Type
    levPolyAlphaTy = TyVar -> Type
    mkTyVarTy TyVar
    levPolyAlphaTyVar
    levPolyBetaTy :: Type
    levPolyBetaTy  = TyVar -> Type
    mkTyVarTy TyVar
    levPolyBetaTyVar

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

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

    {- Note [Function type constructors and FunTy]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    We have four distinct function type constructors, and a type synonym

     FUN :: forall (m :: Multiplicity) ->
            forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
            TYPE rep1 -> TYPE rep2 -> Type

     (=>)  :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
              CONSTRAINT rep1 -> TYPE rep2 -> Type

     (==>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
              CONSTRAINT rep1 -> CONSTRAINT rep2 -> Constraint

     (-=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
              TYPE rep1 -> CONSTRAINT rep2 -> Constraint

     type (->) = FUN Many

    For efficiency, all four are always represented by
      FunTy { ft_af :: FunTyFlag, ft_mult :: Mult
            , ft_arg :: Type, ft_res :: Type }
    rather than by using a TyConApp.

    * The four TyCons FUN, (=>), (==>), (-=>) are all wired in.
      But (->) is just a regular synonym, with no special treatment;
      in particular it is not wired-in.

    * The ft_af :: FunTyFlag distinguishes the four cases.
      See Note [FunTyFlag] in GHC.Types.Var.

    * The ft_af field is redundant: it can always be gleaned from
      the kinds of ft_arg and ft_res.  See Note [FunTyFlag] in GHC.Types.Var.

    * The ft_mult :: Mult field gives the first argument for FUN
      For the other three cases ft_mult is redundant; it is always Many.
      Note that of the four type constructors, only `FUN` takes a Multiplicity.

    * Functions in GHC.Core.Type help to build and decompose `FunTy`.
      * funTyConAppTy_maybe
      * funTyFlagTyCon
      * tyConAppFun_maybe
      * splitFunTy_maybe
      Use them!
    -}

    funTyFlagTyCon :: FunTyFlag -> TyCon
    -- `anonArgTyCon af` gets the TyCon that corresponds to the `FunTyFlag`
    -- But be careful: fUNTyCon has a different kind to the others!
    -- See Note [Function type constructors and FunTy]
    funTyFlagTyCon :: FunTyFlag -> TyCon
    funTyFlagTyCon FunTyFlag
    FTF_T_T = TyCon
    fUNTyCon
    funTyFlagTyCon FunTyFlag
    FTF_T_C = TyCon
    tcArrowTyCon
    funTyFlagTyCon FunTyFlag
    FTF_C_T = TyCon
    ctArrowTyCon
    funTyFlagTyCon FunTyFlag
    FTF_C_C = TyCon
    ccArrowTyCon

    isArrowTyCon :: TyCon -> Bool
    -- We don't bother to look for plain (->), because this function
    -- should only be used after unwrapping synonyms
    isArrowTyCon :: TyCon -> Bool
    isArrowTyCon TyCon
    tc
      = Bool -> SDoc -> (TyCon -> Unique) -> TyCon -> Unique
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr (Bool -> Bool
    not (TyCon -> Bool
    isTypeSynonymTyCon TyCon
    tc)) (TyCon -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr TyCon
    tc)
        TyCon -> Unique
    forall a. Uniquable a => a -> Unique
    getUnique TyCon
    tc Unique -> [Unique] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem`
        [Unique
    fUNTyConKey, Unique
    ctArrowTyConKey, Unique
    ccArrowTyConKey, Unique
    tcArrowTyConKey]

    fUNTyConName, ctArrowTyConName, ccArrowTyConName, tcArrowTyConName :: Name
    fUNTyConName :: Name
    fUNTyConName     = FastString -> Unique -> TyCon -> Name
    mkPrimTc        (String -> FastString
    fsLit String
    "FUN") Unique
    fUNTyConKey       TyCon
    fUNTyCon
    ctArrowTyConName :: Name
    ctArrowTyConName = FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc (String -> FastString
    fsLit String
    "=>")  Unique
    ctArrowTyConKey TyCon
    ctArrowTyCon
    ccArrowTyConName :: Name
    ccArrowTyConName = FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc (String -> FastString
    fsLit String
    "==>") Unique
    ccArrowTyConKey TyCon
    ccArrowTyCon
    tcArrowTyConName :: Name
    tcArrowTyConName = FastString -> Unique -> TyCon -> Name
    mkBuiltInPrimTc (String -> FastString
    fsLit String
    "-=>") Unique
    tcArrowTyConKey TyCon
    tcArrowTyCon

    -- | The @FUN@ type constructor.
    --
    -- @
    -- FUN :: forall (m :: Multiplicity) ->
    --        forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
    --        TYPE rep1 -> TYPE rep2 -> Type
    -- @
    --
    -- 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.
    fUNTyCon :: TyCon
    fUNTyCon :: TyCon
    fUNTyCon = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    fUNTyConName [TyConBinder]
    tc_bndrs Type
    liftedTypeKind [Role]
    tc_roles
      where
        -- See also unrestrictedFunTyCon
        tc_bndrs :: [TyConBinder]
    tc_bndrs = [ ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Required TyVar
    multiplicityTyVar1
                   , ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep1TyVar
                   , ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep2TyVar ]
                   [TyConBinder] -> [TyConBinder] -> [TyConBinder]
    forall a. [a] -> [a] -> [a]
    ++ [Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [ Type -> Type
    mk_TYPE_app Type
    runtimeRep1Ty
                                                 , Type -> Type
    mk_TYPE_app Type
    runtimeRep2Ty ]
        tc_roles :: [Role]
    tc_roles = [Role
    Nominal, Role
    Nominal, Role
    Nominal, Role
    Representational, Role
    Representational]

    -- (=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
    --         CONSTRAINT rep1 -> TYPE rep2 -> Type
    ctArrowTyCon :: TyCon
    ctArrowTyCon :: TyCon
    ctArrowTyCon = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    ctArrowTyConName [TyConBinder]
    tc_bndrs Type
    liftedTypeKind [Role]
    tc_roles
      where
        -- See also unrestrictedFunTyCon
        tc_bndrs :: [TyConBinder]
    tc_bndrs = [ ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep1TyVar
                   , ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep2TyVar ]
                   [TyConBinder] -> [TyConBinder] -> [TyConBinder]
    forall a. [a] -> [a] -> [a]
    ++ [Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [ Type -> Type
    mk_CONSTRAINT_app Type
    runtimeRep1Ty
                                                 , Type -> Type
    mk_TYPE_app       Type
    runtimeRep2Ty ]
        tc_roles :: [Role]
    tc_roles = [Role
    Nominal, Role
    Nominal, Role
    Representational, Role
    Representational]

    -- (==>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
    --          CONSTRAINT rep1 -> CONSTRAINT rep2 -> Constraint
    ccArrowTyCon :: TyCon
    ccArrowTyCon :: TyCon
    ccArrowTyCon = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    ccArrowTyConName [TyConBinder]
    tc_bndrs Type
    constraintKind [Role]
    tc_roles
      where
        -- See also unrestrictedFunTyCon
        tc_bndrs :: [TyConBinder]
    tc_bndrs = [ ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep1TyVar
                   , ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep2TyVar ]
                   [TyConBinder] -> [TyConBinder] -> [TyConBinder]
    forall a. [a] -> [a] -> [a]
    ++ [Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [ Type -> Type
    mk_CONSTRAINT_app Type
    runtimeRep1Ty
                                                 , Type -> Type
    mk_CONSTRAINT_app Type
    runtimeRep2Ty ]
        tc_roles :: [Role]
    tc_roles = [Role
    Nominal, Role
    Nominal, Role
    Representational, Role
    Representational]

    -- (-=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
    --          TYPE rep1 -> CONSTRAINT rep2 -> Constraint
    tcArrowTyCon :: TyCon
    tcArrowTyCon :: TyCon
    tcArrowTyCon = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    tcArrowTyConName [TyConBinder]
    tc_bndrs Type
    constraintKind [Role]
    tc_roles
      where
        -- See also unrestrictedFunTyCon
        tc_bndrs :: [TyConBinder]
    tc_bndrs = [ ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep1TyVar
                   , ForAllTyFlag -> TyVar -> TyConBinder
    mkNamedTyConBinder ForAllTyFlag
    Inferred TyVar
    runtimeRep2TyVar ]
                   [TyConBinder] -> [TyConBinder] -> [TyConBinder]
    forall a. [a] -> [a] -> [a]
    ++ [Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [ Type -> Type
    mk_TYPE_app       Type
    runtimeRep1Ty
                                                 , Type -> Type
    mk_CONSTRAINT_app Type
    runtimeRep2Ty ]
        tc_roles :: [Role]
    tc_roles = [Role
    Nominal, Role
    Nominal, Role
    Representational, Role
    Representational]

    {-
    ************************************************************************
    *                                                                      *
                    Type and Constraint
    *                                                                      *
    ************************************************************************

    Note [TYPE and CONSTRAINT]  aka Note [Type vs Constraint]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
    GHC distinguishes Type from Constraint throughout the compiler.
    See GHC Proposal #518, and tickets #21623 and #11715.

    All types that classify values have a kind of the form
      (TYPE rr) or (CONSTRAINT rr)
    where the `RuntimeRep` parameter, rr, tells us how the value is represented
    at runtime.  TYPE and CONSTRAINT are primitive type constructors.

    See Note [RuntimeRep polymorphism] about the `rr` parameter.

    There are a bunch of type synonyms and data types defined in the
    library ghc-prim:GHC.Types.  All of them are also wired in to GHC, in
    GHC.Builtin.Types

      type Constraint   = CONSTRAINT LiftedRep  :: Type

      type Type         = TYPE LiftedRep   :: Type
      type UnliftedType = TYPE UnliftedRep :: Type

      type LiftedRep    = BoxedRep Lifted   :: RuntimeRep
      type UnliftedRep  = BoxedRep Unlifted :: RuntimeRep

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

      data Levity = Lifted | Unlifted

    We abbreviate '*' specially (with -XStarIsType), as if we had this:
        type * = Type

    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])

        Eq Int       :: CONSTRAINT (BoxedRep Lifted)
        IP "foo" Int :: CONSTRAINT (BoxedRep Lifted)
        a ~ b        :: CONSTRAINT (BoxedRep Lifted)
        a ~# b       :: CONSTRAINT (TupleRep [])

    Constraints are mostly lifted, but unlifted ones are useful too.
    Specifically  (a ~# b) :: CONSTRAINT (TupleRep [])

    Wrinkles

    (W1) Type and Constraint are considered distinct throughout GHC. But they
         are not /apart/: see Note [Type and Constraint are not apart]

    (W2) We need two absent-error Ids, aBSENT_ERROR_ID for types of kind Type, and
         aBSENT_CONSTRAINT_ERROR_ID for types of kind Constraint.
         See Note [Type vs Constraint for error ids] in GHC.Core.Make.
         Ditto noInlineId vs noInlineConstraintId in GHC.Types.Id.Make;
         see Note [inlineId magic].

    (W3) We need a TypeOrConstraint flag in LitRubbish.

    (W4) In the CPR transformation, we can't unbox constructors with constraint
         arguments because unboxed tuples (# …, … #) currently only supports fields
         of type TYPE rr. See (CPR2) in Note [Which types are unboxed?] in
         GHC.Core.Opt.WorkWrap.Utils.

    Note [Type and Constraint are not apart]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Type and Constraint are not equal (eqType) but they are not /apart/
    either. Reason (c.f. #7451):

    * We want to allow newtype classes, where
        class C a where { op :: a -> a }

    * The axiom for such a class will look like
        axiom axC a :: (C a :: Constraint) ~# (a->a :: Type)

    * This axiom connects a type of kind Type with one of kind Constraint
      That is dangerous: kindCo (axC Int) :: Type ~N Constraint
      And /that/ is bad because we could have
         type family F a where
            F Type       = Int
            F Constraint = Bool
      So now we can prove Int ~N Bool, and all is lost.  We prevent this
      by saying that Type and Constraint are not Apart, which makes the
      above type family instances illegal.

    So we ensure that Type and Constraint are not apart; or, more
    precisely, that TYPE and CONSTRAINT are not apart.  This
    non-apart-ness check is implemented in GHC.Core.Unify.unify_ty: look
    for `maybeApart MARTypeVsConstraint`.

    Note that, as before, nothing prevents writing instances like:

      instance C (Proxy @Type a) where ...

    In particular, TYPE and CONSTRAINT (and the synonyms Type, Constraint
    etc) are all allowed in instance heads. It's just that TYPE is not
    apart from CONSTRAINT, which means that the above instance would
    irretrievably overlap with:

      instance C (Proxy @Constraint a) where ...

    Wrinkles

    (W1) In GHC.Core.RoughMap.roughMatchTyConName we are careful to map
         TYPE and CONSTRAINT to the same rough-map key.  Reason:
         If we insert (F @Constraint tys) into a FamInstEnv, and look
         up (F @Type tys'), we /must/ ensure that the (C @Constraint tys)
         appears among the unifiables when we do the lookupRM' in
         GHC.Core.FamInstEnv.lookup_fam_inst_env'.  So for the RoughMap we
         simply pretend that they are the same type constructor.  If we
         don't, we'll treat them as fully apart, which is unsound.

    (W2) We must extend this treatment to the different arrow types (see
         Note [Function type constructors and FunTy]): if we have
           FunCo (axC Int) <Int> :: (C Int => Int) ~ ((Int -> Int) -> Int),
         then we could extract an equality between (=>) and (->). We thus
         must ensure that (=>) and (->) (among the other arrow combinations)
         are not Apart. See the FunTy/FunTy case in GHC.Core.Unify.unify_ty.

    (W3) Are (TYPE IntRep) and (CONSTRAINT WordRep) apart?  In truth yes,
         they are.  But it's easier to say that they are not apart, by
         reporting "maybeApart" (which is always safe), rather than
         recurse into the arguments (whose kinds may be utterly different)
         to look for apartness inside them.  Again this is in
         GHC.Core.Unify.unify_ty.

    (W4) We give a different Typeable instance for Type than for Constraint.
         For type classes instances (unlike type family instances) it is not
         /unsound/ for Type and Constraint to treated as fully distinct; and
         for Typeable is desirable to give them different TypeReps.
         Certainly,
           - both Type and Constraint must /have/ a TypeRep, and
           - they had better not be the same (else eqTypeRep would give us
             a proof Type ~N Constraint, which we do not want
         So in GHC.Tc.Instance.Class.matchTypeable, Type and Constraint are
         treated as separate TyCons; i.e. given no special treatment.

    Note [RuntimeRep polymorphism]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Generally speaking, you can't be polymorphic in `RuntimeRep`.  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])
    -}

    ----------------------
    tYPETyCon :: TyCon
    tYPETyCon :: TyCon
    tYPETyCon = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    tYPETyConName
                            ([Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [Type
    runtimeRepTy])
                            Type
    liftedTypeKind
                            [Role
    Nominal]

    tYPETyConName :: Name
    tYPETyConName :: Name
    tYPETyConName = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "TYPE") Unique
    tYPETyConKey TyCon
    tYPETyCon

    tYPEKind :: Type
    tYPEKind :: Type
    tYPEKind = TyCon -> Type
    mkTyConTy TyCon
    tYPETyCon

    ----------------------
    cONSTRAINTTyCon :: TyCon
    cONSTRAINTTyCon :: TyCon
    cONSTRAINTTyCon = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    cONSTRAINTTyConName
                                  ([Type] -> [TyConBinder]
    mkTemplateAnonTyConBinders [Type
    runtimeRepTy])
                                  Type
    liftedTypeKind
                                  [Role
    Nominal]

    cONSTRAINTTyConName :: Name
    cONSTRAINTTyConName :: Name
    cONSTRAINTTyConName = FastString -> Unique -> TyCon -> Name
    mkPrimTc (String -> FastString
    fsLit String
    "CONSTRAINT") Unique
    cONSTRAINTTyConKey TyCon
    cONSTRAINTTyCon

    cONSTRAINTKind :: Type
    cONSTRAINTKind :: Type
    cONSTRAINTKind = TyCon -> Type
    mkTyConTy TyCon
    cONSTRAINTTyCon

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

    charPrimTy :: Type
    charPrimTy :: Type
    charPrimTy      = TyCon -> Type
    mkTyConTy TyCon
    charPrimTyCon
    charPrimTyCon :: TyCon
    charPrimTyCon :: TyCon
    charPrimTyCon   = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    charPrimTyConName Type
    wordRepDataConTy

    intPrimTy :: Type
    intPrimTy :: Type
    intPrimTy       = TyCon -> Type
    mkTyConTy TyCon
    intPrimTyCon
    intPrimTyCon :: TyCon
    intPrimTyCon :: TyCon
    intPrimTyCon    = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    intPrimTyConName Type
    intRepDataConTy

    int8PrimTy :: Type
    int8PrimTy :: Type
    int8PrimTy     = TyCon -> Type
    mkTyConTy TyCon
    int8PrimTyCon
    int8PrimTyCon :: TyCon
    int8PrimTyCon :: TyCon
    int8PrimTyCon  = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    int8PrimTyConName Type
    int8RepDataConTy

    int16PrimTy :: Type
    int16PrimTy :: Type
    int16PrimTy    = TyCon -> Type
    mkTyConTy TyCon
    int16PrimTyCon
    int16PrimTyCon :: TyCon
    int16PrimTyCon :: TyCon
    int16PrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    int16PrimTyConName Type
    int16RepDataConTy

    int32PrimTy :: Type
    int32PrimTy :: Type
    int32PrimTy     = TyCon -> Type
    mkTyConTy TyCon
    int32PrimTyCon
    int32PrimTyCon :: TyCon
    int32PrimTyCon :: TyCon
    int32PrimTyCon  = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    int32PrimTyConName Type
    int32RepDataConTy

    int64PrimTy :: Type
    int64PrimTy :: Type
    int64PrimTy     = TyCon -> Type
    mkTyConTy TyCon
    int64PrimTyCon
    int64PrimTyCon :: TyCon
    int64PrimTyCon :: TyCon
    int64PrimTyCon  = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    int64PrimTyConName Type
    int64RepDataConTy

    wordPrimTy :: Type
    wordPrimTy :: Type
    wordPrimTy      = TyCon -> Type
    mkTyConTy TyCon
    wordPrimTyCon
    wordPrimTyCon :: TyCon
    wordPrimTyCon :: TyCon
    wordPrimTyCon   = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    wordPrimTyConName Type
    wordRepDataConTy

    word8PrimTy :: Type
    word8PrimTy :: Type
    word8PrimTy     = TyCon -> Type
    mkTyConTy TyCon
    word8PrimTyCon
    word8PrimTyCon :: TyCon
    word8PrimTyCon :: TyCon
    word8PrimTyCon  = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    word8PrimTyConName Type
    word8RepDataConTy

    word16PrimTy :: Type
    word16PrimTy :: Type
    word16PrimTy    = TyCon -> Type
    mkTyConTy TyCon
    word16PrimTyCon
    word16PrimTyCon :: TyCon
    word16PrimTyCon :: TyCon
    word16PrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    word16PrimTyConName Type
    word16RepDataConTy

    word32PrimTy :: Type
    word32PrimTy :: Type
    word32PrimTy    = TyCon -> Type
    mkTyConTy TyCon
    word32PrimTyCon
    word32PrimTyCon :: TyCon
    word32PrimTyCon :: TyCon
    word32PrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    word32PrimTyConName Type
    word32RepDataConTy

    word64PrimTy :: Type
    word64PrimTy :: Type
    word64PrimTy    = TyCon -> Type
    mkTyConTy TyCon
    word64PrimTyCon
    word64PrimTyCon :: TyCon
    word64PrimTyCon :: TyCon
    word64PrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    word64PrimTyConName Type
    word64RepDataConTy

    addrPrimTy :: Type
    addrPrimTy :: Type
    addrPrimTy      = TyCon -> Type
    mkTyConTy TyCon
    addrPrimTyCon
    addrPrimTyCon :: TyCon
    addrPrimTyCon :: TyCon
    addrPrimTyCon   = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    addrPrimTyConName Type
    addrRepDataConTy

    floatPrimTy     :: Type
    floatPrimTy :: Type
    floatPrimTy     = TyCon -> Type
    mkTyConTy TyCon
    floatPrimTyCon
    floatPrimTyCon :: TyCon
    floatPrimTyCon :: TyCon
    floatPrimTyCon  = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    floatPrimTyConName Type
    floatRepDataConTy

    doublePrimTy :: Type
    doublePrimTy :: Type
    doublePrimTy    = TyCon -> Type
    mkTyConTy TyCon
    doublePrimTyCon
    doublePrimTyCon :: TyCon
    doublePrimTyCon :: TyCon
    doublePrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    doublePrimTyConName Type
    doubleRepDataConTy

    {-
    ************************************************************************
    *                                                                      *
       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 -> TYPE (TupleRep '[])
        --------------------------
    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.isEqPred 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 [Solving equality classes]
       in GHC.Tc.Solver.Dict

     * 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.Dict.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.

     * The data constructor of the class is "Eq#", not ":C~"

    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 -> TYPE (TupleRep '[])
        --------------------------
    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 -> TYPE (TupleRep '[])
        --------------------------
    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 :: Type -> Type
    mkStatePrimTy Type
    ty = TyCon -> [Type] -> Type
    TyConApp TyCon
    statePrimTyCon [Type
    ty]

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

    {-
    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] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    realWorldTyConName [] Type
    liftedTypeKind []
    realWorldTy :: Type
    realWorldTy :: Type
    realWorldTy          = TyCon -> Type
    mkTyConTy TyCon
    realWorldTyCon
    realWorldStatePrimTy :: Type
    realWorldStatePrimTy :: Type
    realWorldStatePrimTy = Type -> Type
    mkStatePrimTy Type
    realWorldTy        -- State# RealWorld
    realWorldMutableByteArrayPrimTy :: Type
    realWorldMutableByteArrayPrimTy :: Type
    realWorldMutableByteArrayPrimTy
      = Type -> Type
    mkMutableByteArrayPrimTy Type
    realWorldTy -- MutableByteArray# RealWorld

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

    proxyPrimTyCon :: TyCon
    proxyPrimTyCon :: TyCon
    proxyPrimTyCon = Name -> [TyConBinder] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    proxyPrimTyConName [TyConBinder]
    binders Type
    res_kind [Role
    Nominal,Role
    Phantom]
      where
         -- Kind: forall k. k -> TYPE (TupleRep '[])
         binders :: [TyConBinder]
    binders = [Type] -> ([Type] -> [Type]) -> [TyConBinder]
    mkTemplateTyConBinders [Type
    liftedTypeKind] [Type] -> [Type]
    forall a. a -> a
    id
         res_kind :: Type
    res_kind = [Type] -> Type
    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] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    eqPrimTyConName [TyConBinder]
    binders Type
    res_kind [Role]
    roles
      where
        -- Kind :: forall k1 k2. k1 -> k2 -> CONSTRAINT ZeroBitRep
        binders :: [TyConBinder]
    binders  = [Type] -> ([Type] -> [Type]) -> [TyConBinder]
    mkTemplateTyConBinders [Type
    liftedTypeKind, Type
    liftedTypeKind] [Type] -> [Type]
    forall a. a -> a
    id
        res_kind :: Type
    res_kind = TyCon -> [Type] -> Type
    TyConApp TyCon
    cONSTRAINTTyCon [Type
    zeroBitRepTy]
        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] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    eqReprPrimTyConName [TyConBinder]
    binders Type
    res_kind [Role]
    roles
      where
        -- Kind :: forall k1 k2. k1 -> k2 -> CONSTRAINT ZeroBitRep
        binders :: [TyConBinder]
    binders  = [Type] -> ([Type] -> [Type]) -> [TyConBinder]
    mkTemplateTyConBinders [Type
    liftedTypeKind, Type
    liftedTypeKind] [Type] -> [Type]
    forall a. a -> a
    id
        res_kind :: Type
    res_kind = TyCon -> [Type] -> Type
    TyConApp TyCon
    cONSTRAINTTyCon [Type
    zeroBitRepTy]
        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] -> Type -> [Role] -> TyCon
    mkPrimTyCon Name
    eqPhantPrimTyConName [TyConBinder]
    binders Type
    res_kind [Role]
    roles
      where
        -- Kind :: forall k1 k2. k1 -> k2 -> CONSTRAINT ZeroBitRep
        binders :: [TyConBinder]
    binders  = [Type] -> ([Type] -> [Type]) -> [TyConBinder]
    mkTemplateTyConBinders [Type
    liftedTypeKind, Type
    liftedTypeKind] [Type] -> [Type]
    forall a. a -> a
    id
        res_kind :: Type
    res_kind = TyCon -> [Type] -> Type
    TyConApp TyCon
    cONSTRAINTTyCon [Type
    zeroBitRepTy]
        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,
        smallArrayPrimTyCon, smallMutableArrayPrimTyCon :: TyCon
    arrayPrimTyCon :: TyCon
    arrayPrimTyCon             = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    arrayPrimTyConName        [Role
    Representational]          Type
    unliftedRepTy
    mutableArrayPrimTyCon :: TyCon
    mutableArrayPrimTyCon      = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    mutableArrayPrimTyConName [Role
    Nominal, Role
    Representational] Type
    unliftedRepTy
    mutableByteArrayPrimTyCon :: TyCon
    mutableByteArrayPrimTyCon  = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon Name
    mutableByteArrayPrimTyConName  [Role
    Nominal] Type
    unliftedRepTy
    byteArrayPrimTyCon :: TyCon
    byteArrayPrimTyCon         = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    byteArrayPrimTyConName        Type
    unliftedRepTy
    smallArrayPrimTyCon :: TyCon
    smallArrayPrimTyCon        = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    smallArrayPrimTyConName        [Role
    Representational]          Type
    unliftedRepTy
    smallMutableArrayPrimTyCon :: TyCon
    smallMutableArrayPrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    smallMutableArrayPrimTyConName [Role
    Nominal, Role
    Representational] Type
    unliftedRepTy

    mkArrayPrimTy :: Type -> Type
    mkArrayPrimTy :: Type -> Type
    mkArrayPrimTy Type
    elt           = TyCon -> [Type] -> Type
    TyConApp TyCon
    arrayPrimTyCon [HasDebugCallStack => Type -> Type
    Type -> Type
    getLevity Type
    elt, Type
    elt]
    byteArrayPrimTy :: Type
    byteArrayPrimTy :: Type
    byteArrayPrimTy             = TyCon -> Type
    mkTyConTy TyCon
    byteArrayPrimTyCon
    mkSmallArrayPrimTy :: Type -> Type
    mkSmallArrayPrimTy :: Type -> Type
    mkSmallArrayPrimTy Type
    elt = TyCon -> [Type] -> Type
    TyConApp TyCon
    smallArrayPrimTyCon [HasDebugCallStack => Type -> Type
    Type -> Type
    getLevity Type
    elt, Type
    elt]
    mkMutableArrayPrimTy :: Type -> Type -> Type
    mkMutableArrayPrimTy :: Type -> Type -> Type
    mkMutableArrayPrimTy Type
    s Type
    elt  = TyCon -> [Type] -> Type
    TyConApp TyCon
    mutableArrayPrimTyCon [HasDebugCallStack => Type -> Type
    Type -> Type
    getLevity Type
    elt, Type
    s, Type
    elt]
    mkMutableByteArrayPrimTy :: Type -> Type
    mkMutableByteArrayPrimTy :: Type -> Type
    mkMutableByteArrayPrimTy Type
    s  = TyCon -> [Type] -> Type
    TyConApp TyCon
    mutableByteArrayPrimTyCon [Type
    s]
    mkSmallMutableArrayPrimTy :: Type -> Type -> Type
    mkSmallMutableArrayPrimTy :: Type -> Type -> Type
    mkSmallMutableArrayPrimTy Type
    s Type
    elt = TyCon -> [Type] -> Type
    TyConApp TyCon
    smallMutableArrayPrimTyCon [HasDebugCallStack => Type -> Type
    Type -> Type
    getLevity Type
    elt, Type
    s, Type
    elt]

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

    mutVarPrimTyCon :: TyCon
    mutVarPrimTyCon :: TyCon
    mutVarPrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    mutVarPrimTyConName [Role
    Nominal, Role
    Representational] Type
    unliftedRepTy

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

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

    mVarPrimTyCon :: TyCon
    mVarPrimTyCon :: TyCon
    mVarPrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    mVarPrimTyConName [Role
    Nominal, Role
    Representational] Type
    unliftedRepTy

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

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

    tVarPrimTyCon :: TyCon
    tVarPrimTyCon :: TyCon
    tVarPrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    tVarPrimTyConName [Role
    Nominal, Role
    Representational] Type
    unliftedRepTy

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

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

    stablePtrPrimTyCon :: TyCon
    stablePtrPrimTyCon :: TyCon
    stablePtrPrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    stablePtrPrimTyConName [Role
    Representational] Type
    addrRepDataConTy

    mkStablePtrPrimTy :: Type -> Type
    mkStablePtrPrimTy :: Type -> Type
    mkStablePtrPrimTy Type
    ty = TyCon -> [Type] -> Type
    TyConApp TyCon
    stablePtrPrimTyCon [HasDebugCallStack => Type -> Type
    Type -> Type
    getLevity Type
    ty, Type
    ty]

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

    stableNamePrimTyCon :: TyCon
    stableNamePrimTyCon :: TyCon
    stableNamePrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    stableNamePrimTyConName [Role
    Phantom] Type
    unliftedRepTy

    mkStableNamePrimTy :: Type -> Type
    mkStableNamePrimTy :: Type -> Type
    mkStableNamePrimTy Type
    ty = TyCon -> [Type] -> Type
    TyConApp TyCon
    stableNamePrimTyCon [HasDebugCallStack => Type -> Type
    Type -> Type
    getLevity Type
    ty, Type
    ty]

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

    compactPrimTyCon :: TyCon
    compactPrimTyCon :: TyCon
    compactPrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    compactPrimTyConName Type
    unliftedRepTy

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

    {-
    ************************************************************************
    *                                                                      *
       The @StackSnapshot#@ type
    *                                                                      *
    ************************************************************************
    -}

    stackSnapshotPrimTyCon :: TyCon
    stackSnapshotPrimTyCon :: TyCon
    stackSnapshotPrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    stackSnapshotPrimTyConName Type
    unliftedRepTy

    stackSnapshotPrimTy :: Type
    stackSnapshotPrimTy :: Type
    stackSnapshotPrimTy = TyCon -> Type
    mkTyConTy TyCon
    stackSnapshotPrimTyCon

    {-
    ************************************************************************
    *                                                                      *
       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 :: Type
    bcoPrimTy    = TyCon -> Type
    mkTyConTy TyCon
    bcoPrimTyCon
    bcoPrimTyCon :: TyCon
    bcoPrimTyCon :: TyCon
    bcoPrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    bcoPrimTyConName Type
    liftedRepTy

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

    weakPrimTyCon :: TyCon
    weakPrimTyCon :: TyCon
    weakPrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon_LevPolyLastArg Name
    weakPrimTyConName [Role
    Representational] Type
    unliftedRepTy

    mkWeakPrimTy :: Type -> Type
    mkWeakPrimTy :: Type -> Type
    mkWeakPrimTy Type
    v = TyCon -> [Type] -> Type
    TyConApp TyCon
    weakPrimTyCon [HasDebugCallStack => Type -> Type
    Type -> Type
    getLevity Type
    v, Type
    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 :: Type
    threadIdPrimTy    = TyCon -> Type
    mkTyConTy TyCon
    threadIdPrimTyCon
    threadIdPrimTyCon :: TyCon
    threadIdPrimTyCon :: TyCon
    threadIdPrimTyCon = Name -> Type -> TyCon
    pcPrimTyCon0 Name
    threadIdPrimTyConName Type
    unliftedRepTy

    {-
    ************************************************************************
    *                                                                      *
       The ``prompt tag'' type
    *                                                                      *
    ************************************************************************
    -}

    promptTagPrimTyCon :: TyCon
    promptTagPrimTyCon :: TyCon
    promptTagPrimTyCon = Name -> [Role] -> Type -> TyCon
    pcPrimTyCon Name
    promptTagPrimTyConName [Role
    Representational] Type
    unliftedRepTy

    mkPromptTagPrimTy :: Type -> Type
    mkPromptTagPrimTy :: Type -> Type
    mkPromptTagPrimTy Type
    v = TyCon -> [Type] -> Type
    TyConApp TyCon
    promptTagPrimTyCon [Type
    v]

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

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