[project @ 2000-12-19 08:36:34 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index 1f29b86..45f4f00 100644 (file)
@@ -41,22 +41,22 @@ import PrelNames    ( pREL_ERR, pREL_GHC )
 import PrelRules       ( primOpRule )
 import Rules           ( addRule )
 import Type            ( Type, ThetaType, mkDictTy, mkDictTys, mkTyConApp, mkTyVarTys,
-                         mkFunTys, mkFunTy, mkSigmaTy,
+                         mkFunTys, mkFunTy, mkSigmaTy, splitSigmaTy, 
                          isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
-                         splitFunTys, splitForAllTys
+                         splitFunTys, splitForAllTys, mkPredTy
                        )
 import Module          ( Module )
 import CoreUtils       ( exprType, mkInlineMe )
 import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
 import Literal         ( Literal(..) )
 import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
-                          tyConTheta, isProductTyCon, isUnboxedTupleTyCon )
+                          tyConTheta, isProductTyCon, isDataTyCon )
 import Class           ( Class, classTyCon, classTyVars, classSelIds )
 import Var             ( Id, TyVar )
 import VarSet          ( isEmptyVarSet )
-import Name            ( mkDerivedName, mkWiredInName, mkLocalName, 
+import Name            ( mkWiredInName, mkLocalName, 
                          mkWorkerOcc, mkCCallName,
-                         Name, NamedThing(..),
+                         Name, NamedThing(..), getSrcLoc
                        )
 import OccName         ( mkVarOcc )
 import PrimOp          ( PrimOp(DataToTagOp, CCallOp), 
@@ -73,10 +73,10 @@ import DataCon              ( DataCon, StrictnessMark(..),
                          maybeMarkedUnboxed, splitProductType_maybe
                        )
 import Id              ( idType, mkId,
-                         mkVanillaId, mkTemplateLocals,
+                         mkVanillaId, mkTemplateLocals, mkTemplateLocalsNum,
                          mkTemplateLocal, idCprInfo
                        )
-import IdInfo          ( IdInfo, vanillaIdInfo, mkIdInfo,
+import IdInfo          ( IdInfo, constantIdInfo, mkIdInfo,
                          exactArity, setUnfoldingInfo, setCafInfo, setCprInfo,
                          setArityInfo, setSpecInfo, setTyGenInfo,
                          mkStrictnessInfo, setStrictnessInfo,
@@ -138,18 +138,22 @@ wiredInIds
 
 \begin{code}
 mkSpecPragmaId occ uniq ty loc
-  = mkId (mkLocalName uniq occ loc) ty (mkIdInfo SpecPragmaId)
+  = mkId (mkLocalName uniq occ loc) ty (mkIdInfo SpecPragmaId NoCafRefs)
        -- Maybe a SysLocal?  But then we'd lose the location
 
 mkDefaultMethodId dm_name rec_c ty
   = mkId dm_name ty info
   where
-    info = vanillaIdInfo `setTyGenInfo` TyGenNever
+    info = constantIdInfo `setTyGenInfo` TyGenNever
              -- type is wired-in (see comment at TcClassDcl.tcClassSig), so
              -- do not generalise it
 
+mkWorkerId :: Unique -> Id -> Type -> Id
+-- A worker gets a local name.  CoreTidy will globalise it if necessary.
 mkWorkerId uniq unwrkr ty
-  = mkVanillaId (mkDerivedName mkWorkerOcc (getName unwrkr) uniq) ty
+  = mkVanillaId wkr_name ty
+  where
+    wkr_name = mkLocalName uniq (mkWorkerOcc (getOccName unwrkr)) (getSrcLoc unwrkr)
 \end{code}
 
 %************************************************************************
@@ -165,7 +169,7 @@ mkDataConId :: Name -> DataCon -> Id
 mkDataConId work_name data_con
   = mkId work_name (dataConRepType data_con) info
   where
-    info = mkIdInfo (DataConId data_con)
+    info = mkIdInfo (DataConId data_con) NoCafRefs
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
           `setCprInfo`         cpr_info
@@ -174,20 +178,13 @@ mkDataConId work_name data_con
 
     strict_info = mkStrictnessInfo (dataConRepStrictness data_con, False)
 
+    tycon = dataConTyCon data_con
     cpr_info | isProductTyCon tycon && 
-              not (isUnboxedTupleTyCon tycon) && 
-              arity > 0                        = ReturnsCPR
-            | otherwise                        = NoCPRInfo
-            where
-               tycon = dataConTyCon data_con
-               -- Newtypes don't have a worker at all
-               -- 
-               -- If we are a product with 0 args we must be void(like)
-               -- We can't create an unboxed tuple with 0 args for this
-               -- and since Void has only one, constant value it should 
-               -- just mean returning a pointer to a pre-existing cell. 
-               -- So we won't really gain from doing anything fancy
-               -- and we treat this case as Top.
+              isDataTyCon tycon    &&
+              arity > 0                = ReturnsCPR
+            | otherwise                = NoCPRInfo
+       -- ReturnsCPR is only true for products that are real data types;
+       -- that is, not unboxed tuples or newtypes
 \end{code}
 
 The wrapper for a constructor is an ordinary top-level binding that evaluates
@@ -234,7 +231,7 @@ mkDataConWrapId data_con
     wrap_id = mkId (dataConName data_con) wrap_ty info
     work_id = dataConId data_con
 
-    info = mkIdInfo (DataConWrapId data_con)
+    info = mkIdInfo (DataConWrapId data_con) NoCafRefs
           `setUnfoldingInfo`   mkTopUnfolding (mkInlineMe wrap_rhs)
           `setCprInfo`         cpr_info
                -- The Cpr info can be important inside INLINE rhss, where the
@@ -242,10 +239,6 @@ mkDataConWrapId data_con
           `setArityInfo`       exactArity arity
                -- It's important to specify the arity, so that partial
                -- applications are treated as values
-          `setCafInfo`       NoCafRefs
-               -- The wrapper Id ends up in STG code as an argument,
-               -- sometimes before its definition, so we want to
-               -- signal that it has no CAFs
            `setTyGenInfo`     TyGenNever
                 -- No point generalising its type, since it gets eagerly inlined
                 -- away anyway
@@ -395,45 +388,69 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
     data_cons  = tyConDataCons tycon
     tyvars     = tyConTyVars tycon     -- These scope over the types in 
                                        -- the FieldLabels of constructors of this type
-    tycon_theta        = tyConTheta tycon      -- The context on the data decl
-                                       --   eg data (Eq a, Ord b) => T a b = ...
-    (field_tyvars,field_tau) = splitForAllTys field_ty
-
     data_ty   = mkTyConApp tycon tyvar_tys
     tyvar_tys = mkTyVarTys tyvars
 
+    tycon_theta        = tyConTheta tycon      -- The context on the data decl
+                                       --   eg data (Eq a, Ord b) => T a b = ...
+    dict_tys  = [mkDictTy cls tys | (cls, tys) <- tycon_theta, 
+                                   needed_dict (cls, tys)]
+    needed_dict pred = or [ pred `elem` (dataConTheta dc) 
+                         | (DataAlt dc, _, _) <- the_alts]
+    n_dict_tys = length dict_tys
+
+    (field_tyvars,field_theta,field_tau) = splitSigmaTy field_ty
+    field_dict_tys                      = map mkPredTy 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
+       --      data R = R { op :: forall a => Foo a => a -> a }
+       -- Then we can't give op the type
+       --      op :: R -> forall a. Foo a => a -> a
+       -- because the typechecker doesn't understand foralls to the
+       -- right of an arrow.  The "right" type to give it is
+       --      op :: forall a. Foo a => a -> a
+       -- But then we must generat the right unfolding too:
+       --      op = /\a -> \dfoo -> \ r ->
+       --           case r of
+       --              R op -> op a dfoo
+       -- 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
-    dict_tys  = [mkDictTy cls tys | (cls, tys) <- tycon_theta, needed_dict (cls, tys)]
-    needed_dict pred = or [ pred `elem` (dataConTheta dc) 
-                         | (DataAlt dc, _, _) <- the_alts]
 
     selector_ty :: Type
     selector_ty  = mkForAllTys tyvars $ mkForAllTys field_tyvars $
-                  mkFunTys dict_tys $  mkFunTy data_ty field_tau
+                  mkFunTys dict_tys  $  mkFunTys field_dict_tys $
+                  mkFunTy data_ty field_tau
       
-    info = mkIdInfo (RecordSelId field_label)
-          `setArityInfo`       exactArity (1 + length dict_tys)
+    arity = 1 + n_dict_tys + n_field_dict_tys
+    info = mkIdInfo (RecordSelId field_label) NoCafRefs
+          `setArityInfo`       exactArity arity
           `setUnfoldingInfo`   unfolding       
-          `setCafInfo`         NoCafRefs
            `setTyGenInfo`      TyGenNever
        -- ToDo: consider adding further IdInfo
 
     unfolding = mkTopUnfolding sel_rhs
 
-       
-    (data_id:dict_ids) = mkTemplateLocals (data_ty:dict_tys)
+       -- Allocate Ids.  We do it a funny way round because field_dict_tys is
+       -- almost always empty  
+    dict_ids          = mkTemplateLocalsNum 1              dict_tys
+    field_dict_ids     = mkTemplateLocalsNum (n_dict_tys+1) field_dict_tys
+    data_id           = mkTemplateLocal     arity          data_ty
+
     alts      = map mk_maybe_alt data_cons
     the_alts  = catMaybes alts
     default_alt | all isJust alts = [] -- No default needed
                | otherwise       = [(DEFAULT, [], error_expr)]
 
-    sel_rhs = mkLams tyvars $ mkLams field_tyvars $ 
-             mkLams dict_ids $ Lam data_id $
-             sel_body
+    sel_rhs = mkLams tyvars   $ mkLams field_tyvars $ 
+             mkLams dict_ids $ mkLams field_dict_ids $
+             Lam data_id     $ sel_body
 
     sel_body | isNewTyCon tycon = Note (Coerce field_tau data_ty) (Var data_id)
             | otherwise        = Case (Var data_id) data_id (the_alts ++ default_alt)
@@ -443,13 +460,13 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
                Nothing         -> Nothing
                Just the_arg_id -> Just (DataAlt data_con, real_args, expr)
                  where
-                   body              = mkVarApps (Var the_arg_id) field_tyvars
+                   body              = mkVarApps (mkVarApps (Var the_arg_id) field_tyvars) field_dict_ids
                    strict_marks      = dataConStrictMarks data_con
                    (expr, real_args) = rebuildConArgs data_con arg_ids strict_marks body
-                                         (length arg_ids + 1)
+                                                      (length arg_ids + 1)
        where
-            arg_ids = mkTemplateLocals (dataConInstOrigArgTys data_con tyvar_tys)
-                                   -- The first one will shadow data_id, but who cares
+            arg_ids = mkTemplateLocalsNum (arity+1) (dataConInstOrigArgTys data_con tyvar_tys)
+                               -- arity+1 avoids all shadowing
            maybe_the_arg_id  = assocMaybe (field_lbls `zip` arg_ids) field_label
            field_lbls        = dataConFieldLabels data_con
 
@@ -526,10 +543,9 @@ mkDictSelId name clas
     field_lbl = mkFieldLabel name tycon ty tag
     tag       = assoc "MkId.mkDictSelId" (classSelIds clas `zip` allFieldLabelTags) sel_id
 
-    info      = mkIdInfo (RecordSelId field_lbl)
+    info      = mkIdInfo (RecordSelId field_lbl) NoCafRefs
                `setArityInfo`      exactArity 1
                `setUnfoldingInfo`  unfolding
-               `setCafInfo`        NoCafRefs
                 `setTyGenInfo`      TyGenNever
                
        -- We no longer use 'must-inline' on record selectors.  They'll
@@ -572,7 +588,7 @@ mkPrimOpId prim_op
     name = mkPrimOpIdName prim_op
     id   = mkId name ty info
                
-    info = mkIdInfo (PrimOpId prim_op)
+    info = mkIdInfo (PrimOpId prim_op) NoCafRefs
           `setSpecInfo`        rules
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
@@ -603,7 +619,7 @@ mkCCallOpId uniq ccall ty
     name    = mkCCallName uniq occ_str
     prim_op = CCallOp ccall
 
-    info = mkIdInfo (PrimOpId prim_op)
+    info = mkIdInfo (PrimOpId prim_op) NoCafRefs
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
 
@@ -632,9 +648,11 @@ mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta
   = mkId dfun_name dfun_ty info
   where
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
-    info = vanillaIdInfo `setTyGenInfo` TyGenNever
+    info = mkIdInfo DictFunId MayHaveCafRefs
+          `setTyGenInfo` TyGenNever
              -- type is wired-in (see comment at TcClassDcl.tcClassSig), so
              -- do not generalise it
+       -- An imported dfun may refer to CAFs, so we assume the worst
 
 {-  1 dec 99: disable the Mark Jones optimisation for the sake
     of compatibility with Hugs.
@@ -686,8 +704,7 @@ another gun with which to shoot yourself in the foot.
 unsafeCoerceId
   = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
   where
-    info = vanillaIdInfo
-          `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = constantIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
           
 
     ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
@@ -705,7 +722,7 @@ evaluate its argument and call the dataToTag# primitive.
 getTagId
   = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info
   where
-    info = vanillaIdInfo
+    info = constantIdInfo
           `setUnfoldingInfo`   mkCompulsoryUnfolding rhs
        -- We don't provide a defn for this; you must inline it
 
@@ -813,7 +830,7 @@ pc_bottoming_Id key mod name ty
 generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy
 
 -- Very useful...
-noCafIdInfo = vanillaIdInfo `setCafInfo` NoCafRefs
+noCafIdInfo = constantIdInfo `setCafInfo` NoCafRefs
 
 (openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars
 openAlphaTy  = mkTyVarTy openAlphaTyVar