[project @ 2005-02-25 13:06:31 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index 1ad85bc..50e981b 100644 (file)
@@ -16,7 +16,7 @@ module MkId (
        mkDictFunId, mkDefaultMethodId,
        mkDictSelId, 
 
        mkDictFunId, mkDefaultMethodId,
        mkDictSelId, 
 
-       mkDataConId, mkDataConWrapId,
+       mkDataConIds,
        mkRecordSelId, 
        mkPrimOpId, mkFCallId,
 
        mkRecordSelId, 
        mkPrimOpId, mkFCallId,
 
@@ -30,71 +30,65 @@ module MkId (
        mkRuntimeErrorApp,
        rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID,
        nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID,
        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
+       pAT_ERROR_ID, eRROR_ID
     ) where
 
 #include "HsVersions.h"
 
 
 import BasicTypes      ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict )
     ) where
 
 #include "HsVersions.h"
 
 
 import BasicTypes      ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict )
-import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, betaTyVar, betaTy,
-                         intPrimTy, realWorldStatePrimTy, addrPrimTy
+import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, 
+                         realWorldStatePrimTy, addrPrimTy
                        )
 import TysWiredIn      ( charTy, mkListTy )
 import PrelRules       ( primOpRules )
 import Rules           ( addRule )
                        )
 import TysWiredIn      ( charTy, mkListTy )
 import PrelRules       ( primOpRules )
 import Rules           ( addRule )
-import TcType          ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
-                         mkTyVarTys, mkClassPred, tcEqPred,
+import Type            ( TyThing(..) )
+import TcType          ( Type, ThetaType, mkDictTy, mkPredTys, mkPredTy, 
+                         mkTyConApp, mkTyVarTys, mkClassPred, tcEqPred,
                          mkFunTys, mkFunTy, mkSigmaTy, tcSplitSigmaTy, 
                          isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
                          mkFunTys, mkFunTy, mkSigmaTy, tcSplitSigmaTy, 
                          isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
-                         tcSplitFunTys, tcSplitForAllTys, mkPredTy
+                         tcSplitFunTys, tcSplitForAllTys
                        )
 import CoreUtils       ( exprType )
                        )
 import CoreUtils       ( exprType )
-import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
-import Literal         ( Literal(..), nullAddrLit )
+import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding )
+import Literal         ( nullAddrLit, mkStringLit )
 import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
 import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
-                          tyConTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon )
-import Class           ( Class, classTyCon, classTyVars, classSelIds )
+                          tyConStupidTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon )
+import Class           ( Class, classTyCon, classSelIds )
 import Var             ( Id, TyVar, Var )
 import VarSet          ( isEmptyVarSet )
 import Var             ( Id, TyVar, Var )
 import VarSet          ( isEmptyVarSet )
-import Name            ( mkFCallName, Name )
-import PrimOp          ( PrimOp(DataToTagOp), primOpSig, mkPrimOpIdName )
+import Name            ( mkFCallName, mkWiredInName, Name, BuiltInSyntax(..) )
+import OccName         ( mkOccFS, varName )
+import PrimOp          ( PrimOp, primOpSig, primOpOcc, primOpTag )
 import ForeignCall     ( ForeignCall )
 import ForeignCall     ( ForeignCall )
-import DataCon         ( DataCon, 
-                         dataConFieldLabels, dataConRepArity, dataConTyCon,
-                         dataConArgTys, dataConRepType, 
-                         dataConOrigArgTys,
-                          dataConName, dataConTheta,
-                         dataConSig, dataConStrictMarks, dataConWorkId,
-                         splitProductType
+import DataCon         ( DataCon, DataConIds(..), dataConTyVars,
+                         dataConFieldLabels, dataConRepArity, 
+                         dataConRepArgTys, dataConRepType, dataConStupidTheta, 
+                         dataConSig, dataConStrictMarks, dataConExStricts, 
+                         splitProductType, isVanillaDataCon
                        )
                        )
-import Id              ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal,
-                         mkTemplateLocals, mkTemplateLocalsNum,
-                         mkTemplateLocal, idNewStrictness, idName
+import Id              ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, 
+                         mkTemplateLocals, mkTemplateLocalsNum, mkExportedLocalId,
+                         mkTemplateLocal, idName
                        )
                        )
-import IdInfo          ( IdInfo, noCafIdInfo, hasCafIdInfo,
-                         setUnfoldingInfo, 
+import IdInfo          ( IdInfo, noCafIdInfo,  setUnfoldingInfo, 
                          setArityInfo, setSpecInfo, setCafInfo,
                          setArityInfo, setSpecInfo, setCafInfo,
-                         setAllStrictnessInfo,
+                         setAllStrictnessInfo, vanillaIdInfo,
                          GlobalIdDetails(..), CafInfo(..)
                        )
                          GlobalIdDetails(..), CafInfo(..)
                        )
-import NewDemand       ( mkStrictSig, strictSigResInfo, DmdResult(..),
+import NewDemand       ( mkStrictSig, DmdResult(..),
                          mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR,
                          Demand(..), Demands(..) )
                          mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR,
                          Demand(..), Demands(..) )
-import FieldLabel      ( mkFieldLabel, fieldLabelName, 
-                         firstFieldLabelTag, allFieldLabelTags, fieldLabelType
-                       )
 import DmdAnal         ( dmdAnalTopRhs )
 import CoreSyn
 import DmdAnal         ( dmdAnalTopRhs )
 import CoreSyn
