[project @ 2002-06-28 14:06:52 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index f5998d2..954ada9 100644 (file)
@@ -14,18 +14,23 @@ have a standard form, namely:
 \begin{code}
 module MkId (
        mkDictFunId, mkDefaultMethodId,
-       mkDictSelId,
+       mkDictSelId, 
 
        mkDataConId, mkDataConWrapId,
-       mkRecordSelId, rebuildConArgs,
+       mkRecordSelId, 
        mkPrimOpId, mkFCallId,
 
+       mkReboxingAlt, mkNewTypeBody,
+
        -- And some particular Ids; see below for why they are wired in
-       wiredInIds,
-       unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId,
-       eRROR_ID, eRROR_CSTRING_ID, rEC_SEL_ERROR_ID, pAT_ERROR_ID, rEC_CON_ERROR_ID,
-       rEC_UPD_ERROR_ID, iRREFUT_PAT_ERROR_ID, nON_EXHAUSTIVE_GUARDS_ERROR_ID,
-       nO_METHOD_BINDING_ERROR_ID, aBSENT_ERROR_ID, pAR_ERROR_ID
+       wiredInIds, ghcPrimIds,
+       unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId, seqId,
+       lazyId, lazyIdUnfolding, lazyIdKey,
+
+       mkRuntimeErrorApp,
+       rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID,
+       nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID,
+       pAT_ERROR_ID
     ) where
 
 #include "HsVersions.h"
@@ -45,13 +50,13 @@ import TcType               ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
                          tcSplitFunTys, tcSplitForAllTys, mkPredTy
                        )
 import Module          ( Module )
-import CoreUtils       ( mkInlineMe, exprType )
+import CoreUtils       ( exprType )
 import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
 import Literal         ( Literal(..), nullAddrLit )
 import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
                           tyConTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon )
 import Class           ( Class, classTyCon, classTyVars, classSelIds )
-import Var             ( Id, TyVar )
+import Var             ( Id, TyVar, Var )
 import VarSet          ( isEmptyVarSet )
 import Name            ( mkWiredInName, mkFCallName, Name )
 import OccName         ( mkVarOcc )
@@ -60,24 +65,23 @@ import ForeignCall  ( ForeignCall )
 import DataCon         ( DataCon, 
                          dataConFieldLabels, dataConRepArity, dataConTyCon,
                          dataConArgTys, dataConRepType, 
-                         dataConInstOrigArgTys,
+                         dataConOrigArgTys,
                           dataConName, dataConTheta,
-                         dataConSig, dataConStrictMarks, dataConId,
+                         dataConSig, dataConStrictMarks, dataConWorkId,
                          splitProductType
                        )
 import Id              ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal,
                          mkTemplateLocals, mkTemplateLocalsNum,
                          mkTemplateLocal, idNewStrictness, idName
                        )
