Warn on all out-of-range literals in pats/exprs
[ghc.git] / compiler / prelude / TysPrim.hs
index 1b5adf6..77ea80e 100644 (file)
 module TysPrim(
         mkPrimTyConName, -- For implicit parameters in TysWiredIn only
 
-        mkTemplateTyVars,
+        mkTemplateKindVars, mkTemplateTyVars, mkTemplateTyVarsFrom,
+        mkTemplateKiTyVars,
+
+        mkTemplateTyConBinders, mkTemplateKindTyConBinders,
+        mkTemplateAnonTyConBinders,
+
         alphaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
         alphaTys, alphaTy, betaTy, gammaTy, deltaTy,
-        levity1TyVar, levity2TyVar, levity1Ty, levity2Ty,
+        alphaTyVarsUnliftedRep, alphaTyVarUnliftedRep,
+        alphaTysUnliftedRep, alphaTyUnliftedRep,
+        runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep1Ty, runtimeRep2Ty,
         openAlphaTy, openBetaTy, openAlphaTyVar, openBetaTyVar,
-        kKiVar,
 
         -- Kind constructors...
-        tYPETyCon, unliftedTypeKindTyCon, unliftedTypeKind,
-
-        tYPETyConName, unliftedTypeKindTyConName,
+        tYPETyCon, tYPETyConName,
 
         -- Kinds
-        tYPE,
+        tYPE, primRepToRuntimeRep,
 
         funTyCon, funTyConName,
-        primTyCons,
+        unexposedPrimTyCons, exposedPrimTyCons, primTyCons,
 
-        charPrimTyCon,          charPrimTy,
-        intPrimTyCon,           intPrimTy,
-        wordPrimTyCon,          wordPrimTy,
-        addrPrimTyCon,          addrPrimTy,
-        floatPrimTyCon,         floatPrimTy,
-        doublePrimTyCon,        doublePrimTy,
+        charPrimTyCon,          charPrimTy, charPrimTyConName,
+        intPrimTyCon,           intPrimTy, intPrimTyConName,
+        wordPrimTyCon,          wordPrimTy, wordPrimTyConName,
+        addrPrimTyCon,          addrPrimTy, addrPrimTyConName,
+        floatPrimTyCon,         floatPrimTy, floatPrimTyConName,
+        doublePrimTyCon,        doublePrimTy, doublePrimTyConName,
 
         voidPrimTyCon,          voidPrimTy,
         statePrimTyCon,         mkStatePrimTy,
@@ -57,40 +61,61 @@ module TysPrim(
         tVarPrimTyCon,                  mkTVarPrimTy,
         stablePtrPrimTyCon,             mkStablePtrPrimTy,
         stableNamePrimTyCon,            mkStableNamePrimTy,
+        compactPrimTyCon,               compactPrimTy,
         bcoPrimTyCon,                   bcoPrimTy,
         weakPrimTyCon,                  mkWeakPrimTy,
         threadIdPrimTyCon,              threadIdPrimTy,
 
-        int32PrimTyCon,         int32PrimTy,
-        word32PrimTyCon,        word32PrimTy,
+        int8PrimTyCon,          int8PrimTy, int8PrimTyConName,
+        word8PrimTyCon,         word8PrimTy, word8PrimTyConName,
+
+        int16PrimTyCon,         int16PrimTy, int16PrimTyConName,
+        word16PrimTyCon,        word16PrimTy, word16PrimTyConName,
+
+        int32PrimTyCon,         int32PrimTy, int32PrimTyConName,
+        word32PrimTyCon,        word32PrimTy, word32PrimTyConName,
 
-        int64PrimTyCon,         int64PrimTy,
-        word64PrimTyCon,        word64PrimTy,
+        int64PrimTyCon,         int64PrimTy, int64PrimTyConName,
+        word64PrimTyCon,        word64PrimTy, word64PrimTyConName,
 
         eqPrimTyCon,            -- ty1 ~# ty2
         eqReprPrimTyCon,        -- ty1 ~R# ty2  (at role Representational)
         eqPhantPrimTyCon,       -- ty1 ~P# ty2  (at role Phantom)
 
-        -- * Any
-        anyTy, anyTyCon, anyTypeOfKind,
-
         -- * SIMD
 #include "primop-vector-tys-exports.hs-incl"
   ) where
 
 #include "HsVersions.h"
 
-import {-# SOURCE #-} TysWiredIn ( levityTy, unliftedDataConTy, liftedTypeKind )
-
-import Var              ( TyVar, KindVar, mkTyVar )
+import GhcPrelude
+
+import {-# SOURCE #-} TysWiredIn
+  ( runtimeRepTy, unboxedTupleKind, liftedTypeKind
+  , vecRepDataConTyCon, tupleRepDataConTyCon
+  , liftedRepDataConTy, unliftedRepDataConTy, intRepDataConTy, int8RepDataConTy
+  , int16RepDataConTy, word16RepDataConTy
+  , wordRepDataConTy, int64RepDataConTy, word8RepDataConTy, word64RepDataConTy
+  , addrRepDataConTy
+  , floatRepDataConTy, doubleRepDataConTy
+  , vec2DataConTy, vec4DataConTy, vec8DataConTy, vec16DataConTy, vec32DataConTy
+  , vec64DataConTy
+  , int8ElemRepDataConTy, int16ElemRepDataConTy, int32ElemRepDataConTy
+  , int64ElemRepDataConTy, word8ElemRepDataConTy, word16ElemRepDataConTy
+  , word32ElemRepDataConTy, word64ElemRepDataConTy, floatElemRepDataConTy
+  , doubleElemRepDataConTy
+  , mkPromotedListTy )
+
+import Var              ( TyVar, VarBndr(Bndr), mkTyVar )
 import Name
 import TyCon
 import SrcLoc
 import Unique
 import PrelNames
 import FastString
-import TyCoRep   -- doesn't need special access, but this is easier to avoid
-                 -- import loops
+import Outputable
+import TyCoRep   -- Doesn't need special access, but this is easier to avoid
+                 -- import loops which show up if you import Type instead
 
 import Data.Char
 
@@ -103,7 +128,22 @@ import Data.Char
 -}
 
 primTyCons :: [TyCon]
-primTyCons
+primTyCons = unexposedPrimTyCons ++ exposedPrimTyCons
+
+-- | Primitive 'TyCon's that are defined in "GHC.Prim" but not exposed.
+-- It's important to keep these separate as we don't want users to be able to
+-- write them (see Trac #15209) or see them in GHCi's @:browse@ output
+-- (see Trac #12023).
+unexposedPrimTyCons :: [TyCon]
+unexposedPrimTyCons
+  = [ eqPrimTyCon
+    , eqReprPrimTyCon
+    , eqPhantPrimTyCon
+    ]
+
+-- | Primitive 'TyCon's that are defined in, and exported from, "GHC.Prim".
+exposedPrimTyCons :: [TyCon]
+exposedPrimTyCons
   = [ addrPrimTyCon
     , arrayPrimTyCon
     , byteArrayPrimTyCon
@@ -113,6 +153,8 @@ primTyCons
     , doublePrimTyCon
     , floatPrimTyCon
     , intPrimTyCon
+    , int8PrimTyCon
+    , int16PrimTyCon
     , int32PrimTyCon
     , int64PrimTyCon
     , bcoPrimTyCon
@@ -127,19 +169,17 @@ primTyCons
     , realWorldTyCon
     , stablePtrPrimTyCon
     , stableNamePrimTyCon
+    , compactPrimTyCon
     , statePrimTyCon
     , voidPrimTyCon
     , proxyPrimTyCon
     , threadIdPrimTyCon
     , wordPrimTyCon
+    , word8PrimTyCon
+    , word16PrimTyCon
     , word32PrimTyCon
     , word64PrimTyCon
-    , anyTyCon
-    , eqPrimTyCon
-    , eqReprPrimTyCon
-    , eqPhantPrimTyCon
 
-    , unliftedTypeKindTyCon
     , tYPETyCon
 
 #include "primop-vector-tycons.hs-incl"
@@ -160,12 +200,16 @@ mkBuiltInPrimTc fs unique tycon
                   BuiltInSyntax
 
 
-charPrimTyConName, intPrimTyConName, int32PrimTyConName, int64PrimTyConName, wordPrimTyConName, word32PrimTyConName, word64PrimTyConName, addrPrimTyConName, floatPrimTyConName, doublePrimTyConName, statePrimTyConName, proxyPrimTyConName, realWorldTyConName, arrayPrimTyConName, arrayArrayPrimTyConName, smallArrayPrimTyConName, byteArrayPrimTyConName, mutableArrayPrimTyConName, mutableByteArrayPrimTyConName, mutableArrayArrayPrimTyConName, smallMutableArrayPrimTyConName, mutVarPrimTyConName, mVarPrimTyConName, tVarPrimTyConName, stablePtrPrimTyConName, stableNamePrimTyConName, bcoPrimTyConName, weakPrimTyConName, threadIdPrimTyConName, eqPrimTyConName, eqReprPrimTyConName, eqPhantPrimTyConName, voidPrimTyConName :: Name
+charPrimTyConName, intPrimTyConName, int8PrimTyConName, int16PrimTyConName, int32PrimTyConName, int64PrimTyConName, wordPrimTyConName, word32PrimTyConName, word8PrimTyConName, word16PrimTyConName, word64PrimTyConName, addrPrimTyConName, floatPrimTyConName, doublePrimTyConName, statePrimTyConName, proxyPrimTyConName, realWorldTyConName, arrayPrimTyConName, arrayArrayPrimTyConName, smallArrayPrimTyConName, byteArrayPrimTyConName, mutableArrayPrimTyConName, mutableByteArrayPrimTyConName, mutableArrayArrayPrimTyConName, smallMutableArrayPrimTyConName, mutVarPrimTyConName, mVarPrimTyConName, tVarPrimTyConName, stablePtrPrimTyConName, stableNamePrimTyConName, compactPrimTyConName, bcoPrimTyConName, weakPrimTyConName, threadIdPrimTyConName, eqPrimTyConName, eqReprPrimTyConName, eqPhantPrimTyConName, voidPrimTyConName :: Name
 charPrimTyConName             = mkPrimTc (fsLit "Char#") charPrimTyConKey charPrimTyCon
 intPrimTyConName              = mkPrimTc (fsLit "Int#") intPrimTyConKey  intPrimTyCon
+int8PrimTyConName             = mkPrimTc (fsLit "Int8#") int8PrimTyConKey int8PrimTyCon
+int16PrimTyConName            = mkPrimTc (fsLit "Int16#") int16PrimTyConKey int16PrimTyCon
 int32PrimTyConName            = mkPrimTc (fsLit "Int32#") int32PrimTyConKey int32PrimTyCon
 int64PrimTyConName            = mkPrimTc (fsLit "Int64#") int64PrimTyConKey int64PrimTyCon
 wordPrimTyConName             = mkPrimTc (fsLit "Word#") wordPrimTyConKey wordPrimTyCon
+word8PrimTyConName            = mkPrimTc (fsLit "Word8#") word8PrimTyConKey word8PrimTyCon
+word16PrimTyConName           = mkPrimTc (fsLit "Word16#") word16PrimTyConKey word16PrimTyCon
 word32PrimTyConName           = mkPrimTc (fsLit "Word32#") word32PrimTyConKey word32PrimTyCon
 word64PrimTyConName           = mkPrimTc (fsLit "Word64#") word64PrimTyConKey word64PrimTyCon
 addrPrimTyConName             = mkPrimTc (fsLit "Addr#") addrPrimTyConKey addrPrimTyCon
@@ -191,6 +235,7 @@ mVarPrimTyConName             = mkPrimTc (fsLit "MVar#") mVarPrimTyConKey mVarPr
 tVarPrimTyConName             = mkPrimTc (fsLit "TVar#") tVarPrimTyConKey tVarPrimTyCon
 stablePtrPrimTyConName        = mkPrimTc (fsLit "StablePtr#") stablePtrPrimTyConKey stablePtrPrimTyCon
 stableNamePrimTyConName       = mkPrimTc (fsLit "StableName#") stableNamePrimTyConKey stableNamePrimTyCon
+compactPrimTyConName          = mkPrimTc (fsLit "Compact#") compactPrimTyConKey compactPrimTyCon
 bcoPrimTyConName              = mkPrimTc (fsLit "BCO#") bcoPrimTyConKey bcoPrimTyCon
 weakPrimTyConName             = mkPrimTc (fsLit "Weak#") weakPrimTyConKey weakPrimTyCon
 threadIdPrimTyConName         = mkPrimTc (fsLit "ThreadId#") threadIdPrimTyConKey threadIdPrimTyCon
@@ -206,16 +251,79 @@ alphaTyVars is a list of type variables for use in templates:
         ["a", "b", ..., "z", "t1", "t2", ... ]
 -}
 
+mkTemplateKindVars :: [Kind] -> [TyVar]
+-- k0  with unique (mkAlphaTyVarUnique 0)
+-- k1  with unique (mkAlphaTyVarUnique 1)
+-- ... etc
+mkTemplateKindVars [kind]
+  = [mkTyVar (mk_tv_name 0 "k") kind]
+    -- Special case for one kind: just "k"
+
+mkTemplateKindVars kinds
+  = [ mkTyVar (mk_tv_name u ('k' : show u)) kind
+    | (kind, u) <- kinds `zip` [0..] ]
+mk_tv_name :: Int -> String -> Name
+mk_tv_name u s = mkInternalName (mkAlphaTyVarUnique u)
+                                (mkTyVarOccFS (mkFastString s))
+                                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 n kinds
+  = [ mkTyVar name kind
+    | (kind, index) <- zip kinds [0..],
+      let ch_ord = index + ord 'a'
+          name_str | ch_ord <= ord 'z' = [chr ch_ord]
+                   | otherwise         = 't':show index
+          name = mk_tv_name (index + n) name_str
+    ]
+
 mkTemplateTyVars :: [Kind] -> [TyVar]
-mkTemplateTyVars kinds =
-  [ mkTyVar (mkInternalName (mkAlphaTyVarUnique u)
-                            (mkTyVarOccFS (mkFastString name))
-                            noSrcSpan) k
-  | (k,u) <- zip kinds [2..],
-    let name | c <= 'z'  = [c]
-             | otherwise = 't':show u
-          where c = chr (u-2 + ord 'a')
-  ]
+mkTemplateTyVars = mkTemplateTyVarsFrom 1
+
+mkTemplateTyConBinders
+    :: [Kind]                -- [k1, .., kn]   Kinds of kind-forall'd vars
+    -> ([Kind] -> [Kind])    -- Arg is [kv1:k1, ..., kvn:kn]
+                             --     same length as first arg
+                             -- Result is anon arg kinds
+    -> [TyConBinder]
+mkTemplateTyConBinders kind_var_kinds mk_anon_arg_kinds
+  = kv_bndrs ++ tv_bndrs
+  where
+    kv_bndrs   = mkTemplateKindTyConBinders kind_var_kinds
+    anon_kinds = mk_anon_arg_kinds (mkTyVarTys (binderVars kv_bndrs))
+    tv_bndrs   = mkTemplateAnonTyConBindersFrom (length kv_bndrs) anon_kinds
+
+mkTemplateKiTyVars
+    :: [Kind]                -- [k1, .., kn]   Kinds of kind-forall'd vars
+    -> ([Kind] -> [Kind])    -- Arg is [kv1:k1, ..., kvn:kn]
+                             --     same length as first arg
+                             -- Result is anon arg kinds [ak1, .., akm]
+    -> [TyVar]   -- [kv1:k1, ..., kvn:kn, av1:ak1, ..., avm:akm]
+-- Example: if you want the tyvars for
+--   forall (r:RuntimeRep) (a:TYPE r) (b:*). blah
+-- call mkTemplateKiTyVars [RuntimeRep] (\[r]. [TYPE r, *)
+mkTemplateKiTyVars kind_var_kinds mk_arg_kinds
+  = kv_bndrs ++ tv_bndrs
+  where
+    kv_bndrs   = mkTemplateKindVars kind_var_kinds
+    anon_kinds = mk_arg_kinds (mkTyVarTys kv_bndrs)
+    tv_bndrs   = mkTemplateTyVarsFrom (length kv_bndrs) anon_kinds
+
+mkTemplateKindTyConBinders :: [Kind] -> [TyConBinder]
+-- Makes named, Specified binders
+mkTemplateKindTyConBinders kinds = [mkNamedTyConBinder Specified tv | tv <- mkTemplateKindVars kinds]
+
+mkTemplateAnonTyConBinders :: [Kind] -> [TyConBinder]
+mkTemplateAnonTyConBinders kinds = map mkAnonTyConBinder (mkTemplateTyVars kinds)
+
+mkTemplateAnonTyConBindersFrom :: Int -> [Kind] -> [TyConBinder]
+mkTemplateAnonTyConBindersFrom n kinds = map mkAnonTyConBinder (mkTemplateTyVarsFrom n kinds)
 
 alphaTyVars :: [TyVar]
 alphaTyVars = mkTemplateTyVars $ repeat liftedTypeKind
@@ -228,26 +336,33 @@ alphaTys = mkTyVarTys alphaTyVars
 alphaTy, betaTy, gammaTy, deltaTy :: Type
 (alphaTy:betaTy:gammaTy:deltaTy:_) = alphaTys
 
-levity1TyVar, levity2TyVar :: TyVar
-(levity1TyVar : levity2TyVar : _)
-  = drop 21 (mkTemplateTyVars (repeat levityTy))  -- selects 'v','w'
+alphaTyVarsUnliftedRep :: [TyVar]
+alphaTyVarsUnliftedRep = mkTemplateTyVars $ repeat (tYPE unliftedRepDataConTy)
+
+alphaTyVarUnliftedRep :: TyVar
+(alphaTyVarUnliftedRep:_) = alphaTyVarsUnliftedRep
+
+alphaTysUnliftedRep :: [Type]
+alphaTysUnliftedRep = mkTyVarTys alphaTyVarsUnliftedRep
+alphaTyUnliftedRep :: Type
+(alphaTyUnliftedRep:_) = alphaTysUnliftedRep
 
-levity1Ty, levity2Ty :: Type
-levity1Ty = mkTyVarTy levity1TyVar
-levity2Ty = mkTyVarTy levity2TyVar
+runtimeRep1TyVar, runtimeRep2TyVar :: TyVar
+(runtimeRep1TyVar : runtimeRep2TyVar : _)
+  = drop 16 (mkTemplateTyVars (repeat runtimeRepTy))  -- selects 'q','r'
+
+runtimeRep1Ty, runtimeRep2Ty :: Type
+runtimeRep1Ty = mkTyVarTy runtimeRep1TyVar
+runtimeRep2Ty = mkTyVarTy runtimeRep2TyVar
 
 openAlphaTyVar, openBetaTyVar :: TyVar
 [openAlphaTyVar,openBetaTyVar]
-  = mkTemplateTyVars [tYPE levity1Ty, tYPE levity2Ty]
+  = mkTemplateTyVars [tYPE runtimeRep1Ty, tYPE runtimeRep2Ty]
 
 openAlphaTy, openBetaTy :: Type
 openAlphaTy = mkTyVarTy openAlphaTyVar
 openBetaTy  = mkTyVarTy openBetaTyVar
 
-kKiVar :: KindVar
-kKiVar = (mkTemplateTyVars $ repeat liftedTypeKind) !! 10
-  -- the 10 selects the 11th letter in the alphabet: 'k'
-
 {-
 ************************************************************************
 *                                                                      *
@@ -257,36 +372,24 @@ kKiVar = (mkTemplateTyVars $ repeat liftedTypeKind) !! 10
 -}
 
 funTyConName :: Name
-funTyConName = mkPrimTyConName (fsLit "(->)") funTyConKey funTyCon
-
+funTyConName = mkPrimTyConName (fsLit "->") funTyConKey funTyCon
+
+-- | The @(->)@ type constructor.
+--
+-- @
+-- (->) :: forall (rep1 :: RuntimeRep) (rep2 :: RuntimeRep).
+--         TYPE rep1 -> TYPE rep2 -> *
+-- @
 funTyCon :: TyCon
-funTyCon = mkFunTyCon funTyConName kind tc_rep_nm
+funTyCon = mkFunTyCon funTyConName tc_bndrs tc_rep_nm
   where
-    kind = mkFunTys [liftedTypeKind, liftedTypeKind] liftedTypeKind
-        -- You might think that (->) should have type (?? -> ? -> *), and you'd be right
-        -- But if we do that we get kind errors when saying
-        --      instance Control.Arrow (->)
-        -- because the expected kind is (*->*->*).  The trouble is that the
-        -- expected/actual stuff in the unifier does not go contra-variant, whereas
-        -- the kind sub-typing does.  Sigh.  It really only matters if you use (->) in
-        -- a prefix way, thus:  (->) Int# Int#.  And this is unusual.
-        -- because they are never in scope in the source
-
-    tc_rep_nm = mkSpecialTyConRepName (fsLit "tcFun") funTyConName
-
--- One step to remove subkinding.
--- (->) :: * -> * -> *
--- but we should have (and want) the following typing rule for fully applied arrows
---      Gamma |- tau   :: k1    k1 in {*, #}
---      Gamma |- sigma :: k2    k2 in {*, #, (#)}
---      -----------------------------------------
---      Gamma |- tau -> sigma :: *
--- Currently we have the following rule which achieves more or less the same effect
---      Gamma |- tau   :: ??
---      Gamma |- sigma :: ?
---      --------------------------
---      Gamma |- tau -> sigma :: *
--- In the end we don't want subkinding at all.
+    tc_bndrs = [ Bndr runtimeRep1TyVar (NamedTCB Inferred)
+               , Bndr runtimeRep2TyVar (NamedTCB Inferred)
+               ]
+               ++ mkTemplateAnonTyConBinders [ tYPE runtimeRep1Ty
+                                             , tYPE runtimeRep2Ty
+                                             ]
+    tc_rep_nm = mkPrelTyConRepName funTyConName
 
 {-
 ************************************************************************
@@ -295,49 +398,93 @@ funTyCon = mkFunTyCon funTyConName kind tc_rep_nm
 *                                                                      *
 ************************************************************************
 
-Note [TYPE]
-~~~~~~~~~~~
-There are a few places where we wish to be able to deal interchangeably
-with kind * and kind #. unsafeCoerce#, error, and (->) are some of these
-places. The way we do this is to use levity polymorphism.
-
-We have (levityTyCon, liftedDataCon, unliftedDataCon)
-
-    data Levity = Lifted | Unlifted
-
-and a magical constant (tYPETyCon)
-
-    TYPE :: Levity -> TYPE Lifted
+Note [TYPE and RuntimeRep]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+All types that classify values have a kind of the form (TYPE rr), where
+
+    data RuntimeRep     -- Defined in ghc-prim:GHC.Types
+      = LiftedRep
+      | UnliftedRep
+      | IntRep
+      | FloatRep
+      .. etc ..
+
+    rr :: RuntimeRep
+
+    TYPE :: RuntimeRep -> TYPE 'LiftedRep  -- Built in
+
+So for example:
+    Int        :: TYPE 'LiftedRep
+    Array# Int :: TYPE 'UnliftedRep
+    Int#       :: TYPE 'IntRep
+    Float#     :: TYPE 'FloatRep
+    Maybe      :: TYPE 'LiftedRep -> TYPE 'LiftedRep
+    (# , #)    :: TYPE r1 -> TYPE r2 -> TYPE (TupleRep [r1, r2])
+
+We abbreviate '*' specially:
+    type * = TYPE 'LiftedRep
+
+The 'rr' parameter tells us how the value is represented at runime.
+
+Generally speaking, you can't be polymorphic in 'rr'.  E.g
+   f :: forall (rr:RuntimeRep) (a:TYPE rr). a -> [a]
+   f = /\(rr:RuntimeRep) (a:rr) \(a:rr). ...
+This is no good: we could not generate code 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 MkId.unsafeCoerceId:
+  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 TysWiredIn
+  Always inlined, and hence specialised to the call site
+     (#,#) :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
+                     (a :: TYPE r1) (b :: TYPE r2).
+                     a -> b -> TYPE ('TupleRep '[r1, r2])
+
+Note [PrimRep and kindPrimRep]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As part of its source code, in TyCon, GHC has
+  data PrimRep = LiftedRep | UnliftedRep | IntRep | FloatRep | ...etc...
+
+Notice that
+ * RuntimeRep is part of the syntax tree of the program being compiled
+     (defined in a library: ghc-prim:GHC.Types)
+ * PrimRep is part of GHC's source code.
+     (defined in TyCon)
+
+We need to get from one to the other; that is what kindPrimRep does.
+Suppose we have a value
+   (v :: t) where (t :: k)
+Given this kind
+    k = TyConApp "TYPE" [rep]
+GHC needs to be able to figure out how 'v' is represented at runtime.
+It expects 'rep' to be form
+    TyConApp rr_dc args
+where 'rr_dc' is a promoteed data constructor from RuntimeRep. So
+now we need to go from 'dc' to the corresponding PrimRep.  We store this
+PrimRep in the promoted data constructor itself: see TyCon.promDcRepInfo.
 
-We then have synonyms (liftedTypeKindTyCon, unliftedTypeKindTyCon)
-
-    type Type = TYPE Lifted
-    type # = TYPE Unlifted
-
-So, for example, we get
-
-    unsafeCoerce# :: forall (v1 :: Levity) (v2 :: Levity)
-                            (a :: TYPE v1) (b :: TYPE v2). a -> b
-
-This replaces the old sub-kinding machinery. We call variables `a` and `b`
-above "levity polymorphic".
 -}
 
-tYPETyCon, unliftedTypeKindTyCon :: TyCon
-tYPETyConName, unliftedTypeKindTyConName :: Name
+tYPETyCon :: TyCon
+tYPETyConName :: Name
 
 tYPETyCon = mkKindTyCon tYPETyConName
-                        (ForAllTy (Anon levityTy) liftedTypeKind)
+                        (mkTemplateAnonTyConBinders [runtimeRepTy])
+                        liftedTypeKind
                         [Nominal]
-                        (mkSpecialTyConRepName (fsLit "tcTYPE") tYPETyConName)
-
-   -- See Note [TYPE]
-   -- NB: unlifted is wired in because there is no way to parse it in
-   -- Haskell. That's the only reason for wiring it in.
-unliftedTypeKindTyCon = mkSynonymTyCon unliftedTypeKindTyConName
-                                       liftedTypeKind
-                                       [] []
-                                       (tYPE unliftedDataConTy)
+                        (mkPrelTyConRepName tYPETyConName)
 
 --------------------------
 -- ... and now their names
@@ -345,10 +492,6 @@ unliftedTypeKindTyCon = mkSynonymTyCon unliftedTypeKindTyConName
 -- If you edit these, you may need to update the GHC formalism
 -- See Note [GHC Formalism] in coreSyn/CoreLint.hs
 tYPETyConName             = mkPrimTyConName (fsLit "TYPE") tYPETyConKey tYPETyCon
-unliftedTypeKindTyConName = mkPrimTyConName (fsLit "#") unliftedTypeKindTyConKey unliftedTypeKindTyCon
-
-unliftedTypeKind :: Kind
-unliftedTypeKind = tYPE unliftedDataConTy
 
 mkPrimTyConName :: FastString -> Unique -> TyCon -> Name
 mkPrimTyConName = mkPrimTcName BuiltInSyntax
@@ -360,9 +503,10 @@ mkPrimTcName built_in_syntax occ key tycon
   = mkWiredInName gHC_PRIM (mkTcOccFS occ) key (ATyCon tycon) built_in_syntax
 
 -----------------------------
--- | Given a Levity, applies TYPE to it. See Note [TYPE].
+-- | Given a RuntimeRep, applies TYPE to it.
+-- see Note [TYPE and RuntimeRep]
 tYPE :: Type -> Type
-tYPE lev = TyConApp tYPETyCon [lev]
+tYPE rr = TyConApp tYPETyCon [rr]
 
 {-
 ************************************************************************
@@ -375,16 +519,55 @@ tYPE lev = TyConApp tYPETyCon [lev]
 -- only used herein
 pcPrimTyCon :: Name -> [Role] -> PrimRep -> TyCon
 pcPrimTyCon name roles rep
-  = mkPrimTyCon name kind roles rep
+  = mkPrimTyCon name binders result_kind roles
   where
-    kind        = mkFunTys (map (const liftedTypeKind) roles) result_kind
-    result_kind = unliftedTypeKind
+    binders     = mkTemplateAnonTyConBinders (map (const liftedTypeKind) roles)
+    result_kind = tYPE (primRepToRuntimeRep rep)
+
+-- | Convert a 'PrimRep' to a 'Type' of kind RuntimeRep
+-- Defined here to avoid (more) module loops
+primRepToRuntimeRep :: PrimRep -> Type
+primRepToRuntimeRep rep = case rep of
+  VoidRep       -> TyConApp tupleRepDataConTyCon [mkPromotedListTy runtimeRepTy []]
+  LiftedRep     -> liftedRepDataConTy
+  UnliftedRep   -> unliftedRepDataConTy
+  IntRep        -> intRepDataConTy
+  Int8Rep       -> int8RepDataConTy
+  Int16Rep      -> int16RepDataConTy
+  WordRep       -> wordRepDataConTy
+  Int64Rep      -> int64RepDataConTy
+  Word8Rep      -> word8RepDataConTy
+  Word16Rep     -> word16RepDataConTy
+  Word64Rep     -> word64RepDataConTy
+  AddrRep       -> addrRepDataConTy
+  FloatRep      -> floatRepDataConTy
+  DoubleRep     -> doubleRepDataConTy
+  VecRep n elem -> TyConApp vecRepDataConTyCon [n', elem']
+    where
+      n' = case n of
+        2  -> vec2DataConTy
+        4  -> vec4DataConTy
+        8  -> vec8DataConTy
+        16 -> vec16DataConTy
+        32 -> vec32DataConTy
+        64 -> vec64DataConTy
+        _  -> pprPanic "Disallowed VecCount" (ppr n)
+
+      elem' = case elem of
+        Int8ElemRep   -> int8ElemRepDataConTy
+        Int16ElemRep  -> int16ElemRepDataConTy
+        Int32ElemRep  -> int32ElemRepDataConTy
+        Int64ElemRep  -> int64ElemRepDataConTy
+        Word8ElemRep  -> word8ElemRepDataConTy
+        Word16ElemRep -> word16ElemRepDataConTy
+        Word32ElemRep -> word32ElemRepDataConTy
+        Word64ElemRep -> word64ElemRepDataConTy
+        FloatElemRep  -> floatElemRepDataConTy
+        DoubleElemRep -> doubleElemRepDataConTy
 
 pcPrimTyCon0 :: Name -> PrimRep -> TyCon
 pcPrimTyCon0 name rep
-  = mkPrimTyCon name result_kind [] rep
-  where
-    result_kind = unliftedTypeKind
+  = pcPrimTyCon name [] rep
 
 charPrimTy :: Type
 charPrimTy      = mkTyConTy charPrimTyCon
@@ -396,6 +579,16 @@ intPrimTy       = mkTyConTy intPrimTyCon
 intPrimTyCon :: TyCon
 intPrimTyCon    = pcPrimTyCon0 intPrimTyConName IntRep
 
+int8PrimTy :: Type
+int8PrimTy     = mkTyConTy int8PrimTyCon
+int8PrimTyCon :: TyCon
+int8PrimTyCon  = pcPrimTyCon0 int8PrimTyConName Int8Rep
+
+int16PrimTy :: Type
+int16PrimTy    = mkTyConTy int16PrimTyCon
+int16PrimTyCon :: TyCon
+int16PrimTyCon = pcPrimTyCon0 int16PrimTyConName Int16Rep
+
 int32PrimTy :: Type
 int32PrimTy     = mkTyConTy int32PrimTyCon
 int32PrimTyCon :: TyCon
@@ -411,6 +604,16 @@ wordPrimTy      = mkTyConTy wordPrimTyCon
 wordPrimTyCon :: TyCon
 wordPrimTyCon   = pcPrimTyCon0 wordPrimTyConName WordRep
 
+word8PrimTy :: Type
+word8PrimTy     = mkTyConTy word8PrimTyCon
+word8PrimTyCon :: TyCon
+word8PrimTyCon  = pcPrimTyCon0 word8PrimTyConName Word8Rep
+
+word16PrimTy :: Type
+word16PrimTy    = mkTyConTy word16PrimTyCon
+word16PrimTyCon :: TyCon
+word16PrimTyCon = pcPrimTyCon0 word16PrimTyConName Word16Rep
+
 word32PrimTy :: Type
 word32PrimTy    = mkTyConTy word32PrimTyCon
 word32PrimTyCon :: TyCon
@@ -443,16 +646,165 @@ doublePrimTyCon = pcPrimTyCon0 doublePrimTyConName DoubleRep
 *                                                                      *
 ************************************************************************
 
-Note [The ~# TyCon]
-~~~~~~~~~~~~~~~~~~~~
-There is a perfectly ordinary type constructor ~# that represents the type
-of coercions (which, remember, are values).  For example
-   Refl Int :: ~# * * Int Int
+Note [The equality types story]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GHC sports a veritable menagerie of equality types:
+
+         Type or  Lifted?  Hetero?  Role      Built in         Defining module
+         class?    L/U                        TyCon
+-----------------------------------------------------------------------------------------
+~#         T        U      hetero   nominal   eqPrimTyCon      GHC.Prim
+~~         C        L      hetero   nominal   heqTyCon         GHC.Types
+~          C        L      homo     nominal   eqTyCon          GHC.Types
+:~:        T        L      homo     nominal   (not built-in)   Data.Type.Equality
+:~~:       T        L      hetero   nominal   (not built-in)   Data.Type.Equality
+
+~R#        T        U      hetero   repr      eqReprPrimTy     GHC.Prim
+Coercible  C        L      homo     repr      coercibleTyCon   GHC.Types
+Coercion   T        L      homo     repr      (not built-in)   Data.Type.Coercion
+~P#        T        U      hetero   phantom   eqPhantPrimTyCon GHC.Prim
+
+Recall that "hetero" means the equality can related types of different
+kinds. Knowing that (t1 ~# t2) or (t1 ~R# t2) or even that (t1 ~P# t2)
+also means that (k1 ~# k2), where (t1 :: k1) and (t2 :: k2).
+
+To produce less confusion for end users, when not dumping and without
+-fprint-equality-relations, each of these groups is printed as the bottommost
+listed equality. That is, (~#) and (~~) are both rendered as (~) in
+error messages, and (~R#) is rendered as Coercible.
+
+Let's take these one at a time:
+
+    --------------------------
+    (~#) :: forall k1 k2. k1 -> k2 -> #
+    --------------------------
+This is The Type Of Equality in GHC. It classifies nominal coercions.
+This type is used in the solver for recording equality constraints.
+It responds "yes" to Type.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 TyCoRep.) But see also
+Note [Deferred errors for coercion holes] in TcErrors to see how
+equality constraints are deferred.
+
+Within GHC, ~# is called eqPrimTyCon, and it is defined in TysPrim.
+
+
+    --------------------------
+    (~~) :: forall k1 k2. k1 -> k2 -> Constraint
+    --------------------------
+This is (almost) an ordinary class, defined as if by
+  class a ~# b => a ~~ b
+  instance a ~# b => a ~~ b
+Here's what's unusual about it:
+
+ * We can't actually declare it that way because we don't have syntax for ~#.
+   And ~# isn't a constraint, so even if we could write it, it wouldn't kind
+   check.
+
+ * Users cannot write instances of it.
+
+ * It is "naturally coherent". This means that the solver won't hesitate to
+   solve a goal of type (a ~~ b) even if there is, say (Int ~~ c) in the
+   context. (Normally, it waits to learn more, just in case the given
+   influences what happens next.) See Note [Naturally coherent classes]
+   in TcInteract.
+
+ * 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 TcInteract.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 TysWiredIn.
+
+
+    --------------------------
+    (~) :: forall k. k -> k -> Constraint
+    --------------------------
+This is /exactly/ like (~~), except with a homogeneous kind.
+It is an almost-ordinary class defined as if by
+  class a ~# b => (a :: k) ~ (b :: k)
+  instance a ~# b => a ~ b
+
+ * All the bullets for (~~) apply
+
+ * In addition (~) is magical syntax, as ~ is a reserved symbol.
+   It cannot be exported or imported.
+
+Within GHC, ~ is called eqTyCon, and it is defined in TysWiredIn.
+
+Historical note: prior to July 18 (~) was defined as a
+  more-ordinary class with (~~) as a superclass.  But that made it
+  special in different ways; and the extra superclass selections to
+  get from (~) to (~#) via (~~) were tiresome.  Now it's defined
+  uniformly with (~~) and Coercible; much nicer.)
+
+
+    --------------------------
+    (:~:) :: forall k. k -> k -> *
+    (:~~:) :: forall k1 k2. k1 -> k2 -> *
+    --------------------------
+These are perfectly ordinary GADTs, wrapping (~) and (~~) resp.
+They are not defined within GHC at all.
+
+
+    --------------------------
+    (~R#) :: forall k1 k2. k1 -> k2 -> #
+    --------------------------
+The is the representational analogue of ~#. This is the type of representational
+equalities that the solver works on. All wanted constraints of this type are
+built with coercion holes.
+
+Within GHC, ~R# is called eqReprPrimTyCon, and it is defined in TysPrim.
+
+
+    --------------------------
+    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
+TysWiredIn.
+
+
+    --------------------------
+    Coercion :: forall k. k -> k -> *
+    --------------------------
+This is a perfectly ordinary GADT, wrapping Coercible. It is not defined
+within GHC at all.
+
+
+    --------------------------
+    (~P#) :: forall k1 k2. k1 -> k2 -> #
+    --------------------------
+This is the phantom analogue of ~# and it is barely used at all.
+(The solver has no idea about this one.) Here is the motivation:
+
+    data Phant a = MkPhant
+    type role Phant phantom
+
+    Phant <Int, Bool>_P :: Phant Int ~P# Phant Bool
+
+We just need to have something to put on that last line. You probably
+don't need to worry about it.
 
-It is a kind-polymorphic type constructor like Any:
-   Refl Maybe :: ~# (* -> *) (* -> *) Maybe Maybe
 
-(~) only appears saturated. So we check that in CoreLint.
 
 Note [The State# TyCon]
 ~~~~~~~~~~~~~~~~~~~~~~~
@@ -476,6 +828,23 @@ mkStatePrimTy ty = TyConApp statePrimTyCon [ty]
 statePrimTyCon :: TyCon   -- See Note [The State# TyCon]
 statePrimTyCon   = pcPrimTyCon statePrimTyConName [Nominal] VoidRep
 
+{-
+RealWorld is deeply magical.  It is *primitive*, but it is not
+*unlifted* (hence ptrArg).  We never manipulate values of type
+RealWorld; it's only used in the type system, to parameterise State#.
+-}
+
+realWorldTyCon :: TyCon
+realWorldTyCon = mkLiftedPrimTyCon realWorldTyConName [] liftedTypeKind []
+realWorldTy :: Type
+realWorldTy          = mkTyConTy realWorldTyCon
+realWorldStatePrimTy :: Type
+realWorldStatePrimTy = mkStatePrimTy realWorldTy        -- State# RealWorld
+
+-- Note: the ``state-pairing'' types are not truly primitive,
+-- so they are defined in \tr{TysWiredIn.hs}, not here.
+
+
 voidPrimTy :: Type
 voidPrimTy = TyConApp voidPrimTyCon []
 
@@ -486,86 +855,68 @@ mkProxyPrimTy :: Type -> Type -> Type
 mkProxyPrimTy k ty = TyConApp proxyPrimTyCon [k, ty]
 
 proxyPrimTyCon :: TyCon
-proxyPrimTyCon = mkPrimTyCon proxyPrimTyConName kind [Nominal,Nominal] VoidRep
-  where kind = ForAllTy (Named kv Invisible) $
-               mkFunTy k unliftedTypeKind
-        kv   = kKiVar
-        k    = mkTyVarTy kv
+proxyPrimTyCon = mkPrimTyCon proxyPrimTyConName binders res_kind [Nominal,Nominal]
+  where
+     -- Kind: forall k. k -> Void#
+     binders = mkTemplateTyConBinders [liftedTypeKind] (\ks-> ks)
+     res_kind = unboxedTupleKind []
+
+
+{- *********************************************************************
+*                                                                      *
+                Primitive equality constraints
+    See Note [The equality types story]
+*                                                                      *
+********************************************************************* -}
 
 eqPrimTyCon :: TyCon  -- The representation type for equality predicates
-                      -- See Note [The ~# TyCon]
-eqPrimTyCon  = mkPrimTyCon eqPrimTyConName kind roles VoidRep
-  where kind = ForAllTy (Named kv1 Invisible) $
-               ForAllTy (Named kv2 Invisible) $
-               mkFunTys [k1, k2] unliftedTypeKind
-        [kv1, kv2] = mkTemplateTyVars [liftedTypeKind, liftedTypeKind]
-        k1 = mkTyVarTy kv1
-        k2 = mkTyVarTy kv2
-        roles = [Nominal, Nominal, Nominal, Nominal]
+                      -- See Note [The equality types story]
+eqPrimTyCon  = mkPrimTyCon eqPrimTyConName binders res_kind roles
+  where
+    -- Kind :: forall k1 k2. k1 -> k2 -> Void#
+    binders  = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] (\ks -> ks)
+    res_kind = unboxedTupleKind []
+    roles    = [Nominal, Nominal, Nominal, 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
-eqReprPrimTyCon = mkPrimTyCon eqReprPrimTyConName kind
-                              roles VoidRep
-  where kind = ForAllTy (Named kv1 Invisible) $
-               ForAllTy (Named kv2 Invisible) $
-               mkFunTys [k1, k2] unliftedTypeKind
-        [kv1, kv2]    = mkTemplateTyVars [liftedTypeKind, liftedTypeKind]
-        k1            = mkTyVarTy kv1
-        k2            = mkTyVarTy kv2
-        roles         = [Nominal, Nominal, Representational, Representational]
+eqReprPrimTyCon :: TyCon   -- See Note [The equality types story]
+eqReprPrimTyCon = mkPrimTyCon eqReprPrimTyConName binders res_kind roles
+  where
+    -- Kind :: forall k1 k2. k1 -> k2 -> Void#
+    binders  = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] (\ks -> ks)
+    res_kind = unboxedTupleKind []
+    roles    = [Nominal, Nominal, Representational, 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 = mkPrimTyCon eqPhantPrimTyConName kind
-                               [Nominal, Nominal, Phantom, Phantom]
-                               VoidRep
-  where kind = ForAllTy (Named kv1 Invisible) $
-               ForAllTy (Named kv2 Invisible) $
-               mkFunTys [k1, k2] unliftedTypeKind
-        [kv1, kv2]    = mkTemplateTyVars [liftedTypeKind, liftedTypeKind]
-        k1            = mkTyVarTy kv1
-        k2            = mkTyVarTy kv2
-
-{-
-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 = mkLiftedPrimTyCon realWorldTyConName liftedTypeKind [] PtrRep
-realWorldTy :: Type
-realWorldTy          = mkTyConTy realWorldTyCon
-realWorldStatePrimTy :: Type
-realWorldStatePrimTy = mkStatePrimTy realWorldTy        -- State# RealWorld
-
-{-
-Note: the ``state-pairing'' types are not truly primitive, so they are
-defined in \tr{TysWiredIn.hs}, not here.
+eqPhantPrimTyCon = mkPrimTyCon eqPhantPrimTyConName binders res_kind roles
+  where
+    -- Kind :: forall k1 k2. k1 -> k2 -> Void#
+    binders  = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] (\ks -> ks)
+    res_kind = unboxedTupleKind []
+    roles    = [Nominal, Nominal, Phantom, Phantom]
 
-************************************************************************
+{- *********************************************************************
 *                                                                      *
-\subsection[TysPrim-arrays]{The primitive array types}
+             The primitive array types
 *                                                                      *
-************************************************************************
--}
+********************************************************************* -}
 
 arrayPrimTyCon, mutableArrayPrimTyCon, mutableByteArrayPrimTyCon,
     byteArrayPrimTyCon, arrayArrayPrimTyCon, mutableArrayArrayPrimTyCon,
     smallArrayPrimTyCon, smallMutableArrayPrimTyCon :: TyCon
-arrayPrimTyCon             = pcPrimTyCon arrayPrimTyConName             [Representational] PtrRep
-mutableArrayPrimTyCon      = pcPrimTyCon  mutableArrayPrimTyConName     [Nominal, Representational] PtrRep
-mutableByteArrayPrimTyCon  = pcPrimTyCon mutableByteArrayPrimTyConName  [Nominal] PtrRep
-byteArrayPrimTyCon         = pcPrimTyCon0 byteArrayPrimTyConName        PtrRep
-arrayArrayPrimTyCon        = pcPrimTyCon0 arrayArrayPrimTyConName       PtrRep
-mutableArrayArrayPrimTyCon = pcPrimTyCon mutableArrayArrayPrimTyConName [Nominal] PtrRep
-smallArrayPrimTyCon        = pcPrimTyCon smallArrayPrimTyConName        [Representational] PtrRep
-smallMutableArrayPrimTyCon = pcPrimTyCon smallMutableArrayPrimTyConName [Nominal, Representational] PtrRep
+arrayPrimTyCon             = pcPrimTyCon arrayPrimTyConName             [Representational] UnliftedRep
+mutableArrayPrimTyCon      = pcPrimTyCon  mutableArrayPrimTyConName     [Nominal, Representational] UnliftedRep
+mutableByteArrayPrimTyCon  = pcPrimTyCon mutableByteArrayPrimTyConName  [Nominal] UnliftedRep
+byteArrayPrimTyCon         = pcPrimTyCon0 byteArrayPrimTyConName        UnliftedRep
+arrayArrayPrimTyCon        = pcPrimTyCon0 arrayArrayPrimTyConName       UnliftedRep
+mutableArrayArrayPrimTyCon = pcPrimTyCon mutableArrayArrayPrimTyConName [Nominal] UnliftedRep
+smallArrayPrimTyCon        = pcPrimTyCon smallArrayPrimTyConName        [Representational] UnliftedRep
+smallMutableArrayPrimTyCon = pcPrimTyCon smallMutableArrayPrimTyConName [Nominal, Representational] UnliftedRep
 
 mkArrayPrimTy :: Type -> Type
 mkArrayPrimTy elt           = TyConApp arrayPrimTyCon [elt]
@@ -584,16 +935,15 @@ mkMutableArrayArrayPrimTy s = TyConApp mutableArrayArrayPrimTyCon [s]
 mkSmallMutableArrayPrimTy :: Type -> Type -> Type
 mkSmallMutableArrayPrimTy s elt = TyConApp smallMutableArrayPrimTyCon [s, elt]
 
-{-
-************************************************************************
+
+{- *********************************************************************
 *                                                                      *
-\subsection[TysPrim-mut-var]{The mutable variable type}
+                The mutable variable type
 *                                                                      *
-************************************************************************
--}
+********************************************************************* -}
 
 mutVarPrimTyCon :: TyCon
-mutVarPrimTyCon = pcPrimTyCon mutVarPrimTyConName [Nominal, Representational] PtrRep
+mutVarPrimTyCon = pcPrimTyCon mutVarPrimTyConName [Nominal, Representational] UnliftedRep
 
 mkMutVarPrimTy :: Type -> Type -> Type
 mkMutVarPrimTy s elt        = TyConApp mutVarPrimTyCon [s, elt]
@@ -607,7 +957,7 @@ mkMutVarPrimTy s elt        = TyConApp mutVarPrimTyCon [s, elt]
 -}
 
 mVarPrimTyCon :: TyCon
-mVarPrimTyCon = pcPrimTyCon mVarPrimTyConName [Nominal, Representational] PtrRep
+mVarPrimTyCon = pcPrimTyCon mVarPrimTyConName [Nominal, Representational] UnliftedRep
 
 mkMVarPrimTy :: Type -> Type -> Type
 mkMVarPrimTy s elt          = TyConApp mVarPrimTyCon [s, elt]
@@ -621,7 +971,7 @@ mkMVarPrimTy s elt          = TyConApp mVarPrimTyCon [s, elt]
 -}
 
 tVarPrimTyCon :: TyCon
-tVarPrimTyCon = pcPrimTyCon tVarPrimTyConName [Nominal, Representational] PtrRep
+tVarPrimTyCon = pcPrimTyCon tVarPrimTyConName [Nominal, Representational] UnliftedRep
 
 mkTVarPrimTy :: Type -> Type -> Type
 mkTVarPrimTy s elt = TyConApp tVarPrimTyCon [s, elt]
@@ -649,7 +999,7 @@ mkStablePtrPrimTy ty = TyConApp stablePtrPrimTyCon [ty]
 -}
 
 stableNamePrimTyCon :: TyCon
-stableNamePrimTyCon = pcPrimTyCon stableNamePrimTyConName [Representational] PtrRep
+stableNamePrimTyCon = pcPrimTyCon stableNamePrimTyConName [Phantom] UnliftedRep
 
 mkStableNamePrimTy :: Type -> Type
 mkStableNamePrimTy ty = TyConApp stableNamePrimTyCon [ty]
@@ -657,6 +1007,20 @@ mkStableNamePrimTy ty = TyConApp stableNamePrimTyCon [ty]
 {-
 ************************************************************************
 *                                                                      *
+\subsection[TysPrim-compact-nfdata]{The Compact NFData (CNF) type}
+*                                                                      *
+************************************************************************
+-}
+
+compactPrimTyCon :: TyCon
+compactPrimTyCon = pcPrimTyCon0 compactPrimTyConName UnliftedRep
+
+compactPrimTy :: Type
+compactPrimTy = mkTyConTy compactPrimTyCon
+
+{-
+************************************************************************
+*                                                                      *
 \subsection[TysPrim-BCOs]{The ``bytecode object'' type}
 *                                                                      *
 ************************************************************************
@@ -665,7 +1029,7 @@ mkStableNamePrimTy ty = TyConApp stableNamePrimTyCon [ty]
 bcoPrimTy    :: Type
 bcoPrimTy    = mkTyConTy bcoPrimTyCon
 bcoPrimTyCon :: TyCon
-bcoPrimTyCon = pcPrimTyCon0 bcoPrimTyConName PtrRep
+bcoPrimTyCon = pcPrimTyCon0 bcoPrimTyConName UnliftedRep
 
 {-
 ************************************************************************
@@ -676,7 +1040,7 @@ bcoPrimTyCon = pcPrimTyCon0 bcoPrimTyConName PtrRep
 -}
 
 weakPrimTyCon :: TyCon
-weakPrimTyCon = pcPrimTyCon weakPrimTyConName [Representational] PtrRep
+weakPrimTyCon = pcPrimTyCon weakPrimTyConName [Representational] UnliftedRep
 
 mkWeakPrimTy :: Type -> Type
 mkWeakPrimTy v = TyConApp weakPrimTyCon [v]
@@ -701,83 +1065,7 @@ to the thread id internally.
 threadIdPrimTy :: Type
 threadIdPrimTy    = mkTyConTy threadIdPrimTyCon
 threadIdPrimTyCon :: TyCon
-threadIdPrimTyCon = pcPrimTyCon0 threadIdPrimTyConName PtrRep
-
-{-
-************************************************************************
-*                                                                      *
-                Any
-*                                                                      *
-************************************************************************
-
-Note [Any types]
-~~~~~~~~~~~~~~~~
-The type constructor Any of kind forall k. k has these properties:
-
-  * It is defined in module GHC.Prim, and exported so that it is
-    available to users.  For this reason it's treated like any other
-    primitive type:
-      - has a fixed unique, anyTyConKey,
-      - lives in the global name cache
-
-  * It is a *closed* type family, with no instances.  This means that
-    if   ty :: '(k1, k2)  we add a given coercion
-             g :: ty ~ (Fst ty, Snd ty)
-    If Any was a *data* type, then we'd get inconsistency because 'ty'
-    could be (Any '(k1,k2)) and then we'd have an equality with Any on
-    one side and '(,) on the other. See also #9097.
-
-  * It is lifted, and hence represented by a pointer
-
-  * It is inhabited by at least one value, namely bottom
-
-  * You can unsafely coerce any lifted type to Any, and back.
-
-  * It does not claim to be a *data* type, and that's important for
-    the code generator, because the code gen may *enter* a data value
-    but never enters a function value.
-
-  * It is used to instantiate otherwise un-constrained type variables
-    For example         length Any []
-    See Note [Strangely-kinded void TyCons]
-
-Note [Strangely-kinded void TyCons]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-See Trac #959 for more examples
-
-When the type checker finds a type variable with no binding, which
-means it can be instantiated with an arbitrary type, it usually
-instantiates it to Void.  Eg.
-
-        length []
-===>
-        length Any (Nil Any)
-
-But in really obscure programs, the type variable might have a kind
-other than *, so we need to invent a suitably-kinded type.
-
-This commit uses
-        Any for kind *
-        Any(*->*) for kind *->*
-        etc
--}
-
-anyTyConName :: Name
-anyTyConName = mkPrimTc (fsLit "Any") anyTyConKey anyTyCon
-
-anyTy :: Type
-anyTy = mkTyConTy anyTyCon
-
-anyTyCon :: TyCon
-anyTyCon = mkFamilyTyCon anyTyConName kind [kKiVar] Nothing
-                         (ClosedSynFamilyTyCon Nothing)
-                         Nothing
-                         NotInjective
-  where
-    kind = ForAllTy (Named kKiVar Invisible) (mkTyVarTy kKiVar)
-
-anyTypeOfKind :: Kind -> Type
-anyTypeOfKind kind = TyConApp anyTyCon [kind]
+threadIdPrimTyCon = pcPrimTyCon0 threadIdPrimTyConName UnliftedRep
 
 {-
 ************************************************************************