    {-|
      Copyright   :  (C) 2012-2016, University of Twente,
                         2016     , Myrtle Software Ltd,
                         2021     , QBayLogic B.V.
      License     :  BSD2 (see the file LICENSE)
      Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com>

      Builtin Type and Kind definitions
    -}

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE TemplateHaskellQuotes #-}

    module Clash.Core.TysPrim
      ( liftedTypeKind
      , typeNatKind
      , typeSymbolKind
      , intPrimTy
      , integerPrimTy
      , charPrimTy
      , stringPrimTy
    #if !MIN_VERSION_ghc(9,2,0)
      , voidPrimTy
    #endif
      , wordPrimTy
      , int64PrimTy
      , word64PrimTy
    #if MIN_VERSION_ghc(8,8,0)
      , int8PrimTy
      , int16PrimTy
      , int32PrimTy
      , word8PrimTy
      , word16PrimTy
      , word32PrimTy
    #endif
      , floatPrimTy
      , doublePrimTy
      , naturalPrimTy
      , byteArrayPrimTy
      , eqPrimTy
      , tysPrimMap
      )
    where

    #if MIN_VERSION_ghc(9,0,0)
    import           GHC.Builtin.Names
    import           GHC.Types.Unique     (getKey)
    #else
    import           PrelNames
    import           Unique               (getKey)
    #endif

    #if MIN_VERSION_ghc(8,8,0)
    import           GHC.Base hiding (Type, TyCon)
    import           Data.Text.Extra (showt)
    #endif

    #if MIN_VERSION_base(4,17,0)
    import           Clash.Core.DataCon (DataCon(..), DcStrictness(..))
    import           GHC.Num.Integer (Integer(..))
    import           GHC.Num.Natural (Natural(..))
    #endif

    import           Clash.Core.Name
    import           Clash.Core.TyCon
    import           Clash.Core.Type
    import           Clash.Core.Var (mkTyVar)
    import qualified Clash.Data.UniqMap as UniqMap

    -- | Builtin Name
    liftedTypeKindTyConName, typeNatKindTyConName, typeSymbolKindTyConName :: TyConName
    liftedTypeKindTyConName :: TyConName
    liftedTypeKindTyConName   = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "Type" (Unique -> Unique
    getKey Unique
    liftedTypeKindTyConKey)
    #if MIN_VERSION_ghc(9,2,0)
    typeNatKindTyConName :: TyConName
    typeNatKindTyConName      = TyConName
    naturalPrimTyConName
    #else
    typeNatKindTyConName      = mkUnsafeSystemName "Nat" (getKey typeNatKindConNameKey)
    #endif
    typeSymbolKindTyConName :: TyConName
    typeSymbolKindTyConName   = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "Symbol" (Unique -> Unique
    getKey Unique
    typeSymbolKindConNameKey)

    -- | Builtin Kind
    liftedTypeKindTc, typeNatKindTc, typeSymbolKindTc :: TyCon
    liftedTypeKindTc :: TyCon
    liftedTypeKindTc = TyConName -> Kind -> TyCon
    mkKindTyCon TyConName
    liftedTypeKindTyConName Kind
    liftedTypeKind
    typeNatKindTc :: TyCon
    typeNatKindTc    = TyConName -> Kind -> TyCon
    mkKindTyCon TyConName
    typeNatKindTyConName Kind
    liftedTypeKind
    typeSymbolKindTc :: TyCon
    typeSymbolKindTc = TyConName -> Kind -> TyCon
    mkKindTyCon TyConName
    typeSymbolKindTyConName Kind
    liftedTypeKind

    liftedTypeKind, typeNatKind, typeSymbolKind :: Type
    liftedTypeKind :: Kind
    liftedTypeKind = TyConName -> Kind
    mkTyConTy TyConName
    liftedTypeKindTyConName
    typeNatKind :: Kind
    typeNatKind    = TyConName -> Kind
    mkTyConTy TyConName
    typeNatKindTyConName
    typeSymbolKind :: Kind
    typeSymbolKind = TyConName -> Kind
    mkTyConTy TyConName
    typeSymbolKindTyConName

    intPrimTyConName, integerPrimTyConName, charPrimTyConName, stringPrimTyConName,
      wordPrimTyConName,  int64PrimTyConName, word64PrimTyConName,
      floatPrimTyConName, doublePrimTyConName,
      naturalPrimTyConName, byteArrayPrimTyConName, eqPrimTyConName :: TyConName
    intPrimTyConName :: TyConName
    intPrimTyConName     = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Int#"
                                    (Unique -> Unique
    getKey Unique
    intPrimTyConKey)
    #if MIN_VERSION_base(4,15,0)
    integerPrimTyConName :: TyConName
    integerPrimTyConName = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Num.Integer.Integer"
                                    (Unique -> Unique
    getKey Unique
    integerTyConKey)
    #else
    integerPrimTyConName = mkUnsafeSystemName "GHC.Integer.Type.Integer"
                                    (getKey integerTyConKey)
    #endif
    stringPrimTyConName :: TyConName
    stringPrimTyConName  = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Addr#" (Unique -> Unique
    getKey Unique
    addrPrimTyConKey)
    charPrimTyConName :: TyConName
    charPrimTyConName    = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Char#"
                                    (Unique -> Unique
    getKey Unique
    charPrimTyConKey)
    wordPrimTyConName :: TyConName
    wordPrimTyConName    = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Word#"
                                    (Unique -> Unique
    getKey Unique
    wordPrimTyConKey)
    int64PrimTyConName :: TyConName
    int64PrimTyConName   = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Int64#"
                                    (Unique -> Unique
    getKey Unique
    int64PrimTyConKey)
    word64PrimTyConName :: TyConName
    word64PrimTyConName  = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Word64#"
                                    (Unique -> Unique
    getKey Unique
    word64PrimTyConKey)
    floatPrimTyConName :: TyConName
    floatPrimTyConName   = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Float#"
                                    (Unique -> Unique
    getKey Unique
    floatPrimTyConKey)
    doublePrimTyConName :: TyConName
    doublePrimTyConName  = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.Double#"
                                    (Unique -> Unique
    getKey Unique
    doublePrimTyConKey)
    #if MIN_VERSION_base(4,15,0)
    naturalPrimTyConName :: TyConName
    naturalPrimTyConName = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Num.Natural.Natural"
                                    (Unique -> Unique
    getKey Unique
    naturalTyConKey)
    #else
    naturalPrimTyConName = mkUnsafeSystemName "GHC.Natural.Natural"
                                    (getKey naturalTyConKey)
    #endif
    byteArrayPrimTyConName :: TyConName
    byteArrayPrimTyConName = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.ByteArray#"
                              (Unique -> Unique
    getKey Unique
    byteArrayPrimTyConKey)

    eqPrimTyConName :: TyConName
    eqPrimTyConName = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "GHC.Prim.~#" (Unique -> Unique
    getKey Unique
    eqPrimTyConKey)

    #if !MIN_VERSION_ghc(9,2,0)
    voidPrimTyConName :: TyConName
    voidPrimTyConName    = mkUnsafeSystemName "Void#" (getKey voidPrimTyConKey)
    #endif

    #if MIN_VERSION_ghc(8,8,0)
    int8PrimTyConName, int16PrimTyConName, int32PrimTyConName, word8PrimTyConName,
      word16PrimTyConName, word32PrimTyConName :: TyConName
    int8PrimTyConName :: TyConName
    int8PrimTyConName   = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt ''Int8#) (Unique -> Unique
    getKey Unique
    int8PrimTyConKey)
    int16PrimTyConName :: TyConName
    int16PrimTyConName  = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt ''Int16#) (Unique -> Unique
    getKey Unique
    int16PrimTyConKey)
    int32PrimTyConName :: TyConName
    int32PrimTyConName  = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt ''Int32#) (Unique -> Unique
    getKey Unique
    int32PrimTyConKey)
    word8PrimTyConName :: TyConName
    word8PrimTyConName  = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt ''Word8#) (Unique -> Unique
    getKey Unique
    word8PrimTyConKey)
    word16PrimTyConName :: TyConName
    word16PrimTyConName = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt ''Word16#) (Unique -> Unique
    getKey Unique
    word16PrimTyConKey)
    word32PrimTyConName :: TyConName
    word32PrimTyConName = Text -> Unique -> TyConName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt ''Word32#) (Unique -> Unique
    getKey Unique
    word32PrimTyConKey)
    #endif

    liftedPrimTC :: TyConName
                 -> TyCon
    liftedPrimTC :: TyConName -> TyCon
    liftedPrimTC TyConName
    name = Unique -> TyConName -> Kind -> Unique -> TyCon
    PrimTyCon (TyConName -> Unique
    forall a. Name a -> Unique
    nameUniq TyConName
    name) TyConName
    name Kind
    liftedTypeKind Unique
    0

    -- | Builtin Type
    intPrimTc, integerPrimTc, charPrimTc, stringPrimTc, wordPrimTc,
      int64PrimTc, word64PrimTc, floatPrimTc, doublePrimTc, naturalPrimTc,
      byteArrayPrimTc :: TyCon
    intPrimTc :: TyCon
    intPrimTc     = TyConName -> TyCon
    liftedPrimTC TyConName
    intPrimTyConName
    #if MIN_VERSION_base(4,17,0)
    -- While GHC might have dropped Integer and Natural literals, in Clash it is
    -- still nice to have them around. However, Integer and Natural are also no
    -- longer primitive types in GHC, but we still want to give the Integer and
    -- Natural type to our Integer and Natural literals.
    --
    -- So instead of recording the primitive types, we record the algebraic types,
    -- i.e. the complete data type for Integer and Natural, data constructors and all.

    integerPrimTc :: TyCon
    integerPrimTc =
      let
        name :: TyConName
    name = TyConName
    integerPrimTyConName
        uniq :: Unique
    uniq = TyConName -> Unique
    forall a. Name a -> Unique
    nameUniq TyConName
    name
        isDcNm :: Name a
    isDcNm = Text -> Unique -> Name a
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt 'IS) (Unique -> Unique
    getKey Unique
    integerISDataConKey)
        isDc :: DataCon
    isDc = MkData
          { dcName :: DcName
    dcName = DcName
    forall {a}. Name a
    isDcNm
          , dcUniq :: Unique
    dcUniq = Name Any -> Unique
    forall a. Name a -> Unique
    nameUniq Name Any
    forall {a}. Name a
    isDcNm
          , dcTag :: Unique
    dcTag  = Unique
    1
          , dcType :: Kind
    dcType = Kind -> [Either TyVar Kind] -> Kind
    mkPolyFunTy Kind
    integerPrimTy [Kind -> Either TyVar Kind
    forall a b. b -> Either a b
    Right Kind
    intPrimTy]
          , dcUnivTyVars :: [TyVar]
    dcUnivTyVars = []
          , dcExtTyVars :: [TyVar]
    dcExtTyVars = []
          , dcArgTys :: [Kind]
    dcArgTys = [Kind
    intPrimTy]
          , dcArgStrict :: [DcStrictness]
    dcArgStrict = [DcStrictness
    Strict]
          , dcFieldLabels :: [Text]
    dcFieldLabels = []
          }
        ipDcNm :: Name a
    ipDcNm = Text -> Unique -> Name a
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt 'IP) (Unique -> Unique
    getKey Unique
    integerIPDataConKey)
        ipDc :: DataCon
    ipDc = MkData
          { dcName :: DcName
    dcName = DcName
    forall {a}. Name a
    ipDcNm
          , dcUniq :: Unique
    dcUniq = Name Any -> Unique
    forall a. Name a -> Unique
    nameUniq Name Any
    forall {a}. Name a
    ipDcNm
          , dcTag :: Unique
    dcTag  = Unique
    2
          , dcType :: Kind
    dcType = Kind -> [Either TyVar Kind] -> Kind
    mkPolyFunTy Kind
    integerPrimTy [Kind -> Either TyVar Kind
    forall a b. b -> Either a b
    Right Kind
    byteArrayPrimTy]
          , dcUnivTyVars :: [TyVar]
    dcUnivTyVars = []
          , dcExtTyVars :: [TyVar]
    dcExtTyVars = []
          , dcArgTys :: [Kind]
    dcArgTys = [Kind
    byteArrayPrimTy]
          , dcArgStrict :: [DcStrictness]
    dcArgStrict = [DcStrictness
    Strict]
          , dcFieldLabels :: [Text]
    dcFieldLabels = []
          }
        inDcNm :: Name a
    inDcNm = Text -> Unique -> Name a
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt 'IN) (Unique -> Unique
    getKey Unique
    integerINDataConKey)
        inDc :: DataCon
    inDc = MkData
          { dcName :: DcName
    dcName = DcName
    forall {a}. Name a
    inDcNm
          , dcUniq :: Unique
    dcUniq = Name Any -> Unique
    forall a. Name a -> Unique
    nameUniq Name Any
    forall {a}. Name a
    inDcNm
          , dcTag :: Unique
    dcTag  = Unique
    3
          , dcType :: Kind
    dcType = Kind -> [Either TyVar Kind] -> Kind
    mkPolyFunTy Kind
    integerPrimTy [Kind -> Either TyVar Kind
    forall a b. b -> Either a b
    Right Kind
    byteArrayPrimTy]
          , dcUnivTyVars :: [TyVar]
    dcUnivTyVars = []
          , dcExtTyVars :: [TyVar]
    dcExtTyVars = []
          , dcArgTys :: [Kind]
    dcArgTys = [Kind
    byteArrayPrimTy]
          , dcArgStrict :: [DcStrictness]
    dcArgStrict = [DcStrictness
    Strict]
          , dcFieldLabels :: [Text]
    dcFieldLabels = []
          }
        rhs :: AlgTyConRhs
    rhs = [DataCon] -> AlgTyConRhs
    DataTyCon [DataCon
    isDc,DataCon
    ipDc,DataCon
    inDc]
      in
        Unique
    -> TyConName -> Kind -> Unique -> AlgTyConRhs -> Bool -> TyCon
    AlgTyCon Unique
    uniq TyConName
    name Kind
    liftedTypeKind Unique
    0 AlgTyConRhs
    rhs Bool
    False

    naturalPrimTc :: TyCon
    naturalPrimTc =
      let
        name :: TyConName
    name = TyConName
    naturalPrimTyConName
        uniq :: Unique
    uniq = TyConName -> Unique
    forall a. Name a -> Unique
    nameUniq TyConName
    name
        nsDcNm :: Name a
    nsDcNm = Text -> Unique -> Name a
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt 'NS) (Unique -> Unique
    getKey Unique
    naturalNSDataConKey)
        nsDc :: DataCon
    nsDc = MkData
          { dcName :: DcName
    dcName = DcName
    forall {a}. Name a
    nsDcNm
          , dcUniq :: Unique
    dcUniq = Name Any -> Unique
    forall a. Name a -> Unique
    nameUniq Name Any
    forall {a}. Name a
    nsDcNm
          , dcTag :: Unique
    dcTag  = Unique
    1
          , dcType :: Kind
    dcType = Kind -> [Either TyVar Kind] -> Kind
    mkPolyFunTy Kind
    naturalPrimTy [Kind -> Either TyVar Kind
    forall a b. b -> Either a b
    Right Kind
    wordPrimTy]
          , dcUnivTyVars :: [TyVar]
    dcUnivTyVars = []
          , dcExtTyVars :: [TyVar]
    dcExtTyVars = []
          , dcArgTys :: [Kind]
    dcArgTys = [Kind
    wordPrimTy]
          , dcArgStrict :: [DcStrictness]
    dcArgStrict = [DcStrictness
    Strict]
          , dcFieldLabels :: [Text]
    dcFieldLabels = []
          }
        nbDcNm :: Name a
    nbDcNm = Text -> Unique -> Name a
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName (Name -> Text
    forall a. Show a => a -> Text
    showt 'NB) (Unique -> Unique
    getKey Unique
    naturalNBDataConKey)
        nbDc :: DataCon
    nbDc = MkData
          { dcName :: DcName
    dcName = DcName
    forall {a}. Name a
    nbDcNm
          , dcUniq :: Unique
    dcUniq = Name Any -> Unique
    forall a. Name a -> Unique
    nameUniq Name Any
    forall {a}. Name a
    nbDcNm
          , dcTag :: Unique
    dcTag  = Unique
    2
          , dcType :: Kind
    dcType = Kind -> [Either TyVar Kind] -> Kind
    mkPolyFunTy Kind
    naturalPrimTy [Kind -> Either TyVar Kind
    forall a b. b -> Either a b
    Right Kind
    byteArrayPrimTy]
          , dcUnivTyVars :: [TyVar]
    dcUnivTyVars = []
          , dcExtTyVars :: [TyVar]
    dcExtTyVars = []
          , dcArgTys :: [Kind]
    dcArgTys = [Kind
    byteArrayPrimTy]
          , dcArgStrict :: [DcStrictness]
    dcArgStrict = [DcStrictness
    Strict]
          , dcFieldLabels :: [Text]
    dcFieldLabels = []
          }
        rhs :: AlgTyConRhs
    rhs = [DataCon] -> AlgTyConRhs
    DataTyCon [DataCon
    nsDc,DataCon
    nbDc]
       in
        Unique
    -> TyConName -> Kind -> Unique -> AlgTyConRhs -> Bool -> TyCon
    AlgTyCon Unique
    uniq TyConName
    name Kind
    liftedTypeKind Unique
    0 AlgTyConRhs
    rhs Bool
    False
    #else
    integerPrimTc = liftedPrimTC integerPrimTyConName
    naturalPrimTc = liftedPrimTC naturalPrimTyConName
    #endif
    charPrimTc :: TyCon
    charPrimTc    = TyConName -> TyCon
    liftedPrimTC TyConName
    charPrimTyConName
    stringPrimTc :: TyCon
    stringPrimTc  = TyConName -> TyCon
    liftedPrimTC TyConName
    stringPrimTyConName
    wordPrimTc :: TyCon
    wordPrimTc    = TyConName -> TyCon
    liftedPrimTC TyConName
    wordPrimTyConName
    int64PrimTc :: TyCon
    int64PrimTc   = TyConName -> TyCon
    liftedPrimTC TyConName
    int64PrimTyConName
    word64PrimTc :: TyCon
    word64PrimTc  = TyConName -> TyCon
    liftedPrimTC TyConName
    word64PrimTyConName
    floatPrimTc :: TyCon
    floatPrimTc   = TyConName -> TyCon
    liftedPrimTC TyConName
    floatPrimTyConName
    doublePrimTc :: TyCon
    doublePrimTc  = TyConName -> TyCon
    liftedPrimTC TyConName
    doublePrimTyConName
    byteArrayPrimTc :: TyCon
    byteArrayPrimTc = TyConName -> TyCon
    liftedPrimTC  TyConName
    byteArrayPrimTyConName

    #if !MIN_VERSION_ghc(9,2,0)
    voidPrimTc :: TyCon
    voidPrimTc    = liftedPrimTC voidPrimTyConName
    #endif

    #if MIN_VERSION_ghc(8,8,0)
    int8PrimTc, int16PrimTc, int32PrimTc, word8PrimTc, word16PrimTc,
      word32PrimTc :: TyCon
    int8PrimTc :: TyCon
    int8PrimTc    = TyConName -> TyCon
    liftedPrimTC TyConName
    int8PrimTyConName
    int16PrimTc :: TyCon
    int16PrimTc   = TyConName -> TyCon
    liftedPrimTC TyConName
    int16PrimTyConName
    int32PrimTc :: TyCon
    int32PrimTc   = TyConName -> TyCon
    liftedPrimTC TyConName
    int32PrimTyConName
    word8PrimTc :: TyCon
    word8PrimTc   = TyConName -> TyCon
    liftedPrimTC TyConName
    word8PrimTyConName
    word16PrimTc :: TyCon
    word16PrimTc  = TyConName -> TyCon
    liftedPrimTC TyConName
    word16PrimTyConName
    word32PrimTc :: TyCon
    word32PrimTc  = TyConName -> TyCon
    liftedPrimTC TyConName
    word32PrimTyConName
    #endif

    eqPrimTc :: TyCon
    eqPrimTc :: TyCon
    eqPrimTc = Unique -> TyConName -> Kind -> Unique -> TyCon
    PrimTyCon (TyConName -> Unique
    forall a. Name a -> Unique
    nameUniq TyConName
    eqPrimTyConName) TyConName
    eqPrimTyConName Kind
    ty Unique
    4
     where
      -- forall (a :: Type). forall (b :: Type). a -> b -> Type
      --
      -- The "real" type for this in GHC has a codomain of `TYPE ('TupleRep '[])`
      -- instead of the `TYPE 'LiftedRep` used here.
      ty :: Kind
    ty  = Kind -> [Either TyVar Kind] -> Kind
    mkPolyFunTy Kind
    liftedTypeKind
        [TyVar -> Either TyVar Kind
    forall a b. a -> Either a b
    Left TyVar
    aTv, TyVar -> Either TyVar Kind
    forall a b. a -> Either a b
    Left TyVar
    bTv, Kind -> Either TyVar Kind
    forall a b. b -> Either a b
    Right (TyVar -> Kind
    VarTy TyVar
    aTv), Kind -> Either TyVar Kind
    forall a b. b -> Either a b
    Right (TyVar -> Kind
    VarTy TyVar
    bTv)]

      aTv :: TyVar
    aTv = Kind -> TyName -> TyVar
    mkTyVar Kind
    liftedTypeKind (Text -> Unique -> TyName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "a" Unique
    0)
      bTv :: TyVar
    bTv = Kind -> TyName -> TyVar
    mkTyVar Kind
    liftedTypeKind (Text -> Unique -> TyName
    forall a. Text -> Unique -> Name a
    mkUnsafeSystemName Text
    "b" Unique
    1)

    intPrimTy, integerPrimTy, charPrimTy, stringPrimTy, wordPrimTy,
      int64PrimTy, word64PrimTy, floatPrimTy, doublePrimTy, naturalPrimTy,
      byteArrayPrimTy, eqPrimTy :: Type
    intPrimTy :: Kind
    intPrimTy     = TyConName -> Kind
    mkTyConTy TyConName
    intPrimTyConName
    integerPrimTy :: Kind
    integerPrimTy = TyConName -> Kind
    mkTyConTy TyConName
    integerPrimTyConName
    charPrimTy :: Kind
    charPrimTy    = TyConName -> Kind
    mkTyConTy TyConName
    charPrimTyConName
    stringPrimTy :: Kind
    stringPrimTy  = TyConName -> Kind
    mkTyConTy TyConName
    stringPrimTyConName
    wordPrimTy :: Kind
    wordPrimTy    = TyConName -> Kind
    mkTyConTy TyConName
    wordPrimTyConName
    int64PrimTy :: Kind
    int64PrimTy   = TyConName -> Kind
    mkTyConTy TyConName
    int64PrimTyConName
    word64PrimTy :: Kind
    word64PrimTy  = TyConName -> Kind
    mkTyConTy TyConName
    word64PrimTyConName
    floatPrimTy :: Kind
    floatPrimTy   = TyConName -> Kind
    mkTyConTy TyConName
    floatPrimTyConName
    doublePrimTy :: Kind
    doublePrimTy  = TyConName -> Kind
    mkTyConTy TyConName
    doublePrimTyConName
    naturalPrimTy :: Kind
    naturalPrimTy = TyConName -> Kind
    mkTyConTy TyConName
    naturalPrimTyConName
    byteArrayPrimTy :: Kind
    byteArrayPrimTy = TyConName -> Kind
    mkTyConTy TyConName
    byteArrayPrimTyConName
    eqPrimTy :: Kind
    eqPrimTy = TyConName -> Kind
    mkTyConTy TyConName
    eqPrimTyConName

    #if !MIN_VERSION_ghc(9,2,0)
    voidPrimTy :: Type
    voidPrimTy    = mkTyConTy voidPrimTyConName
    #endif

    #if MIN_VERSION_ghc(8,8,0)
    int8PrimTy, int16PrimTy, int32PrimTy, word8PrimTy, word16PrimTy,
      word32PrimTy :: Type
    int8PrimTy :: Kind
    int8PrimTy    = TyConName -> Kind
    mkTyConTy TyConName
    int8PrimTyConName
    int16PrimTy :: Kind
    int16PrimTy   = TyConName -> Kind
    mkTyConTy TyConName
    int16PrimTyConName
    int32PrimTy :: Kind
    int32PrimTy   = TyConName -> Kind
    mkTyConTy TyConName
    int32PrimTyConName
    word8PrimTy :: Kind
    word8PrimTy   = TyConName -> Kind
    mkTyConTy TyConName
    word8PrimTyConName
    word16PrimTy :: Kind
    word16PrimTy  = TyConName -> Kind
    mkTyConTy TyConName
    word16PrimTyConName
    word32PrimTy :: Kind
    word32PrimTy  = TyConName -> Kind
    mkTyConTy TyConName
    word32PrimTyConName
    #endif

    tysPrimMap :: TyConMap
    tysPrimMap :: TyConMap
    tysPrimMap = [(TyConName, TyCon)] -> TyConMap
    forall a b. Uniquable a => [(a, b)] -> UniqMap b
    UniqMap.fromList
      [  (TyConName
    liftedTypeKindTyConName , TyCon
    liftedTypeKindTc)
      ,  (TyConName
    typeNatKindTyConName , TyCon
    typeNatKindTc)
      ,  (TyConName
    typeSymbolKindTyConName , TyCon
    typeSymbolKindTc)
      ,  (TyConName
    intPrimTyConName , TyCon
    intPrimTc)
      ,  (TyConName
    integerPrimTyConName , TyCon
    integerPrimTc)
      ,  (TyConName
    charPrimTyConName , TyCon
    charPrimTc)
      ,  (TyConName
    stringPrimTyConName , TyCon
    stringPrimTc)
    #if !MIN_VERSION_ghc(9,2,0)
      ,  (voidPrimTyConName , voidPrimTc)
    #endif
      ,  (TyConName
    wordPrimTyConName , TyCon
    wordPrimTc)
      ,  (TyConName
    int64PrimTyConName , TyCon
    int64PrimTc)
      ,  (TyConName
    word64PrimTyConName , TyCon
    word64PrimTc)
    #if MIN_VERSION_ghc(8,8,0)
      ,  (TyConName
    int8PrimTyConName , TyCon
    int8PrimTc)
      ,  (TyConName
    int16PrimTyConName , TyCon
    int16PrimTc)
      ,  (TyConName
    int32PrimTyConName , TyCon
    int32PrimTc)
      ,  (TyConName
    word8PrimTyConName , TyCon
    word8PrimTc)
      ,  (TyConName
    word16PrimTyConName , TyCon
    word16PrimTc)
      ,  (TyConName
    word32PrimTyConName , TyCon
    word32PrimTc)
    #endif
      ,  (TyConName
    floatPrimTyConName , TyCon
    floatPrimTc)
      ,  (TyConName
    doublePrimTyConName , TyCon
    doublePrimTc)
      ,  (TyConName
    naturalPrimTyConName , TyCon
    naturalPrimTc)
      ,  (TyConName
    byteArrayPrimTyConName , TyCon
    byteArrayPrimTc)
      ,  (TyConName
    eqPrimTyConName , TyCon
    eqPrimTc)
      ]