-import IdInfo          ( IdInfo, noCafNoTyGenIdInfo,
+import IdInfo          ( IdInfo, noCafIdInfo, hasCafIdInfo,
                          setUnfoldingInfo, 
-                         setArityInfo, setSpecInfo,  setCgInfo, setCafInfo,
-                         newStrictnessFromOld, setAllStrictnessInfo,
-                         GlobalIdDetails(..), CafInfo(..), CprInfo(..), 
-                         CgInfo 
+                         setArityInfo, setSpecInfo, setCafInfo,
+                         setAllStrictnessInfo,
+                         GlobalIdDetails(..), CafInfo(..)
                        )
 import NewDemand       ( mkStrictSig, strictSigResInfo, DmdResult(..),
-                         mkTopDmdType, topDmd, evalDmd, lazyDmd, 
+                         mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR,
                          Demand(..), Demands(..) )
 import FieldLabel      ( mkFieldLabel, fieldLabelName, 
                          firstFieldLabelTag, allFieldLabelTags, fieldLabelType
@@ -90,8 +94,10 @@ import PrelNames
 import Maybe            ( isJust )
 import Util             ( dropList, isSingleton )
 import Outputable
+import FastString
 import ListSetOps      ( assoc, assocMaybe )
 import UnicodeUtil      ( stringToUtf8 )
+import List            ( nubBy )
 import Char             ( ord )
 \end{code}             
 
@@ -112,24 +118,31 @@ wiredInIds
        -- error-reporting functions that they have an 'open' 
        -- result type. -- sof 1/99]
 
-      aBSENT_ERROR_ID
-    , eRROR_ID
-    , eRROR_CSTRING_ID
-    , iRREFUT_PAT_ERROR_ID
-    , nON_EXHAUSTIVE_GUARDS_ERROR_ID
-    , nO_METHOD_BINDING_ERROR_ID
-    , pAR_ERROR_ID
-    , pAT_ERROR_ID
-    , rEC_CON_ERROR_ID
-    , rEC_UPD_ERROR_ID
-
-       -- These can't be defined in Haskell, but they have
+    eRROR_ID,  -- This one isn't used anywhere else in the compiler
+               -- But we still need it in wiredInIds so that when GHC
+               -- compiles a program that mentions 'error' we don't
+               -- import its type from the interface file; we just get
+               -- the Id defined here.  Which has an 'open-tyvar' type.
+
+    rUNTIME_ERROR_ID,
+    iRREFUT_PAT_ERROR_ID,
+    nON_EXHAUSTIVE_GUARDS_ERROR_ID,
+    nO_METHOD_BINDING_ERROR_ID,
+    pAT_ERROR_ID,
+    rEC_CON_ERROR_ID,
+
+    lazyId
+    ] ++ ghcPrimIds
+
+-- These Ids are exported from GHC.Prim
+ghcPrimIds
+  = [  -- These can't be defined in Haskell, but they have
        -- perfectly reasonable unfoldings in Core
-    , realWorldPrimId
-    , unsafeCoerceId
-    , nullAddrId
-    , getTagId
-    , seqId
+    realWorldPrimId,
+    unsafeCoerceId,
+    nullAddrId,
+    getTagId,
+    seqId
     ]
 \end{code}
 
@@ -146,7 +159,7 @@ mkDataConId :: Name -> DataCon -> Id
 mkDataConId work_name data_con
   = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info
   where
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setArityInfo`               arity
           `setAllStrictnessInfo`       Just strict_sig
 
@@ -173,7 +186,7 @@ mkDataConId work_name data_con
     cpr_info | isProductTyCon tycon && 
               isDataTyCon tycon    &&
               arity > 0            &&
-              arity <= mAX_CPR_SIZE    = RetCPR
+              arity <= mAX_CPR_SIZE    = retCPR
             | otherwise                = TopRes
        -- RetCPR is only true for products that are real data types;
        -- that is, not unboxed tuples or [non-recursive] newtypes
@@ -231,21 +244,19 @@ Notice that
 mkDataConWrapId data_con
   = mkGlobalId (DataConWrapId data_con) (dataConName data_con) wrap_ty info
   where
-    work_id = dataConId data_con
+    work_id = dataConWorkId data_con
 
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setUnfoldingInfo`   wrap_unf
-               -- The NoCaf-ness is set by noCafNoTyGenIdInfo
+               -- The NoCaf-ness is set by noCafIdInfo
           `setArityInfo`       arity
                -- It's important to specify the arity, so that partial
                -- applications are treated as values
           `setAllStrictnessInfo`       Just wrap_sig
 
-    wrap_ty = mkForAllTys all_tyvars (mkFunTys all_arg_tys result_ty)
-
     wrap_sig = mkStrictSig (mkTopDmdType arg_dmds res_info)
     res_info = strictSigResInfo (idNewStrictness work_id)
-    arg_dmds = [Abs | d <- dict_args] ++ map mk_dmd strict_marks
+    arg_dmds = map mk_dmd strict_marks
     mk_dmd str | isMarkedStrict str = evalDmd
               | otherwise          = lazyDmd
        -- The Cpr info can be important inside INLINE rhss, where the
@@ -262,10 +273,10 @@ mkDataConWrapId data_con
                -- No existentials on a newtype, but it can have a context
                -- e.g.         newtype Eq a => T a = MkT (...)
                mkTopUnfolding $ Note InlineMe $
-               mkLams tyvars $ mkLams dict_args $ Lam id_arg1 $ 
+               mkLams tyvars $ Lam id_arg1 $ 
                mkNewTypeBody tycon result_ty (Var id_arg1)
 