-import Unique          ( mkBuiltinUnique )
+import Unique          ( mkBuiltinUnique, mkPrimOpIdUnique )
 import Maybes
 import PrelNames
 import Maybes
 import PrelNames
-import Maybe            ( isJust )
 import Util             ( dropList, isSingleton )
 import Outputable
 import FastString
 import ListSetOps      ( assoc, assocMaybe )
 import Util             ( dropList, isSingleton )
 import Outputable
 import FastString
 import ListSetOps      ( assoc, assocMaybe )
-import UnicodeUtil      ( stringToUtf8 )
 import List            ( nubBy )
 \end{code}             
 
 import List            ( nubBy )
 \end{code}             
 
@@ -138,7 +132,6 @@ ghcPrimIds
     realWorldPrimId,
     unsafeCoerceId,
     nullAddrId,
     realWorldPrimId,
     unsafeCoerceId,
     nullAddrId,
-    getTagId,
     seqId
     ]
 \end{code}
     seqId
     ]
 \end{code}
@@ -149,57 +142,6 @@ ghcPrimIds
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-\begin{code}
-mkDataConId :: Name -> DataCon -> Id
-       -- Makes the *worker* for the data constructor; that is, the function
-       -- that takes the reprsentation arguments and builds the constructor.
-mkDataConId work_name data_con
-  = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info
-  where
-    info = noCafIdInfo
-          `setArityInfo`               arity
-          `setAllStrictnessInfo`       Just strict_sig
-
-    arity      = dataConRepArity data_con
-
-    strict_sig = mkStrictSig (mkTopDmdType (replicate arity topDmd) cpr_info)
-       -- Notice that we do *not* say the worker is strict
-       -- even if the data constructor is declared strict
-       --      e.g.    data T = MkT !(Int,Int)
-       -- Why?  Because the *wrapper* is strict (and its unfolding has case
-       -- expresssions that do the evals) but the *worker* itself is not.
-       -- If we pretend it is strict then when we see
-       --      case x of y -> $wMkT y
-       -- the simplifier thinks that y is "sure to be evaluated" (because
-       -- $wMkT is strict) and drops the case.  No, $wMkT is not strict.
-       --
-       -- When the simplifer sees a pattern 
-       --      case e of MkT x -> ...
-       -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
-       -- but that's fine... dataConRepStrictness comes from the data con
-       -- not from the worker Id.
-
-    tycon = dataConTyCon data_con
-    cpr_info | isProductTyCon tycon && 
-              isDataTyCon tycon    &&
-              arity > 0            &&
-              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
-
-mAX_CPR_SIZE :: Arity
-mAX_CPR_SIZE = 10
--- We do not treat very big tuples as CPR-ish:
---     a) for a start we get into trouble because there aren't 
---        "enough" unboxed tuple types (a tiresome restriction, 
---        but hard to fix), 
---     b) more importantly, big unboxed tuples get returned mainly
---        on the stack, and are often then allocated in the heap
---        by the caller.  So doing CPR for them may in fact make
---        things worse.
-\end{code}
-
 The wrapper for a constructor is an ordinary top-level binding that evaluates
 any strict args, unboxes any args that are going to be flattened, and calls
 the worker.
 The wrapper for a constructor is an ordinary top-level binding that evaluates
 any strict args, unboxes any args that are going to be flattened, and calls
 the worker.
@@ -237,23 +179,95 @@ Notice that
   Making an explicit case expression allows the simplifier to eliminate
   it in the (common) case where the constructor arg is already evaluated.
 
   Making an explicit case expression allows the simplifier to eliminate
   it in the (common) case where the constructor arg is already evaluated.
 
+
 \begin{code}
 \begin{code}
-mkDataConWrapId data_con
-  = mkGlobalId (DataConWrapId data_con) (dataConName data_con) wrap_ty info
+mkDataConIds :: Name -> Name -> DataCon -> DataConIds
+       -- Makes the *worker* for the data constructor; that is, the function
+       -- that takes the reprsentation arguments and builds the constructor.
+mkDataConIds wrap_name wkr_name data_con
+  | isNewTyCon tycon
+  = NewDC nt_wrap_id
+
+  | any isMarkedStrict all_strict_marks                -- Algebraic, needs wrapper
+  = AlgDC (Just alg_wrap_id) wrk_id
+
+  | otherwise                                  -- Algebraic, no wrapper
+  = AlgDC Nothing wrk_id
   where
   where
