never executed always true always false
    1 
    2 {-# LANGUAGE FlexibleContexts #-}
    3 
    4 module GHC.Types.RepType
    5   (
    6     -- * Code generator views onto Types
    7     UnaryType, NvUnaryType, isNvUnaryType,
    8     unwrapType,
    9 
   10     -- * Predicates on types
   11     isVoidTy,
   12 
   13     -- * Type representation for the code generator
   14     typePrimRep, typePrimRep1, typeMonoPrimRep_maybe,
   15     runtimeRepPrimRep, typePrimRepArgs,
   16     PrimRep(..), primRepToType,
   17     countFunRepArgs, countConRepArgs, tyConPrimRep, tyConPrimRep1,
   18 
   19     -- * Unboxed sum representation type
   20     ubxSumRepType, layoutUbxSum, typeSlotTy, SlotTy (..),
   21     slotPrimRep, primRepSlot
   22   ) where
   23 
   24 import GHC.Prelude
   25 
   26 import GHC.Types.Basic (Arity, RepArity)
   27 import GHC.Core.DataCon
   28 import GHC.Builtin.Names
   29 import GHC.Core.Coercion
   30 import GHC.Core.TyCon
   31 import GHC.Core.TyCon.RecWalk
   32 import GHC.Core.TyCo.Rep
   33 import GHC.Core.Type
   34 import GHC.Builtin.Types.Prim
   35 import {-# SOURCE #-} GHC.Builtin.Types ( anyTypeOfKind, runtimeRepTy )
   36 
   37 import GHC.Utils.Misc
   38 import GHC.Utils.Outputable
   39 import GHC.Utils.Panic
   40 import GHC.Utils.Panic.Plain
   41 
   42 import Data.List (sort)
   43 import qualified Data.IntSet as IS
   44 
   45 {- **********************************************************************
   46 *                                                                       *
   47                 Representation types
   48 *                                                                       *
   49 ********************************************************************** -}
   50 
   51 type NvUnaryType = Type
   52 type UnaryType   = Type
   53      -- Both are always a value type; i.e. its kind is TYPE rr
   54      -- for some rr; moreover the rr is never a variable.
   55      --
   56      --   NvUnaryType : never an unboxed tuple or sum, or void
   57      --
   58      --   UnaryType   : never an unboxed tuple or sum;
   59      --                 can be Void# or (# #)
   60 
   61 isNvUnaryType :: Type -> Bool
   62 isNvUnaryType ty
   63   | [_] <- typePrimRep ty
   64   = True
   65   | otherwise
   66   = False
   67 
   68 -- INVARIANT: the result list is never empty.
   69 typePrimRepArgs :: HasDebugCallStack => Type -> [PrimRep]
   70 typePrimRepArgs ty
   71   | [] <- reps
   72   = [VoidRep]
   73   | otherwise
   74   = reps
   75   where
   76     reps = typePrimRep ty
   77 
   78 -- | Gets rid of the stuff that prevents us from understanding the
   79 -- runtime representation of a type. Including:
   80 --   1. Casts
   81 --   2. Newtypes
   82 --   3. Foralls
   83 --   4. Synonyms
   84 -- But not type/data families, because we don't have the envs to hand.
   85 unwrapType :: Type -> Type
   86 unwrapType ty
   87   | Just (_, unwrapped)
   88       <- topNormaliseTypeX stepper mappend inner_ty
   89   = unwrapped
   90   | otherwise
   91   = inner_ty
   92   where
   93     inner_ty = go ty
   94 
   95     go t | Just t' <- coreView t = go t'
   96     go (ForAllTy _ t)            = go t
   97     go (CastTy t _)              = go t
   98     go t                         = t
   99 
  100      -- cf. Coercion.unwrapNewTypeStepper
  101     stepper rec_nts tc tys
  102       | Just (ty', _) <- instNewTyCon_maybe tc tys
  103       = case checkRecTc rec_nts tc of
  104           Just rec_nts' -> NS_Step rec_nts' (go ty') ()
  105           Nothing       -> NS_Abort   -- infinite newtypes
  106       | otherwise
  107       = NS_Done
  108 
  109 countFunRepArgs :: Arity -> Type -> RepArity
  110 countFunRepArgs 0 _
  111   = 0
  112 countFunRepArgs n ty
  113   | FunTy _ _ arg res <- unwrapType ty
  114   = length (typePrimRepArgs arg) + countFunRepArgs (n - 1) res
  115   | otherwise
  116   = pprPanic "countFunRepArgs: arity greater than type can handle" (ppr (n, ty, typePrimRep ty))
  117 
  118 countConRepArgs :: DataCon -> RepArity
  119 countConRepArgs dc = go (dataConRepArity dc) (dataConRepType dc)
  120   where
  121     go :: Arity -> Type -> RepArity
  122     go 0 _
  123       = 0
  124     go n ty
  125       | FunTy _ _ arg res <- unwrapType ty
  126       = length (typePrimRep arg) + go (n - 1) res
  127       | otherwise
  128       = pprPanic "countConRepArgs: arity greater than type can handle" (ppr (n, ty, typePrimRep ty))
  129 
  130 -- | True if the type has zero width.
  131 isVoidTy :: Type -> Bool
  132 isVoidTy = null . typePrimRep
  133 
  134 
  135 {- **********************************************************************
  136 *                                                                       *
  137                 Unboxed sums
  138  See Note [Translating unboxed sums to unboxed tuples] in GHC.Stg.Unarise
  139 *                                                                       *
  140 ********************************************************************** -}
  141 
  142 type SortedSlotTys = [SlotTy]
  143 
  144 -- | Given the arguments of a sum type constructor application,
  145 --   return the unboxed sum rep type.
  146 --
  147 -- E.g.
  148 --
  149 --   (# Int# | Maybe Int | (# Int#, Float# #) #)
  150 --
  151 -- We call `ubxSumRepType [ [IntRep], [LiftedRep], [IntRep, FloatRep] ]`,
  152 -- which returns [WordSlot, PtrSlot, WordSlot, FloatSlot]
  153 --
  154 -- INVARIANT: Result slots are sorted (via Ord SlotTy), except that at the head
  155 -- of the list we have the slot for the tag.
  156 ubxSumRepType :: [[PrimRep]] -> [SlotTy]
  157 ubxSumRepType constrs0
  158   -- These first two cases never classify an actual unboxed sum, which always
  159   -- has at least two disjuncts. But it could happen if a user writes, e.g.,
  160   -- forall (a :: TYPE (SumRep [IntRep])). ...
  161   -- which could never be instantiated. We still don't want to panic.
  162   | constrs0 `lengthLessThan` 2
  163   = [WordSlot]
  164 
  165   | otherwise
  166   = let
  167       combine_alts :: [SortedSlotTys]  -- slots of constructors
  168                    -> SortedSlotTys    -- final slots
  169       combine_alts constrs = foldl' merge [] constrs
  170 
  171       merge :: SortedSlotTys -> SortedSlotTys -> SortedSlotTys
  172       merge existing_slots []
  173         = existing_slots
  174       merge [] needed_slots
  175         = needed_slots
  176       merge (es : ess) (s : ss)
  177         | Just s' <- s `fitsIn` es
  178         = -- found a slot, use it
  179           s' : merge ess ss
  180         | s < es
  181         = -- we need a new slot and this is the right place for it
  182           s : merge (es : ess) ss
  183         | otherwise
  184         = -- keep searching for a slot
  185           es : merge ess (s : ss)
  186 
  187       -- Nesting unboxed tuples and sums is OK, so we need to flatten first.
  188       rep :: [PrimRep] -> SortedSlotTys
  189       rep ty = sort (map primRepSlot ty)
  190 
  191       sumRep = WordSlot : combine_alts (map rep constrs0)
  192                -- WordSlot: for the tag of the sum
  193     in
  194       sumRep
  195 
  196 layoutUbxSum :: SortedSlotTys -- Layout of sum. Does not include tag.
  197                               -- We assume that they are in increasing order
  198              -> [SlotTy]      -- Slot types of things we want to map to locations in the
  199                               -- sum layout
  200              -> [Int]         -- Where to map 'things' in the sum layout
  201 layoutUbxSum sum_slots0 arg_slots0 =
  202     go arg_slots0 IS.empty
  203   where
  204     go :: [SlotTy] -> IS.IntSet -> [Int]
  205     go [] _
  206       = []
  207     go (arg : args) used
  208       = let slot_idx = findSlot arg 0 sum_slots0 used
  209          in slot_idx : go args (IS.insert slot_idx used)
  210 
  211     findSlot :: SlotTy -> Int -> SortedSlotTys -> IS.IntSet -> Int
  212     findSlot arg slot_idx (slot : slots) useds
  213       | not (IS.member slot_idx useds)
  214       , Just slot == arg `fitsIn` slot
  215       = slot_idx
  216       | otherwise
  217       = findSlot arg (slot_idx + 1) slots useds
  218     findSlot _ _ [] _
  219       = pprPanic "findSlot" (text "Can't find slot" $$ ppr sum_slots0 $$ ppr arg_slots0)
  220 
  221 --------------------------------------------------------------------------------
  222 
  223 -- We have 3 kinds of slots:
  224 --
  225 --   - Pointer slot: Only shared between actual pointers to Haskell heap (i.e.
  226 --     boxed objects). These come in two variants: Lifted and unlifted (see
  227 --     #19645).
  228 --
  229 --   - Word slots: Shared between IntRep, WordRep, Int64Rep, Word64Rep, AddrRep.
  230 --
  231 --   - Float slots: Shared between floating point types.
  232 --
  233 --   - Void slots: Shared between void types. Not used in sums.
  234 --
  235 -- TODO(michalt): We should probably introduce `SlotTy`s for 8-/16-/32-bit
  236 -- values, so that we can pack things more tightly.
  237 data SlotTy = PtrLiftedSlot | PtrUnliftedSlot | WordSlot | Word64Slot | FloatSlot | DoubleSlot
  238   deriving (Eq, Ord)
  239     -- Constructor order is important! If slot A could fit into slot B
  240     -- then slot A must occur first.  E.g.  FloatSlot before DoubleSlot
  241     --
  242     -- We are assuming that WordSlot is smaller than or equal to Word64Slot
  243     -- (would not be true on a 128-bit machine)
  244 
  245 instance Outputable SlotTy where
  246   ppr PtrLiftedSlot   = text "PtrLiftedSlot"
  247   ppr PtrUnliftedSlot = text "PtrUnliftedSlot"
  248   ppr Word64Slot      = text "Word64Slot"
  249   ppr WordSlot        = text "WordSlot"
  250   ppr DoubleSlot      = text "DoubleSlot"
  251   ppr FloatSlot       = text "FloatSlot"
  252 
  253 typeSlotTy :: UnaryType -> Maybe SlotTy
  254 typeSlotTy ty
  255   | isVoidTy ty
  256   = Nothing
  257   | otherwise
  258   = Just (primRepSlot (typePrimRep1 ty))
  259 
  260 primRepSlot :: PrimRep -> SlotTy
  261 primRepSlot VoidRep     = pprPanic "primRepSlot" (text "No slot for VoidRep")
  262 primRepSlot LiftedRep   = PtrLiftedSlot
  263 primRepSlot UnliftedRep = PtrUnliftedSlot
  264 primRepSlot IntRep      = WordSlot
  265 primRepSlot Int8Rep     = WordSlot
  266 primRepSlot Int16Rep    = WordSlot
  267 primRepSlot Int32Rep    = WordSlot
  268 primRepSlot Int64Rep    = Word64Slot
  269 primRepSlot WordRep     = WordSlot
  270 primRepSlot Word8Rep    = WordSlot
  271 primRepSlot Word16Rep   = WordSlot
  272 primRepSlot Word32Rep   = WordSlot
  273 primRepSlot Word64Rep   = Word64Slot
  274 primRepSlot AddrRep     = WordSlot
  275 primRepSlot FloatRep    = FloatSlot
  276 primRepSlot DoubleRep   = DoubleSlot
  277 primRepSlot VecRep{}    = pprPanic "primRepSlot" (text "No slot for VecRep")
  278 
  279 slotPrimRep :: SlotTy -> PrimRep
  280 slotPrimRep PtrLiftedSlot   = LiftedRep
  281 slotPrimRep PtrUnliftedSlot = UnliftedRep
  282 slotPrimRep Word64Slot      = Word64Rep
  283 slotPrimRep WordSlot        = WordRep
  284 slotPrimRep DoubleSlot      = DoubleRep
  285 slotPrimRep FloatSlot       = FloatRep
  286 
  287 -- | Returns the bigger type if one fits into the other. (commutative)
  288 --
  289 -- Note that lifted and unlifted pointers are *not* in a fits-in relation for
  290 -- the reasons described in Note [Don't merge lifted and unlifted slots] in
  291 -- GHC.Stg.Unarise.
  292 fitsIn :: SlotTy -> SlotTy -> Maybe SlotTy
  293 fitsIn ty1 ty2
  294   | ty1 == ty2
  295   = Just ty1
  296   | isWordSlot ty1 && isWordSlot ty2
  297   = Just (max ty1 ty2)
  298   | isFloatSlot ty1 && isFloatSlot ty2
  299   = Just (max ty1 ty2)
  300   | otherwise
  301   = Nothing
  302   where
  303     isWordSlot Word64Slot = True
  304     isWordSlot WordSlot   = True
  305     isWordSlot _          = False
  306 
  307     isFloatSlot DoubleSlot = True
  308     isFloatSlot FloatSlot  = True
  309     isFloatSlot _          = False
  310 
  311 
  312 {- **********************************************************************
  313 *                                                                       *
  314                    PrimRep
  315 *                                                                       *
  316 *************************************************************************
  317 
  318 Note [RuntimeRep and PrimRep]
  319 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  320 This Note describes the relationship between GHC.Types.RuntimeRep
  321 (of levity/representation polymorphism fame) and GHC.Core.TyCon.PrimRep,
  322 as these types are closely related.
  323 
  324 A "primitive entity" is one that can be
  325  * stored in one register
  326  * manipulated with one machine instruction
  327 
  328 
  329 Examples include:
  330  * a 32-bit integer
  331  * a 32-bit float
  332  * a 64-bit float
  333  * a machine address (heap pointer), etc.
  334  * a quad-float (on a machine with SIMD register and instructions)
  335  * ...etc...
  336 
  337 The "representation or a primitive entity" specifies what kind of register is
  338 needed and how many bits are required. The data type GHC.Core.TyCon.PrimRep
  339 enumerates all the possibilities.
  340 
  341 data PrimRep
  342   = VoidRep       -- See Note [VoidRep]
  343   | LiftedRep     -- ^ Lifted pointer
  344   | UnliftedRep   -- ^ Unlifted pointer
  345   | Int8Rep       -- ^ Signed, 8-bit value
  346   | Int16Rep      -- ^ Signed, 16-bit value
  347   ...etc...
  348   | VecRep Int PrimElemRep  -- ^ SIMD fixed-width vector
  349 
  350 The Haskell source language is a bit more flexible: a single value may need multiple PrimReps.
  351 For example
  352 
  353   utup :: (# Int, Int #) -> Bool
  354   utup x = ...
  355 
  356 Here x :: (# Int, Int #), and that takes two registers, and two instructions to move around.
  357 Unboxed sums are similar.
  358 
  359 Every Haskell expression e has a type ty, whose kind is of form TYPE rep
  360    e :: ty :: TYPE rep
  361 where rep :: RuntimeRep. Here rep describes the runtime representation for e's value,
  362 but RuntimeRep has some extra cases:
  363 
  364 data RuntimeRep = VecRep VecCount VecElem   -- ^ a SIMD vector type
  365                 | TupleRep [RuntimeRep]     -- ^ An unboxed tuple of the given reps
  366                 | SumRep [RuntimeRep]       -- ^ An unboxed sum of the given reps
  367                 | BoxedRep Levity -- ^ boxed; represented by a pointer
  368                 | IntRep          -- ^ signed, word-sized value
  369                 ...etc...
  370 data Levity     = Lifted
  371                 | Unlifted
  372 
  373 It's all in 1-1 correspondence with PrimRep except for TupleRep and SumRep,
  374 which describe unboxed products and sums respectively. RuntimeRep is defined
  375 in the library ghc-prim:GHC.Types. It is also "wired-in" to GHC: see
  376 GHC.Builtin.Types.runtimeRepTyCon. The unarisation pass, in GHC.Stg.Unarise, transforms the
  377 program, so that every variable has a type that has a PrimRep. For
  378 example, unarisation transforms our utup function above, to take two Int
  379 arguments instead of one (# Int, Int #) argument.
  380 
  381 Also, note that boxed types are represented slightly differently in RuntimeRep
  382 and PrimRep. PrimRep just has the nullary LiftedRep and UnliftedRep data
  383 constructors. RuntimeRep has a BoxedRep data constructor, which accepts a
  384 Levity. The subtle distinction is that since BoxedRep can accept a variable
  385 argument, RuntimeRep can talk about levity polymorphic types. PrimRep, by
  386 contrast, cannot.
  387 
  388 See also Note [Getting from RuntimeRep to PrimRep] and Note [VoidRep].
  389 
  390 Note [VoidRep]
  391 ~~~~~~~~~~~~~~
  392 PrimRep contains a constructor VoidRep, while RuntimeRep does
  393 not. Yet representations are often characterised by a list of PrimReps,
  394 where a void would be denoted as []. (See also Note [RuntimeRep and PrimRep].)
  395 
  396 However, after the unariser, all identifiers have exactly one PrimRep, but
  397 void arguments still exist. Thus, PrimRep includes VoidRep to describe these
  398 binders. Perhaps post-unariser representations (which need VoidRep) should be
  399 a different type than pre-unariser representations (which use a list and do
  400 not need VoidRep), but we have what we have.
  401 
  402 RuntimeRep instead uses TupleRep '[] to denote a void argument. When
  403 converting a TupleRep '[] into a list of PrimReps, we get an empty list.
  404 
  405 Note [Getting from RuntimeRep to PrimRep]
  406 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  407 General info on RuntimeRep and PrimRep is in Note [RuntimeRep and PrimRep].
  408 
  409 How do we get from an Id to the list or PrimReps used to store it? We get
  410 the Id's type ty (using idType), then ty's kind ki (using typeKind), then
  411 pattern-match on ki to extract rep (in kindPrimRep), then extract the PrimRep
  412 from the RuntimeRep (in runtimeRepPrimRep).
  413 
  414 We now must convert the RuntimeRep to a list of PrimReps. Let's look at two
  415 examples:
  416 
  417   1. x :: Int#
  418   2. y :: (# Int, Word# #)
  419 
  420 With these types, we can extract these kinds:
  421 
  422   1. Int# :: TYPE IntRep
  423   2. (# Int, Word# #) :: TYPE (TupleRep [LiftedRep, WordRep])
  424 
  425 In the end, we will get these PrimReps:
  426 
  427   1. [IntRep]
  428   2. [LiftedRep, WordRep]
  429 
  430 It would thus seem that we should have a function somewhere of
  431 type `RuntimeRep -> [PrimRep]`. This doesn't work though: when we
  432 look at the argument of TYPE, we get something of type Type (of course).
  433 RuntimeRep exists in the user's program, but not in GHC as such.
  434 Instead, we must decompose the Type of kind RuntimeRep into tycons and
  435 extract the PrimReps from the TyCons. This is what runtimeRepPrimRep does:
  436 it takes a Type and returns a [PrimRep]
  437 
  438 runtimeRepPrimRep works by using tyConRuntimeRepInfo. That function
  439 should be passed the TyCon produced by promoting one of the constructors
  440 of RuntimeRep into type-level data. The RuntimeRep promoted datacons are
  441 associated with a RuntimeRepInfo (stored directly in the PromotedDataCon
  442 constructor of TyCon). This pairing happens in GHC.Builtin.Types. A RuntimeRepInfo
  443 usually(*) contains a function from [Type] to [PrimRep]: the [Type] are
  444 the arguments to the promoted datacon. These arguments are necessary
  445 for the TupleRep and SumRep constructors, so that this process can recur,
  446 producing a flattened list of PrimReps. Calling this extracted function
  447 happens in runtimeRepPrimRep; the functions themselves are defined in
  448 tupleRepDataCon and sumRepDataCon, both in GHC.Builtin.Types.
  449 
  450 The (*) above is to support vector representations. RuntimeRep refers
  451 to VecCount and VecElem, whose promoted datacons have nuggets of information
  452 related to vectors; these form the other alternatives for RuntimeRepInfo.
  453 
  454 Returning to our examples, the Types we get (after stripping off TYPE) are
  455 
  456   1. TyConApp (PromotedDataCon "IntRep") []
  457   2. TyConApp (PromotedDataCon "TupleRep")
  458               [TyConApp (PromotedDataCon ":")
  459                         [ TyConApp (AlgTyCon "RuntimeRep") []
  460                         , TyConApp (PromotedDataCon "LiftedRep") []
  461                         , TyConApp (PromotedDataCon ":")
  462                                    [ TyConApp (AlgTyCon "RuntimeRep") []
  463                                    , TyConApp (PromotedDataCon "WordRep") []
  464                                    , TyConApp (PromotedDataCon "'[]")
  465                                               [TyConApp (AlgTyCon "RuntimeRep") []]]]]
  466 
  467 runtimeRepPrimRep calls tyConRuntimeRepInfo on (PromotedDataCon "IntRep"), resp.
  468 (PromotedDataCon "TupleRep"), extracting a function that will produce the PrimReps.
  469 In example 1, this function is passed an empty list (the empty list of args to IntRep)
  470 and returns the PrimRep IntRep. (See the definition of runtimeRepSimpleDataCons in
  471 GHC.Builtin.Types and its helper function mk_runtime_rep_dc.) Example 2 passes the promoted
  472 list as the one argument to the extracted function. The extracted function is defined
  473 as prim_rep_fun within tupleRepDataCon in GHC.Builtin.Types. It takes one argument, decomposes
  474 the promoted list (with extractPromotedList), and then recurs back to runtimeRepPrimRep
  475 to process the LiftedRep and WordRep, concatentating the results.
  476 
  477 -}
  478 
  479 -- | Discovers the primitive representation of a 'Type'. Returns
  480 -- a list of 'PrimRep': it's a list because of the possibility of
  481 -- no runtime representation (void) or multiple (unboxed tuple/sum)
  482 -- See also Note [Getting from RuntimeRep to PrimRep]
  483 typePrimRep :: HasDebugCallStack => Type -> [PrimRep]
  484 typePrimRep ty = kindPrimRep (text "typePrimRep" <+>
  485                               parens (ppr ty <+> dcolon <+> ppr (typeKind ty)))
  486                              (typeKind ty)
  487 
  488 -- | Like 'typePrimRep', but assumes that there is precisely one 'PrimRep' output;
  489 -- an empty list of PrimReps becomes a VoidRep.
  490 -- This assumption holds after unarise, see Note [Post-unarisation invariants].
  491 -- Before unarise it may or may not hold.
  492 -- See also Note [RuntimeRep and PrimRep] and Note [VoidRep]
  493 typePrimRep1 :: HasDebugCallStack => UnaryType -> PrimRep
  494 typePrimRep1 ty = case typePrimRep ty of
  495   []    -> VoidRep
  496   [rep] -> rep
  497   _     -> pprPanic "typePrimRep1" (ppr ty $$ ppr (typePrimRep ty))
  498 
  499 -- | Like 'typePrimRep', but returns 'Nothing' instead of panicking, when
  500 --
  501 --    * The @ty@ was not of form @TYPE rep@
  502 --    * @rep@ was not monomorphic
  503 --
  504 typeMonoPrimRep_maybe :: Type -> Maybe [PrimRep]
  505 typeMonoPrimRep_maybe ty = getRuntimeRep_maybe ty >>= runtimeRepMonoPrimRep_maybe
  506 
  507 -- | Find the runtime representation of a 'TyCon'. Defined here to
  508 -- avoid module loops. Returns a list of the register shapes necessary.
  509 -- See also Note [Getting from RuntimeRep to PrimRep]
  510 tyConPrimRep :: HasDebugCallStack => TyCon -> [PrimRep]
  511 tyConPrimRep tc
  512   = kindPrimRep (text "kindRep tc" <+> ppr tc $$ ppr res_kind)
  513                 res_kind
  514   where
  515     res_kind = tyConResKind tc
  516 
  517 -- | Like 'tyConPrimRep', but assumed that there is precisely zero or
  518 -- one 'PrimRep' output
  519 -- See also Note [Getting from RuntimeRep to PrimRep] and Note [VoidRep]
  520 tyConPrimRep1 :: HasDebugCallStack => TyCon -> PrimRep
  521 tyConPrimRep1 tc = case tyConPrimRep tc of
  522   []    -> VoidRep
  523   [rep] -> rep
  524   _     -> pprPanic "tyConPrimRep1" (ppr tc $$ ppr (tyConPrimRep tc))
  525 
  526 -- | Take a kind (of shape @TYPE rr@) and produce the 'PrimRep's
  527 -- of values of types of this kind.
  528 -- See also Note [Getting from RuntimeRep to PrimRep]
  529 kindPrimRep :: HasDebugCallStack => SDoc -> Kind -> [PrimRep]
  530 kindPrimRep doc ki
  531   | Just ki' <- coreView ki
  532   = kindPrimRep doc ki'
  533 kindPrimRep doc (TyConApp typ [runtime_rep])
  534   = assert (typ `hasKey` tYPETyConKey) $
  535     runtimeRepPrimRep doc runtime_rep
  536 kindPrimRep doc ki
  537   = pprPanic "kindPrimRep" (ppr ki $$ doc)
  538 
  539 -- | Take a type of kind RuntimeRep and extract the list of 'PrimRep' that
  540 -- it encodes if it's a monomorphic rep. Otherwise returns 'Nothing'.
  541 -- See also Note [Getting from RuntimeRep to PrimRep]
  542 runtimeRepMonoPrimRep_maybe :: HasDebugCallStack => Type -> Maybe [PrimRep]
  543 runtimeRepMonoPrimRep_maybe rr_ty
  544   | Just (rr_dc, args) <- splitTyConApp_maybe rr_ty
  545   , assertPpr (runtimeRepTy `eqType` typeKind rr_ty) (ppr rr_ty) True
  546   , RuntimeRep fun <- tyConRuntimeRepInfo rr_dc
  547   = Just (fun args)
  548   | otherwise
  549   = Nothing -- not mono rep
  550 
  551 -- | Take a type of kind RuntimeRep and extract the list of 'PrimRep' that
  552 -- it encodes. See also Note [Getting from RuntimeRep to PrimRep]
  553 -- The [PrimRep] is the final runtime representation /after/ unarisation
  554 runtimeRepPrimRep :: HasDebugCallStack => SDoc -> Type -> [PrimRep]
  555 runtimeRepPrimRep doc rr_ty
  556   | Just rr_ty' <- coreView rr_ty
  557   = runtimeRepPrimRep doc rr_ty'
  558   | TyConApp rr_dc args <- rr_ty
  559   , RuntimeRep fun <- tyConRuntimeRepInfo rr_dc
  560   = fun args
  561   | otherwise
  562   = pprPanic "runtimeRepPrimRep" (doc $$ ppr rr_ty)
  563 
  564 -- | Convert a PrimRep back to a Type. Used only in the unariser to give types
  565 -- to fresh Ids. Really, only the type's representation matters.
  566 -- See also Note [RuntimeRep and PrimRep]
  567 primRepToType :: PrimRep -> Type
  568 primRepToType = anyTypeOfKind . tYPE . primRepToRuntimeRep