-            | null dict_args && not (any isMarkedStrict strict_marks)
+            | not (any isMarkedStrict strict_marks)
             = mkCompulsoryUnfolding (Var work_id)
                        -- The common case.  Not only is this efficient,
                        -- but it also ensures that the wrapper is replaced
@@ -286,7 +297,7 @@ mkDataConWrapId data_con
 
             | otherwise
             = mkTopUnfolding $ Note InlineMe $
-              mkLams all_tyvars $ mkLams dict_args $ 
+              mkLams all_tyvars $ 
               mkLams ex_dict_args $ mkLams id_args $
               foldr mk_case con_app 
                     (zip (ex_dict_args++id_args) strict_marks) i3 []
@@ -294,20 +305,23 @@ mkDataConWrapId data_con
     con_app i rep_ids = mkApps (Var work_id)
                               (map varToCoreExpr (all_tyvars ++ reverse rep_ids))
 
-    (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con
+    (tyvars, _, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con
     all_tyvars   = tyvars ++ ex_tyvars
 
-    dict_tys     = mkPredTys theta
     ex_dict_tys  = mkPredTys ex_theta
-    all_arg_tys  = dict_tys ++ ex_dict_tys ++ orig_arg_tys
+    all_arg_tys  = ex_dict_tys ++ orig_arg_tys
     result_ty    = mkTyConApp tycon (mkTyVarTys tyvars)
 
+    wrap_ty = mkForAllTys all_tyvars (mkFunTys all_arg_tys result_ty)
+       -- We used to include the stupid theta in the wrapper's args
+       -- but now we don't.  Instead the type checker just injects these
+       -- extra constraints where necessary.
+
     mkLocals i tys = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n)
                   where
                     n = length tys
 
-    (dict_args, i1)    = mkLocals 1  dict_tys
-    (ex_dict_args,i2)  = mkLocals i1 ex_dict_tys
+    (ex_dict_args,i2)  = mkLocals 1  ex_dict_tys
     (id_args,i3)       = mkLocals i2 orig_arg_tys
     arity             = i3-1
     (id_arg1:_)   = id_args            -- Used for newtype only
@@ -383,7 +397,7 @@ Similarly for newtypes
        unN = /\a -> \n:N -> coerce (a->a) n
 
 \begin{code}
-mkRecordSelId tycon field_label unpack_id unpackUtf8_id
+mkRecordSelId tycon field_label
        -- Assumes that all fields with the same field label have the same type
        --
        -- Annoyingly, we have to pass in the unpackCString# Id, because
@@ -398,13 +412,22 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
     data_ty   = mkTyConApp tycon tyvar_tys
     tyvar_tys = mkTyVarTys tyvars
 
-    tycon_theta        = tyConTheta tycon      -- The context on the data decl
+       -- Very tiresomely, the selectors are (unnecessarily!) overloaded over
+       -- just the dictionaries in the types of the constructors that contain
+       -- the relevant field.  [The Report says that pattern matching on a
+       -- constructor gives the same constraints as applying it.]  Urgh.  
+       --
+       -- However, not all data cons have all constraints (because of
+       -- TcTyDecls.thinContext).  So we need to find all the data cons 
+       -- involved in the pattern match and take the union of their constraints.
+       --
+       -- NB: this code relies on the fact that DataCons are quantified over
+       -- the identical type variables as their parent TyCon
+    tycon_theta         = tyConTheta tycon     -- The context on the data decl
                                        --   eg data (Eq a, Ord b) => T a b = ...
-    dict_tys  = [mkPredTy pred | pred <- tycon_theta, 
-                                needed_dict pred]
-    needed_dict pred = or [ tcEqPred pred p
-                         | (DataAlt dc, _, _) <- the_alts, p <- dataConTheta dc]
-    n_dict_tys = length dict_tys
+    needed_preds = [pred | (DataAlt dc, _, _) <- the_alts, pred <- dataConTheta dc]
+    dict_tys     = map mkPredTy (nubBy tcEqPred needed_preds)
+    n_dict_tys   = length dict_tys
 
     (field_tyvars,field_theta,field_tau) = tcSplitSigmaTy field_ty
     field_dict_tys                      = map mkPredTy field_theta
@@ -424,12 +447,6 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
        -- Note that this is exactly the type we'd infer from a user defn
        --      op (R op) = op
 
-       -- Very tiresomely, the selectors are (unnecessarily!) overloaded over
-       -- just the dictionaries in the types of the constructors that contain
-       -- the relevant field.  Urgh.  
-       -- NB: this code relies on the fact that DataCons are quantified over
-       -- the identical type variables as their parent TyCon
-
     selector_ty :: Type
     selector_ty  = mkForAllTys tyvars $ mkForAllTys field_tyvars $
                   mkFunTys dict_tys  $  mkFunTys field_dict_tys $
@@ -441,7 +458,7 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
        -- Use the demand analyser to work out strictness.
        -- With all this unpackery it's not easy!
 
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setCafInfo`           caf_info
           `setArityInfo`         arity
           `setUnfoldingInfo`     mkTopUnfolding rhs_w_str
@@ -466,7 +483,7 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
     default_alt | no_default = []
                | otherwise  = [(DEFAULT, [], error_expr)]
 
-       -- the default branch may have CAF refs, because it calls recSelError etc.
+       -- The default branch may have CAF refs, because it calls recSelError etc.
     caf_info    | no_default = NoCafRefs
                | otherwise  = MayHaveCafRefs
 
@@ -486,77 +503,83 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
        --      foo = /\a. \t:T. case t of { MkT f -> f a }
 
     mk_maybe_alt data_con 
-         = case maybe_the_arg_id of
+       = case maybe_the_arg_id of
                Nothing         -> Nothing
-               Just the_arg_id -> Just (DataAlt data_con, real_args, mkLets binds body)
-                 where
-                   body               = mk_result the_arg_id
-                   strict_marks       = dataConStrictMarks data_con
-                   (binds, real_args) = rebuildConArgs arg_ids strict_marks
-                                                       (map mkBuiltinUnique [unpack_base..])
+               Just the_arg_id -> Just (mkReboxingAlt uniqs data_con arg_ids body)
+                               where
+                                  body = mk_result the_arg_id
        where
-            arg_ids = mkTemplateLocalsNum field_base (dataConInstOrigArgTys data_con tyvar_tys)
+            arg_ids = mkTemplateLocalsNum field_base (dataConOrigArgTys data_con)
+                       -- No need to instantiate; same tyvars in datacon as tycon
 
            unpack_base = field_base + length arg_ids
+           uniqs = map mkBuiltinUnique [unpack_base..]
 
                                -- arity+1 avoids all shadowing
            maybe_the_arg_id  = assocMaybe (field_lbls `zip` arg_ids) field_label
            field_lbls        = dataConFieldLabels data_con
 
-    error_expr = mkApps (Var rEC_SEL_ERROR_ID) [Type field_tau, err_string]
-    err_string
-        | all safeChar full_msg
-            = App (Var unpack_id) (Lit (MachStr (_PK_ full_msg)))
-        | otherwise
-            = App (Var unpackUtf8_id) (Lit (MachStr (_PK_ (stringToUtf8 (map ord full_msg)))))
-        where
-        safeChar c = c >= '\1' && c <= '\xFF'
-        -- TODO: Putting this Unicode stuff here is ugly. Find a better
-        -- generic place to make string literals. This logic is repeated
-        -- in DsUtils.
+    error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_tau full_msg
     full_msg   = showSDoc (sep [text "No match in record selector", ppr sel_id]) 
 
 
--- This rather ugly function converts the unpacked data con 
--- arguments back into their packed form.
-
-rebuildConArgs
-  :: [Id]                      -- Source-level args
-  -> [StrictnessMark]          -- Strictness annotations (per-arg)
-  -> [Unique]                  -- Uniques for the new Ids
-  -> ([CoreBind], [Id])                -- A binding for each source-level arg, plus
-                               -- a list of the representation-level arguments 
--- e.g.   data T = MkT Int !Int
+-- (mkReboxingAlt us con xs rhs) basically constructs the case
+-- alternative (con, xs, rhs)
+-- but it does the reboxing necessary to construct the *source* 
+-- arguments, xs, from the representation arguments ys.
+-- For example:
+--     data T = MkT !(Int,Int) Bool
+--
+-- mkReboxingAlt MkT [x,b] r 
+--     = (DataAlt MkT, [y::Int,z::Int,b], let x = (y,z) in r)
 --
--- rebuild [x::Int, y::Int] [Not, Unbox]
---  = ([ y = I# t ], [x,t])
+-- mkDataAlt should really be in DataCon, but it can't because
+-- it manipulates CoreSyn.
 
-rebuildConArgs []        stricts us = ([], [])
+mkReboxingAlt
+  :: [Unique]                  -- Uniques for the new Ids
+  -> DataCon
+  -> [Var]                     -- Source-level args
+  -> CoreExpr                  -- RHS
+  -> CoreAlt
 
--- Type variable case
-rebuildConArgs (arg:args) stricts us 
-  | isTyVar arg
-  = let (binds, args') = rebuildConArgs args stricts us
-    in  (binds, arg:args')
+mkReboxingAlt us con args rhs
+  | not (any isMarkedUnboxed stricts)
+  = (DataAlt con, args, rhs)
 
--- Term variable case
-rebuildConArgs (arg:args) (str:stricts) us
-  | isMarkedUnboxed str
+  | otherwise
   = let
-       arg_ty  = idType arg
-
-       (_, tycon_args, pack_con, con_arg_tys)
-                = splitProductType "rebuildConArgs" arg_ty
-
-       unpacked_args  = zipWith (mkSysLocal SLIT("rb")) us con_arg_tys
-       (binds, args') = rebuildConArgs args stricts (dropList con_arg_tys us)
-       con_app        = mkConApp pack_con (map Type tycon_args ++ map Var unpacked_args)
+       (binds, args') = go args stricts us
     in
-    (NonRec arg con_app : binds, unpacked_args ++ args')
+    (DataAlt con, args', mkLets binds rhs)
 
-  | otherwise
-  = let (binds, args') = rebuildConArgs args stricts us
-    in  (binds, arg:args')
+  where
+    stricts = dataConStrictMarks con
+
+    go [] stricts us = ([], [])
+
+       -- Type variable case
+    go (arg:args) stricts us 
+      | isTyVar arg
+      = let (binds, args') = go args stricts us
+       in  (binds, arg:args')
+
+       -- Term variable case
+    go (arg:args) (str:stricts) us
+      | isMarkedUnboxed str
+      = let
+         (_, tycon_args, pack_con, con_arg_tys)
+                = splitProductType "mkReboxingAlt" (idType arg)
+
+         unpacked_args  = zipWith (mkSysLocal FSLIT("rb")) us con_arg_tys
+         (binds, args') = go args stricts (dropList con_arg_tys us)
+         con_app        = mkConApp pack_con (map Type tycon_args ++ map Var unpacked_args)
+       in
+       (NonRec arg con_app : binds, unpacked_args ++ args')
+
+      | otherwise
+      = let (binds, args') = go args stricts us
+        in  (binds, arg:args')
 \end{code}
 
 
@@ -586,7 +609,7 @@ mkDictSelId name clas
     field_lbl = mkFieldLabel name tycon sel_ty tag
     tag       = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` allFieldLabelTags) name
 