-    work_id = dataConWorkId data_con
+    (tyvars, theta, orig_arg_tys, tycon, res_tys) = dataConSig data_con
 
 
-    info = noCafIdInfo
-          `setUnfoldingInfo`   wrap_unf
-               -- 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_sig = mkStrictSig (mkTopDmdType arg_dmds res_info)
-    res_info = strictSigResInfo (idNewStrictness work_id)
-    arg_dmds = map mk_dmd strict_marks
+    dict_tys    = mkPredTys theta
+    all_arg_tys = dict_tys ++ orig_arg_tys
+    result_ty   = mkTyConApp tycon res_tys
+
+    wrap_ty = mkForAllTys 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.
+
+       ----------- Worker (algebraic data types only) --------------
+    wrk_id = mkGlobalId (DataConWorkId data_con) wkr_name
+                       (dataConRepType data_con) wkr_info
+
+    wkr_arity = dataConRepArity data_con
+    wkr_info  = noCafIdInfo
+               `setArityInfo`          wkr_arity
+               `setAllStrictnessInfo`  Just wkr_sig
+               `setUnfoldingInfo`      evaldUnfolding  -- Record that it's evaluated,
+                                                       -- even if arity = 0
+
+    wkr_sig = mkStrictSig (mkTopDmdType (replicate wkr_arity topDmd) cpr_info)
+       -- Notice that we do *not* say the worker is strict
+       -- even if the data constructor is declared strict
+       --      e.g.    data T = MkT !(Int,Int)
+       -- Why?  Because the *wrapper* is strict (and its unfolding has case
+       -- expresssions that do the evals) but the *worker* itself is not.
+       -- If we pretend it is strict then when we see
+       --      case x of y -> $wMkT y
+       -- the simplifier thinks that y is "sure to be evaluated" (because
+       -- $wMkT is strict) and drops the case.  No, $wMkT is not strict.
+       --
+       -- When the simplifer sees a pattern 
+       --      case e of MkT x -> ...
+       -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
+       -- but that's fine... dataConRepStrictness comes from the data con
+       -- not from the worker Id.
+
+    cpr_info | isProductTyCon tycon && 
+              isDataTyCon tycon    &&
+              wkr_arity > 0        &&
+              wkr_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
+
+       ----------- Wrappers for newtypes --------------
+    nt_wrap_id   = mkGlobalId (DataConWrapId data_con) wrap_name wrap_ty nt_wrap_info
+    nt_wrap_info = noCafIdInfo         -- The NoCaf-ness is set by noCafIdInfo
+                 `setArityInfo` 1      -- Arity 1
+                 `setUnfoldingInfo`     newtype_unf
+    newtype_unf  = ASSERT( isVanillaDataCon data_con &&
+                          isSingleton orig_arg_tys )
+                  -- No existentials on a newtype, but it can have a context
+                  -- e.g.      newtype Eq a => T a = MkT (...)
+                  mkTopUnfolding $ Note InlineMe $
+                  mkLams tyvars $ Lam id_arg1 $ 
+                  mkNewTypeBody tycon result_ty (Var id_arg1)
+
+    id_arg1 = mkTemplateLocal 1 (head orig_arg_tys)
+
+       ----------- Wrappers for algebraic data types -------------- 
+    alg_wrap_id = mkGlobalId (DataConWrapId data_con) wrap_name wrap_ty alg_wrap_info
+    alg_wrap_info = noCafIdInfo                -- The NoCaf-ness is set by noCafIdInfo
+                   `setArityInfo`         alg_arity
+                       -- It's important to specify the arity, so that partial
+                       -- applications are treated as values
+                   `setUnfoldingInfo`     alg_unf
+                   `setAllStrictnessInfo` Just wrap_sig
+
+    all_strict_marks = dataConExStricts data_con ++ dataConStrictMarks data_con
+    wrap_sig = mkStrictSig (mkTopDmdType arg_dmds cpr_info)
+    arg_dmds = map mk_dmd all_strict_marks
     mk_dmd str | isMarkedStrict str = evalDmd
               | otherwise          = lazyDmd
        -- The Cpr info can be important inside INLINE rhss, where the
     mk_dmd str | isMarkedStrict str = evalDmd
               | otherwise          = lazyDmd
        -- The Cpr info can be important inside INLINE rhss, where the
@@ -265,65 +279,19 @@ mkDataConWrapId data_con
        --      ...(let w = C x in ...(w p q)...)...
        -- we want to see that w is strict in its two arguments
 
        --      ...(let w = C x in ...(w p q)...)...
        -- we want to see that w is strict in its two arguments
 