-    info      = noCafNoTyGenIdInfo
+    info      = noCafIdInfo
                `setArityInfo`          1
                `setUnfoldingInfo`      mkTopUnfolding rhs
                `setAllStrictnessInfo`  Just strict_sig
@@ -641,16 +664,15 @@ mkPrimOpId :: PrimOp -> Id
 mkPrimOpId prim_op 
   = id
   where
-    (tyvars,arg_tys,res_ty, arity, strict_info) = primOpSig prim_op
+    (tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op
     ty   = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
     name = mkPrimOpIdName prim_op
     id   = mkGlobalId (PrimOpId prim_op) name ty info
                
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setSpecInfo`        rules
           `setArityInfo`       arity
-          `setAllStrictnessInfo`       Just (newStrictnessFromOld name arity strict_info NoCPRInfo)
-       -- Until we modify the primop generation code
+          `setAllStrictnessInfo` Just strict_sig
 
     rules = foldl (addRule id) emptyCoreRules (primOpRules prim_op)
 
@@ -671,13 +693,13 @@ mkFCallId uniq fcall ty
        -- when doing substitutions won't substitute over it
     mkGlobalId (FCallId fcall) name ty info
   where
-    occ_str = showSDocIface (braces (ppr fcall <+> ppr ty))
+    occ_str = showSDoc (braces (ppr fcall <+> ppr ty))
        -- The "occurrence name" of a ccall is the full info about the
        -- ccall; it is encoded, but may have embedded spaces etc!
 
     name = mkFCallName uniq occ_str
 
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setArityInfo`               arity
           `setAllStrictnessInfo`       Just strict_sig
 
@@ -721,7 +743,7 @@ BUT make sure they are *exported* LocalIds (setIdLocalExported) so
 that they aren't discarded by the occurrence analyser.
 
 \begin{code}
-mkDefaultMethodId dm_name ty = mkVanillaGlobal dm_name ty noCafNoTyGenIdInfo
+mkDefaultMethodId dm_name ty = mkVanillaGlobal dm_name ty noCafIdInfo
 
 mkDictFunId :: Name            -- Name to use for the dict fun;
            -> Class 
@@ -731,7 +753,7 @@ mkDictFunId :: Name         -- Name to use for the dict fun;
            -> Id
 
 mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta
-  = mkVanillaGlobal dfun_name dfun_ty noCafNoTyGenIdInfo
+  = mkVanillaGlobal dfun_name dfun_ty noCafIdInfo
   where
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
 
@@ -771,12 +793,12 @@ mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta
 %*                                                                     *
 %************************************************************************
 
-These Ids can't be defined in Haskell.  They could be defined in 
-unfoldings in PrelGHC.hi-boot, but we'd have to ensure that they
-were definitely, definitely inlined, because there is no curried
-identifier for them.  That's what mkCompulsoryUnfolding does.
-If we had a way to get a compulsory unfolding from an interface file,
-we could do that, but we don't right now.
+These Ids can't be defined in Haskell.  They could be defined in
+unfoldings in the wired-in GHC.Prim interface file, but we'd have to
+ensure that they were definitely, definitely inlined, because there is
+no curried identifier for them.  That's what mkCompulsoryUnfolding
+does.  If we had a way to get a compulsory unfolding from an interface
+file, we could do that, but we don't right now.
 
 unsafeCoerce# isn't so much a PrimOp as a phantom identifier, that
 just gets expanded into a type coercion wherever it occurs.  Hence we
@@ -789,9 +811,9 @@ another gun with which to shoot yourself in the foot.
 \begin{code}
 -- unsafeCoerce# :: forall a b. a -> b
 unsafeCoerceId
-  = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
+  = pcMiscPrelId unsafeCoerceIdKey gHC_PRIM FSLIT("unsafeCoerce#") ty info
   where
-    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
           
 
     ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
@@ -804,21 +826,38 @@ unsafeCoerceId
 -- The reason is is here is because we don't provide 
 -- a way to write this literal in Haskell.
 nullAddrId 
-  = pcMiscPrelId nullAddrIdKey pREL_GHC SLIT("nullAddr#") addrPrimTy info
+  = pcMiscPrelId nullAddrIdKey gHC_PRIM FSLIT("nullAddr#") addrPrimTy info
   where
-    info = noCafNoTyGenIdInfo `setUnfoldingInfo` 
+    info = noCafIdInfo `setUnfoldingInfo` 
           mkCompulsoryUnfolding (Lit nullAddrLit)
 
 seqId
-  = pcMiscPrelId seqIdKey pREL_GHC SLIT("seq") ty info
+  = pcMiscPrelId seqIdKey gHC_PRIM FSLIT("seq") ty info
   where
-    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
           
 
     ty  = mkForAllTys [alphaTyVar,betaTyVar]
                      (mkFunTy alphaTy (mkFunTy betaTy betaTy))
     [x,y] = mkTemplateLocals [alphaTy, betaTy]
     rhs = mkLams [alphaTyVar,betaTyVar,x,y] (Case (Var x) x [(DEFAULT, [], Var y)])
+
+-- lazy :: forall a?. a? -> a?  (i.e. works for unboxed types too)
+-- Used to lazify pseq:                pseq a b = a `seq` lazy b
+-- No unfolding: it gets "inlined" by the worker/wrapper pass
+-- Also, no strictness: by being a built-in Id, it overrides all
+-- the info in PrelBase.hi.  This is important, because the strictness
+-- analyser will spot it as strict!
+lazyId
+  = pcMiscPrelId lazyIdKey pREL_BASE FSLIT("lazy") ty info
+  where
+    info = noCafIdInfo
+    ty  = mkForAllTys [alphaTyVar] (mkFunTy alphaTy alphaTy)
+
+lazyIdUnfolding :: CoreExpr    -- Used to expand LazyOp after strictness anal
+lazyIdUnfolding = mkLams [openAlphaTyVar,x] (Var x)
+               where
+                 [x] = mkTemplateLocals [openAlphaTy]
 \end{code}
 
 @getTag#@ is another function which can't be defined in Haskell.  It needs to
@@ -826,9 +865,9 @@ evaluate its argument and call the dataToTag# primitive.
 
 \begin{code}
 getTagId
-  = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info
+  = pcMiscPrelId getTagIdKey gHC_PRIM FSLIT("getTag#") ty info
   where
-    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
        -- We don't provide a defn for this; you must inline it
 
     ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy)
@@ -851,16 +890,16 @@ This comes up in strictness analysis
 
 \begin{code}
 realWorldPrimId        -- :: State# RealWorld
-  = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#")
+  = pcMiscPrelId realWorldPrimIdKey gHC_PRIM FSLIT("realWorld#")
                 realWorldStatePrimTy
-                (noCafNoTyGenIdInfo `setUnfoldingInfo` mkOtherCon [])
+                (noCafIdInfo `setUnfoldingInfo` mkOtherCon [])
        -- The mkOtherCon makes it look that realWorld# is evaluated
        -- which in turn makes Simplify.interestingArg return True,
        -- which in turn makes INLINE things applied to realWorld# likely
        -- to be inlined
 
 voidArgId      -- :: State# RealWorld
-  = mkSysLocal SLIT("void") voidArgIdKey realWorldStatePrimTy
+  = mkSysLocal FSLIT("void") voidArgIdKey realWorldStatePrimTy
 \end{code}
 
 
@@ -886,33 +925,40 @@ not know to be a bottoming Id.  It is used in the @_par_@ and @_seq_@
 templates, but we don't ever expect to generate code for it.
 
 \begin{code}
-eRROR_ID
-  = pc_bottoming_Id errorIdKey pREL_ERR SLIT("error") errorTy
-eRROR_CSTRING_ID
-  = pc_bottoming_Id errorCStringIdKey pREL_ERR SLIT("errorCString") 
-                   (mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy))
-pAT_ERROR_ID
-  = generic_ERROR_ID patErrorIdKey SLIT("patError")
-rEC_SEL_ERROR_ID
-  = generic_ERROR_ID recSelErrIdKey SLIT("recSelError")
-rEC_CON_ERROR_ID
-  = generic_ERROR_ID recConErrorIdKey SLIT("recConError")
-rEC_UPD_ERROR_ID
-  = generic_ERROR_ID recUpdErrorIdKey SLIT("recUpdError")
-iRREFUT_PAT_ERROR_ID
-  = generic_ERROR_ID irrefutPatErrorIdKey SLIT("irrefutPatError")
-nON_EXHAUSTIVE_GUARDS_ERROR_ID
-  = generic_ERROR_ID nonExhaustiveGuardsErrorIdKey SLIT("nonExhaustiveGuardsError")
-nO_METHOD_BINDING_ERROR_ID
-  = generic_ERROR_ID noMethodBindingErrorIdKey SLIT("noMethodBindingError")
-
-aBSENT_ERROR_ID
-  = pc_bottoming_Id absentErrorIdKey pREL_ERR SLIT("absentErr")
-       (mkSigmaTy [openAlphaTyVar] [] openAlphaTy)
-
-pAR_ERROR_ID
-  = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError")
-    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafNoTyGenIdInfo
+mkRuntimeErrorApp 
+       :: Id           -- Should be of type (forall a. Addr# -> a)
+                       --      where Addr# points to a UTF8 encoded string
+       -> Type         -- The type to instantiate 'a'
+       -> String       -- The string to print
+       -> CoreExpr
+
+mkRuntimeErrorApp err_id res_ty err_msg 
+  = mkApps (Var err_id) [Type res_ty, err_string]
+  where
+    err_string = Lit (MachStr (mkFastString (stringToUtf8 err_msg)))
+
+rEC_SEL_ERROR_ID               = mkRuntimeErrorId recSelErrIdKey                FSLIT("recSelError")
+rUNTIME_ERROR_ID               = mkRuntimeErrorId runtimeErrorIdKey             FSLIT("runtimeError")
+
+iRREFUT_PAT_ERROR_ID           = mkRuntimeErrorId irrefutPatErrorIdKey          FSLIT("irrefutPatError")
+rEC_CON_ERROR_ID               = mkRuntimeErrorId recConErrorIdKey              FSLIT("recConError")
+nON_EXHAUSTIVE_GUARDS_ERROR_ID = mkRuntimeErrorId nonExhaustiveGuardsErrorIdKey FSLIT("nonExhaustiveGuardsError")
+pAT_ERROR_ID                   = mkRuntimeErrorId patErrorIdKey                 FSLIT("patError")
+nO_METHOD_BINDING_ERROR_ID      = mkRuntimeErrorId noMethodBindingErrorIdKey    FSLIT("noMethodBindingError")
+
+-- The runtime error Ids take a UTF8-encoded string as argument
+mkRuntimeErrorId key name = pc_bottoming_Id key pREL_ERR name runtimeErrorTy
+runtimeErrorTy                   = mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy)
+\end{code}
+
+\begin{code}
+eRROR_ID = pc_bottoming_Id errorIdKey pREL_ERR FSLIT("error") errorTy
+
+errorTy  :: Type
+errorTy  = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy] openAlphaTy)
+    -- Notice the openAlphaTyVar.  It says that "error" can be applied
+    -- to unboxed as well as boxed types.  This is OK because it never
+    -- returns, so the return type is irrelevant.
 \end{code}
 
 