-    wrap_unf | isNewTyCon tycon
-            = ASSERT( null ex_tyvars && null ex_dict_args && isSingleton orig_arg_tys )
-               -- No existentials on a newtype, but it can have a context
-               -- e.g.         newtype Eq a => T a = MkT (...)
-               mkTopUnfolding $ Note InlineMe $
-               mkLams tyvars $ Lam id_arg1 $ 
-               mkNewTypeBody tycon result_ty (Var id_arg1)
-
-            | 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
-                       -- by the worker even when there are no args.
-                       --              f (:) x
-                       -- becomes 
-                       --              f $w: x
-                       -- This is really important in rule matching,
-                       -- (We could match on the wrappers,
-                       -- but that makes it less likely that rules will match
-                       -- when we bring bits of unfoldings together.)
-               --
-               -- NB:  because of this special case, (map (:) ys) turns into
-               --      (map $w: ys).  The top-level defn for (:) is never used.
-               --      This is somewhat of a bore, but I'm currently leaving it 
-               --      as is, so that there still is a top level curried (:) for
-               --      the interpreter to call.
-
-            | otherwise
-            = mkTopUnfolding $ Note InlineMe $
-              mkLams all_tyvars $ 
-              mkLams ex_dict_args $ mkLams id_args $
-              foldr mk_case con_app 
-                    (zip (ex_dict_args++id_args) strict_marks) i3 []
-
-    con_app i rep_ids = mkApps (Var work_id)
-                              (map varToCoreExpr (all_tyvars ++ reverse rep_ids))
-
-    (tyvars, _, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con
-    all_tyvars   = tyvars ++ ex_tyvars
-
-    ex_dict_tys  = mkPredTys ex_theta
-    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
+    alg_unf = mkTopUnfolding $ Note InlineMe $
+             mkLams tyvars $ 
+             mkLams dict_args $ mkLams id_args $
+             foldr mk_case con_app 
+                   (zip (dict_args ++ id_args) all_strict_marks)
+                   i3 []
 
 
-    (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
+    con_app i rep_ids = mkApps (Var wrk_id)
+                              (map varToCoreExpr (tyvars ++ reverse rep_ids))
 
 
-    strict_marks  = dataConStrictMarks data_con
+    (dict_args,i2) = mkLocals 1  dict_tys
+    (id_args,i3)   = mkLocals i2 orig_arg_tys
+    alg_arity     = i3-1
 
     mk_case 
           :: (Id, StrictnessMark)      -- Arg, strictness
 
     mk_case 
           :: (Id, StrictnessMark)      -- Arg, strictness
@@ -337,15 +305,32 @@ mkDataConWrapId data_con
                MarkedStrict 
                   | isUnLiftedType (idType arg) -> body i (arg:rep_args)
                   | otherwise ->
                MarkedStrict 
                   | isUnLiftedType (idType arg) -> body i (arg:rep_args)
                   | otherwise ->
-                       Case (Var arg) arg [(DEFAULT,[], body i (arg:rep_args))]
+                       Case (Var arg) arg result_ty [(DEFAULT,[], body i (arg:rep_args))]
 
                MarkedUnboxed
                   -> case splitProductType "do_unbox" (idType arg) of
                           (tycon, tycon_args, con, tys) ->
 
                MarkedUnboxed
                   -> case splitProductType "do_unbox" (idType arg) of
                           (tycon, tycon_args, con, tys) ->
-                                  Case (Var arg) arg [(DataAlt con, con_args,
-                                       body i' (reverse con_args ++ rep_args))]
+                                  Case (Var arg) arg result_ty  
+                                       [(DataAlt con, 
+                                         con_args,
+                                         body i' (reverse con_args ++ rep_args))]
                              where 
                                (con_args, i') = mkLocals i tys
                              where 
                                (con_args, i') = mkLocals i tys
+
+mAX_CPR_SIZE :: Arity
+mAX_CPR_SIZE = 10
+-- We do not treat very big tuples as CPR-ish:
+--     a) for a start we get into trouble because there aren't 
+--        "enough" unboxed tuple types (a tiresome restriction, 
+--        but hard to fix), 
+--     b) more importantly, big unboxed tuples get returned mainly
+--        on the stack, and are often then allocated in the heap
+--        by the caller.  So doing CPR for them may in fact make
+--        things worse.
+
+mkLocals i tys = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n)
+              where
+                n = length tys
 \end{code}
 
 
 \end{code}
 
 
@@ -394,15 +379,11 @@ Similarly for (recursive) newtypes
        unN = /\b -> \n:N -> (coerce (forall a. a->a) n)
 
 \begin{code}
        unN = /\b -> \n:N -> (coerce (forall a. a->a) n)
 
 \begin{code}
-mkRecordSelId tycon field_label
+mkRecordSelId tycon field_label field_ty
        -- Assumes that all fields with the same field label have the same type
        -- Assumes that all fields with the same field label have the same type
-       --
-       -- Annoyingly, we have to pass in the unpackCString# Id, because
-       -- we can't conjure it up out of thin air
   = sel_id
   where
   = sel_id
   where
-    sel_id     = mkGlobalId (RecordSelId field_label) (fieldLabelName field_label) selector_ty info
-    field_ty   = fieldLabelType field_label
+    sel_id     = mkGlobalId (RecordSelId tycon field_label) field_label selector_ty info
     data_cons  = tyConDataCons tycon
     tyvars     = tyConTyVars tycon     -- These scope over the types in 
                                        -- the FieldLabels of constructors of this type
     data_cons  = tyConDataCons tycon
     tyvars     = tyConTyVars tycon     -- These scope over the types in 
                                        -- the FieldLabels of constructors of this type
@@ -420,14 +401,12 @@ mkRecordSelId tycon field_label
        --
        -- NB: this code relies on the fact that DataCons are quantified over
        -- the identical type variables as their parent TyCon
        --
        -- 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 = ...
-    needed_preds = [pred | (DataAlt dc, _, _) <- the_alts, pred <- dataConTheta dc]
-    dict_tys     = map mkPredTy (nubBy tcEqPred needed_preds)
+    needed_preds = [pred | (DataAlt dc, _, _) <- the_alts, pred <- dataConStupidTheta dc]
+    dict_tys     = mkPredTys (nubBy tcEqPred needed_preds)
     n_dict_tys   = length dict_tys
 
     (field_tyvars,field_theta,field_tau) = tcSplitSigmaTy field_ty
     n_dict_tys   = length dict_tys
 
     (field_tyvars,field_theta,field_tau) = tcSplitSigmaTy field_ty
-    field_dict_tys                      = map mkPredTy field_theta
+    field_dict_tys                      = mkPredTys field_theta
     n_field_dict_tys                    = length field_dict_tys
        -- If the field has a universally quantified type we have to 
        -- be a bit careful.  Suppose we have
     n_field_dict_tys                    = length field_dict_tys
        -- If the field has a universally quantified type we have to 
        -- be a bit careful.  Suppose we have
@@ -462,19 +441,20 @@ mkRecordSelId tycon field_label
           `setAllStrictnessInfo` Just strict_sig
 
        -- Allocate Ids.  We do it a funny way round because field_dict_tys is
           `setAllStrictnessInfo` Just strict_sig
 
        -- Allocate Ids.  We do it a funny way round because field_dict_tys is
-       -- almost always empty.  Also note that we use length_tycon_theta
+       -- almost always empty.  Also note that we use max_dict_tys
        -- rather than n_dict_tys, because the latter gives an infinite loop:
        -- n_dict tys depends on the_alts, which depens on arg_ids, which depends
        -- on arity, which depends on n_dict tys.  Sigh!  Mega sigh!
        -- rather than n_dict_tys, because the latter gives an infinite loop:
        -- n_dict tys depends on the_alts, which depens on arg_ids, which depends
        -- on arity, which depends on n_dict tys.  Sigh!  Mega sigh!
-    field_dict_base    = length tycon_theta + 1
-    dict_id_base       = field_dict_base + n_field_dict_tys
-    field_base        = dict_id_base + 1
-    dict_ids          = mkTemplateLocalsNum  1               dict_tys
-    field_dict_ids     = mkTemplateLocalsNum  field_dict_base field_dict_tys
-    data_id           = mkTemplateLocal      dict_id_base    data_ty
+    dict_ids       = mkTemplateLocalsNum  1               dict_tys
+    max_dict_tys    = length (tyConStupidTheta tycon)
+    field_dict_base = max_dict_tys + 1
+    field_dict_ids  = mkTemplateLocalsNum  field_dict_base field_dict_tys
+    dict_id_base    = field_dict_base + n_field_dict_tys
+    data_id        = mkTemplateLocal      dict_id_base    data_ty
+    arg_base       = dict_id_base + 1
 
     alts      = map mk_maybe_alt data_cons
 
     alts      = map mk_maybe_alt data_cons
-    the_alts  = catMaybes alts
+    the_alts  = catMaybes alts         -- Already sorted by data-con
 
     no_default = all isJust alts       -- No default needed
     default_alt | no_default = []
 
     no_default = all isJust alts       -- No default needed
     default_alt | no_default = []
@@ -489,7 +469,7 @@ mkRecordSelId tycon field_label
              Lam data_id     $ sel_body
 
     sel_body | isNewTyCon tycon = mk_result (mkNewTypeBody tycon field_ty (Var data_id))
              Lam data_id     $ sel_body
 
     sel_body | isNewTyCon tycon = mk_result (mkNewTypeBody tycon field_ty (Var data_id))
-            | otherwise        = Case (Var data_id) data_id (default_alt ++ the_alts)
+            | otherwise        = Case (Var data_id) data_id field_tau (default_alt ++ the_alts)
 
     mk_result poly_result = mkVarApps (mkVarApps poly_result field_tyvars) field_dict_ids
        -- We pull the field lambdas to the top, so we need to 
 
     mk_result poly_result = mkVarApps (mkVarApps poly_result field_tyvars) field_dict_ids
        -- We pull the field lambdas to the top, so we need to 
@@ -500,20 +480,28 @@ mkRecordSelId tycon field_label
        --      foo = /\a. \t:T. case t of { MkT f -> f a }
 
     mk_maybe_alt data_con 
        --      foo = /\a. \t:T. case t of { MkT f -> f a }
 
     mk_maybe_alt data_con 
-       = case maybe_the_arg_id of
+       = ASSERT( dc_tyvars == tyvars )
+               -- The only non-vanilla case we allow is when we have an existential
+               -- context that binds no type variables, thus
+               --      data T a = (?v::Int) => MkT a
+               -- In the non-vanilla case, the pattern must bind type variables and
+               -- the context stuff; hence the arg_prefix binding below
+
+         case maybe_the_arg_id of
                Nothing         -> Nothing
                Nothing         -> Nothing
-               Just the_arg_id -> Just (mkReboxingAlt uniqs data_con arg_ids body)
-                               where
-                                  body = mk_result (Var the_arg_id)
+               Just the_arg_id -> Just (mkReboxingAlt uniqs data_con (arg_prefix ++ arg_src_ids) $
+                                        mk_result (Var the_arg_id))
        where
        where
-            arg_ids = mkTemplateLocalsNum field_base (dataConOrigArgTys data_con)
-                       -- No need to instantiate; same tyvars in datacon as tycon
+           (dc_tyvars, dc_theta, dc_arg_tys, _, _) = dataConSig data_con
+           arg_src_ids = mkTemplateLocalsNum arg_base dc_arg_tys
+           arg_base'   = arg_base + length arg_src_ids
+           arg_prefix  | isVanillaDataCon data_con = []
+                       | otherwise = tyvars ++ mkTemplateLocalsNum arg_base' (mkPredTys dc_theta)
 
 
-           unpack_base = field_base + length arg_ids
+           unpack_base = arg_base' + length dc_theta
            uniqs = map mkBuiltinUnique [unpack_base..]
 
            uniqs = map mkBuiltinUnique [unpack_base..]
 
-                               -- arity+1 avoids all shadowing
-           maybe_the_arg_id  = assocMaybe (field_lbls `zip` arg_ids) field_label
+           maybe_the_arg_id  = assocMaybe (field_lbls `zip` arg_src_ids) field_label
            field_lbls        = dataConFieldLabels data_con
 
     error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_tau full_msg
            field_lbls        = dataConFieldLabels data_con
 
     error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_tau full_msg
@@ -536,7 +524,7 @@ mkRecordSelId tycon field_label
 mkReboxingAlt
   :: [Unique]                  -- Uniques for the new Ids
   -> DataCon
 mkReboxingAlt
   :: [Unique]                  -- Uniques for the new Ids
   -> DataCon
-  -> [Var]                     -- Source-level args
+  -> [Var]                     -- Source-level args, including existential dicts
   -> CoreExpr                  -- RHS
   -> CoreAlt
 
   -> CoreExpr                  -- RHS
   -> CoreAlt
 
@@ -551,7 +539,7 @@ mkReboxingAlt us con args rhs
     (DataAlt con, args', mkLets binds rhs)
 
   where
     (DataAlt con, args', mkLets binds rhs)
 
   where
-    stricts = dataConStrictMarks con
+    stricts = dataConExStricts con ++ dataConStrictMarks con
 
     go [] stricts us = ([], [])
 
 
     go [] stricts us = ([], [])
 
@@ -589,12 +577,25 @@ mkReboxingAlt us con args rhs
 Selecting a field for a dictionary.  If there is just one field, then
 there's nothing to do.  
 
 Selecting a field for a dictionary.  If there is just one field, then
 there's nothing to do.  
 
-ToDo: unify with mkRecordSelId.
+Dictionary selectors may get nested forall-types.  Thus:
+
+       class Foo a where
+         op :: forall b. Ord b => a -> b -> b
+
+Then the top-level type for op is
+
+       op :: forall a. Foo a => 
+             forall b. Ord b => 
+             a -> b -> b
+
+This is unlike ordinary record selectors, which have all the for-alls
+at the outside.  When dealing with classes it's very convenient to
+recover the original type signature from the class op selector.
 
 \begin{code}
 mkDictSelId :: Name -> Class -> Id
 mkDictSelId name clas
 
 \begin{code}
 mkDictSelId :: Name -> Class -> Id
 mkDictSelId name clas
-  = mkGlobalId (RecordSelId field_lbl) name sel_ty info
+  = mkGlobalId (ClassOpId clas) name sel_ty info
   where
     sel_ty = mkForAllTys tyvars (mkFunTy (idType dict_id) (idType the_arg_id))
        -- We can't just say (exprType rhs), because that would give a type
   where
     sel_ty = mkForAllTys tyvars (mkFunTy (idType dict_id) (idType the_arg_id))
        -- We can't just say (exprType rhs), because that would give a type
@@ -603,10 +604,7 @@ mkDictSelId name clas
        -- But it's type must expose the representation of the dictionary
        -- to gat (say)         C a -> (a -> a)
 
        -- But it's type must expose the representation of the dictionary
        -- to gat (say)         C a -> (a -> a)
 
-    field_lbl = mkFieldLabel name tycon sel_ty tag
-    tag       = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` allFieldLabelTags) name
-
-    info      = noCafIdInfo
+    info = noCafIdInfo
                `setArityInfo`          1
                `setUnfoldingInfo`      mkTopUnfolding rhs
                `setAllStrictnessInfo`  Just strict_sig
                `setArityInfo`          1
                `setUnfoldingInfo`      mkTopUnfolding rhs
                `setAllStrictnessInfo`  Just strict_sig
@@ -623,21 +621,19 @@ mkDictSelId name clas
            | otherwise        = Eval (Prod [ if the_arg_id == id then evalDmd else Abs
                                            | id <- arg_ids ])
 
            | otherwise        = Eval (Prod [ if the_arg_id == id then evalDmd else Abs
                                            | id <- arg_ids ])
 
-    tyvars  = classTyVars clas
-
     tycon      = classTyCon clas
     [data_con] = tyConDataCons tycon
     tycon      = classTyCon clas
     [data_con] = tyConDataCons tycon
-    tyvar_tys  = mkTyVarTys tyvars
-    arg_tys    = dataConArgTys data_con tyvar_tys
-    the_arg_id = arg_ids !! (tag - firstFieldLabelTag)
+    tyvars     = dataConTyVars data_con
+    arg_tys    = dataConRepArgTys data_con
+    the_arg_id = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` arg_ids) name
 
 
-    pred             = mkClassPred clas tyvar_tys
+    pred             = mkClassPred clas (mkTyVarTys tyvars)
     (dict_id:arg_ids) = mkTemplateLocals (mkPredTy pred : arg_tys)
 
     rhs | isNewTyCon tycon = mkLams tyvars $ Lam dict_id $ 
                             mkNewTypeBody tycon (head arg_tys) (Var dict_id)
        | otherwise        = mkLams tyvars $ Lam dict_id $
     (dict_id:arg_ids) = mkTemplateLocals (mkPredTy pred : arg_tys)
 
     rhs | isNewTyCon tycon = mkLams tyvars $ Lam dict_id $ 
                             mkNewTypeBody tycon (head arg_tys) (Var dict_id)
        | otherwise        = mkLams tyvars $ Lam dict_id $
-                            Case (Var dict_id) dict_id
+                            Case (Var dict_id) dict_id (idType the_arg_id)
                                  [(DataAlt data_con, arg_ids, Var the_arg_id)]
 
 mkNewTypeBody tycon result_ty result_expr
                                  [(DataAlt data_con, arg_ids, Var the_arg_id)]
 
 mkNewTypeBody tycon result_ty result_expr
@@ -663,7 +659,9 @@ mkPrimOpId prim_op
   where
     (tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op
     ty   = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
   where
     (tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op
     ty   = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
-    name = mkPrimOpIdName prim_op
+    name = mkWiredInName gHC_PRIM (primOpOcc prim_op) 
+                        (mkPrimOpIdUnique (primOpTag prim_op))
+                        Nothing (AnId id) UserSyntax
     id   = mkGlobalId (PrimOpId prim_op) name ty info
                
     info = noCafIdInfo
     id   = mkGlobalId (PrimOpId prim_op) name ty info
                
     info = noCafIdInfo
@@ -736,11 +734,11 @@ It's OK for dfuns to be LocalIds, because we form the instance-env to
 pass on to the next module (md_insts) in CoreTidy, afer tidying
 and globalising the top-level Ids.
 
 pass on to the next module (md_insts) in CoreTidy, afer tidying
 and globalising the top-level Ids.
 
-BUT make sure they are *exported* LocalIds (setIdLocalExported) so 
+BUT make sure they are *exported* LocalIds (mkExportedLocalId) so 
 that they aren't discarded by the occurrence analyser.
 
 \begin{code}
 that they aren't discarded by the occurrence analyser.
 
 \begin{code}
-mkDefaultMethodId dm_name ty = mkVanillaGlobal dm_name ty noCafIdInfo
+mkDefaultMethodId dm_name ty = mkExportedLocalId dm_name ty
 
 mkDictFunId :: Name            -- Name to use for the dict fun;
            -> [TyVar]
 
 mkDictFunId :: Name            -- Name to use for the dict fun;
            -> [TyVar]
@@ -750,7 +748,7 @@ mkDictFunId :: Name         -- Name to use for the dict fun;
            -> Id
 
 mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys
            -> Id
 
 mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys
-  = mkVanillaGlobal dfun_name dfun_ty noCafIdInfo
+  = mkExportedLocalId dfun_name dfun_ty
   where
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
 
   where
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
 
@@ -760,7 +758,7 @@ mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys
 
     (class_tyvars, sc_theta, _, _) = classBigSig clas
     not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
 
     (class_tyvars, sc_theta, _, _) = classBigSig clas
     not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
-    sc_theta' = substClasses (mkTopTyVarSubst class_tyvars inst_tys) sc_theta
+    sc_theta' = substClasses (zipTopTvSubst class_tyvars inst_tys) sc_theta
     dfun_theta = case inst_decl_theta of
                   []    -> []  -- If inst_decl_theta is empty, then we don't
                                -- want to have any dict arguments, so that we can
     dfun_theta = case inst_decl_theta of
                   []    -> []  -- If inst_decl_theta is empty, then we don't
                                -- want to have any dict arguments, so that we can
@@ -806,6 +804,29 @@ they can unify with both unlifted and lifted types.  Hence we provide
 another gun with which to shoot yourself in the foot.
 
 \begin{code}
 another gun with which to shoot yourself in the foot.
 
 \begin{code}
+mkWiredInIdName mod fs uniq id
+ = mkWiredInName mod (mkOccFS varName fs) uniq Nothing (AnId id) UserSyntax
+
+unsafeCoerceName = mkWiredInIdName gHC_PRIM FSLIT("unsafeCoerce#") unsafeCoerceIdKey  unsafeCoerceId
+nullAddrName     = mkWiredInIdName gHC_PRIM FSLIT("nullAddr#")    nullAddrIdKey      nullAddrId
+seqName                 = mkWiredInIdName gHC_PRIM FSLIT("seq")           seqIdKey           seqId
+realWorldName   = mkWiredInIdName gHC_PRIM FSLIT("realWorld#")    realWorldPrimIdKey realWorldPrimId
+lazyIdName      = mkWiredInIdName pREL_BASE FSLIT("lazy")         lazyIdKey          lazyId
+
+errorName               = mkWiredInIdName pREL_ERR FSLIT("error")           errorIdKey eRROR_ID
+recSelErrorName                 = mkWiredInIdName pREL_ERR FSLIT("recSelError")     recSelErrorIdKey rEC_SEL_ERROR_ID
+runtimeErrorName        = mkWiredInIdName pREL_ERR FSLIT("runtimeError")    runtimeErrorIdKey rUNTIME_ERROR_ID
+irrefutPatErrorName     = mkWiredInIdName pREL_ERR FSLIT("irrefutPatError") irrefutPatErrorIdKey iRREFUT_PAT_ERROR_ID
+recConErrorName                 = mkWiredInIdName pREL_ERR FSLIT("recConError")     recConErrorIdKey rEC_CON_ERROR_ID
+patErrorName            = mkWiredInIdName pREL_ERR FSLIT("patError")        patErrorIdKey pAT_ERROR_ID
+noMethodBindingErrorName = mkWiredInIdName pREL_ERR FSLIT("noMethodBindingError")
+                                          noMethodBindingErrorIdKey nO_METHOD_BINDING_ERROR_ID
+nonExhaustiveGuardsErrorName 
+  = mkWiredInIdName pREL_ERR FSLIT("nonExhaustiveGuardsError") 
+                   nonExhaustiveGuardsErrorIdKey nON_EXHAUSTIVE_GUARDS_ERROR_ID
+\end{code}
+
+\begin{code}
 -- unsafeCoerce# :: forall a b. a -> b
 unsafeCoerceId
   = pcMiscPrelId unsafeCoerceName ty info
 -- unsafeCoerce# :: forall a b. a -> b
 unsafeCoerceId
   = pcMiscPrelId unsafeCoerceName ty info
@@ -834,10 +855,11 @@ seqId
     info = noCafIdInfo `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)])
+    ty  = mkForAllTys [alphaTyVar,openBetaTyVar]
+                     (mkFunTy alphaTy (mkFunTy openBetaTy openBetaTy))
+    [x,y] = mkTemplateLocals [alphaTy, openBetaTy]
+-- gaw 2004
+    rhs = mkLams [alphaTyVar,openBetaTyVar,x,y] (Case (Var x) x openBetaTy [(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
 
 -- lazy :: forall a?. a? -> a?  (i.e. works for unboxed types too)
 -- Used to lazify pseq:                pseq a b = a `seq` lazy b
@@ -857,24 +879,6 @@ lazyIdUnfolding = mkLams [openAlphaTyVar,x] (Var x)
                  [x] = mkTemplateLocals [openAlphaTy]
 \end{code}
 
                  [x] = mkTemplateLocals [openAlphaTy]
 \end{code}
 
-@getTag#@ is another function which can't be defined in Haskell.  It needs to
-evaluate its argument and call the dataToTag# primitive.
-
-\begin{code}
-getTagId
-  = pcMiscPrelId getTagName ty info
-  where
-    info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
-       -- We don't provide a defn for this; you must inline it
-
-    ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy)
-    [x,y] = mkTemplateLocals [alphaTy,alphaTy]
-    rhs = mkLams [alphaTyVar,x] $
-         Case (Var x) y [ (DEFAULT, [], mkApps (Var dataToTagId) [Type alphaTy, Var y]) ]
-
-dataToTagId = mkPrimOpId DataToTagOp
-\end{code}
-
 @realWorld#@ used to be a magic literal, \tr{void#}.  If things get
 nasty as-is, change it back to a literal (@Literal@).
 
 @realWorld#@ used to be a magic literal, \tr{void#}.  If things get
 nasty as-is, change it back to a literal (@Literal@).
 
@@ -888,8 +892,8 @@ This comes up in strictness analysis
 \begin{code}
 realWorldPrimId        -- :: State# RealWorld
   = pcMiscPrelId realWorldName realWorldStatePrimTy
 \begin{code}
 realWorldPrimId        -- :: State# RealWorld
   = pcMiscPrelId realWorldName realWorldStatePrimTy
-                (noCafIdInfo `setUnfoldingInfo` mkOtherCon [])
-       -- The mkOtherCon makes it look that realWorld# is evaluated
+                (noCafIdInfo `setUnfoldingInfo` evaldUnfolding)
+       -- The evaldUnfolding 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
        -- which in turn makes Simplify.interestingArg return True,
        -- which in turn makes INLINE things applied to realWorld# likely
        -- to be inlined
@@ -931,15 +935,15 @@ mkRuntimeErrorApp
 mkRuntimeErrorApp err_id res_ty err_msg 
   = mkApps (Var err_id) [Type res_ty, err_string]
   where
 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)))
+    err_string = Lit (mkStringLit err_msg)
 
 rEC_SEL_ERROR_ID               = mkRuntimeErrorId recSelErrorName
 rUNTIME_ERROR_ID               = mkRuntimeErrorId runtimeErrorName
 iRREFUT_PAT_ERROR_ID           = mkRuntimeErrorId irrefutPatErrorName
 rEC_CON_ERROR_ID               = mkRuntimeErrorId recConErrorName
 
 rEC_SEL_ERROR_ID               = mkRuntimeErrorId recSelErrorName
 rUNTIME_ERROR_ID               = mkRuntimeErrorId runtimeErrorName
 iRREFUT_PAT_ERROR_ID           = mkRuntimeErrorId irrefutPatErrorName
 rEC_CON_ERROR_ID               = mkRuntimeErrorId recConErrorName
-nON_EXHAUSTIVE_GUARDS_ERROR_ID = mkRuntimeErrorId nonExhaustiveGuardsErrorName
 pAT_ERROR_ID                   = mkRuntimeErrorId patErrorName
 nO_METHOD_BINDING_ERROR_ID      = mkRuntimeErrorId noMethodBindingErrorName
 pAT_ERROR_ID                   = mkRuntimeErrorId patErrorName
 nO_METHOD_BINDING_ERROR_ID      = mkRuntimeErrorId noMethodBindingErrorName
+nON_EXHAUSTIVE_GUARDS_ERROR_ID = mkRuntimeErrorId nonExhaustiveGuardsErrorName
 
 -- The runtime error Ids take a UTF8-encoded string as argument
 mkRuntimeErrorId name = pc_bottoming_Id name runtimeErrorTy
 
 -- The runtime error Ids take a UTF8-encoded string as argument
 mkRuntimeErrorId name = pc_bottoming_Id name runtimeErrorTy
@@ -976,7 +980,7 @@ pcMiscPrelId name ty info
 pc_bottoming_Id name ty
  = pcMiscPrelId name ty bottoming_info
  where
 pc_bottoming_Id name ty
  = pcMiscPrelId name ty bottoming_info
  where
-    bottoming_info = hasCafIdInfo `setAllStrictnessInfo` Just strict_sig
+    bottoming_info = vanillaIdInfo `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
        -- 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