@@ -923,7 +969,7 @@ pAR_ERROR_ID
 %************************************************************************
 
 \begin{code}
-pcMiscPrelId :: Unique{-IdKey-} -> Module -> FAST_STRING -> Type -> IdInfo -> Id
+pcMiscPrelId :: Unique{-IdKey-} -> Module -> FastString -> Type -> IdInfo -> Id
 pcMiscPrelId key mod str ty info
   = let
        name = mkWiredInName mod (mkVarOcc str) key
@@ -939,21 +985,21 @@ pcMiscPrelId key mod str ty info
 pc_bottoming_Id key mod name ty
  = pcMiscPrelId key mod name ty bottoming_info
  where
-    strict_sig    = mkStrictSig (mkTopDmdType [evalDmd] BotRes)
-    bottoming_info = noCafNoTyGenIdInfo `setAllStrictnessInfo` Just strict_sig
-       -- these "bottom" out, no matter what their arguments
+    bottoming_info = hasCafIdInfo `setAllStrictnessInfo` Just strict_sig
+       -- Do *not* mark them as NoCafRefs, because they can indeed have
+       -- CAF refs.  For example, pAT_ERROR_ID calls GHC.Err.untangle,
+       -- which has some CAFs
+       -- In due course we may arrange that these error-y things are
+       -- regarded by the GC as permanently live, in which case we
+       -- can give them NoCaf info.  As it is, any function that calls
+       -- any pc_bottoming_Id will itself have CafRefs, which bloats
+       -- SRTs.
 
-generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy
+    strict_sig    = mkStrictSig (mkTopDmdType [evalDmd] BotRes)
+       -- These "bottom" out, no matter what their arguments
 
 (openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars
 openAlphaTy  = mkTyVarTy openAlphaTyVar
 openBetaTy   = mkTyVarTy openBetaTyVar
-
-errorTy  :: Type
-errorTy  = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy] 
-                                                   openAlphaTy)
-    -- Notice the openAlphaTyVar.  It says that "error" can be applied
-    -- to unboxed as well as boxed types.  This is OK because it never
-    -- returns, so the return type is irrelevant.
 \end{code}