[project @ 2002-04-01 08:23:30 by simonpj]
authorsimonpj <unknown>
Mon, 1 Apr 2002 08:23:36 +0000 (08:23 +0000)
committersimonpj <unknown>
Mon, 1 Apr 2002 08:23:36 +0000 (08:23 +0000)
------------------------------------
Change the treatment of the stupid
   context on data constructors
-----------------------------------

Data types can have a context:

data (Eq a, Ord b) => T a b = T1 a b | T2 a

and that makes the constructors have a context too
(notice that T2's context is "thinned"):

T1 :: (Eq a, Ord b) => a -> b -> T a b
T2 :: (Eq a) => a -> T a b

Furthermore, this context pops up when pattern matching
(though GHC hasn't implemented this, but it is in H98, and
I've fixed GHC so that it now does):

f (T2 x) = x
gets inferred type
f :: Eq a => T a b -> a

I say the context is "stupid" because the dictionaries passed
are immediately discarded -- they do nothing and have no benefit.
It's a flaw in the language.

Up to now I have put this stupid context into the type of
the "wrapper" constructors functions, T1 and T2, but that turned
out to be jolly inconvenient for generics, and record update, and
other functions that build values of type T (because they don't
have suitable dictionaries available).

So now I've taken the stupid context out.  I simply deal with
it separately in the type checker on occurrences of a constructor,
either in an expression or in a pattern.

To this end

* Lots of changes in DataCon, MkId

* New function Inst.tcInstDataCon to instantiate a data constructor

I also took the opportunity to

* Rename
dataConId --> dataConWorkId
  for consistency.

* Tidied up MkId.rebuildConArgs quite a bit, and renamed it
mkReboxingAlt

* Add function DataCon.dataConExistentialTyVars, with the obvious meaning

27 files changed:
ghc/compiler/basicTypes/DataCon.lhs
ghc/compiler/basicTypes/MkId.lhs
ghc/compiler/basicTypes/Unique.lhs
ghc/compiler/codeGen/CgCon.lhs
ghc/compiler/coreSyn/CorePrep.lhs
ghc/compiler/coreSyn/CoreSyn.lhs
ghc/compiler/coreSyn/MkExternalCore.lhs
ghc/compiler/deSugar/DsExpr.lhs
ghc/compiler/deSugar/DsUtils.lhs
ghc/compiler/hsSyn/HsExpr.lhs
ghc/compiler/javaGen/JavaGen.lhs
ghc/compiler/main/HscTypes.lhs
ghc/compiler/main/MkIface.lhs
ghc/compiler/prelude/PrelRules.lhs
ghc/compiler/prelude/TysWiredIn.lhs
ghc/compiler/rename/RnSource.lhs
ghc/compiler/simplCore/SimplUtils.lhs
ghc/compiler/typecheck/Inst.lhs
ghc/compiler/typecheck/TcClassDcl.lhs
ghc/compiler/typecheck/TcDeriv.lhs
ghc/compiler/typecheck/TcExpr.lhs
ghc/compiler/typecheck/TcHsSyn.lhs
ghc/compiler/typecheck/TcIfaceSig.lhs
ghc/compiler/typecheck/TcMonad.lhs
ghc/compiler/typecheck/TcPat.lhs
ghc/compiler/typecheck/TcTyDecls.lhs
ghc/compiler/types/Generics.lhs

index ac3ffa3..6ba6096 100644 (file)
@@ -10,12 +10,12 @@ module DataCon (
        mkDataCon,
        dataConRepType, dataConSig, dataConName, dataConTag, dataConTyCon,
        dataConArgTys, dataConOrigArgTys, dataConInstOrigArgTys,
-       dataConRepArgTys, dataConTheta,
+       dataConRepArgTys, dataConTheta, 
        dataConFieldLabels, dataConStrictMarks,
        dataConSourceArity, dataConRepArity,
-       dataConNumInstArgs, dataConId, dataConWrapId, dataConRepStrictness,
+       dataConNumInstArgs, dataConWorkId, dataConWrapId, dataConRepStrictness,
        isNullaryDataCon, isTupleCon, isUnboxedTupleCon,
-       isExistentialDataCon, classDataCon,
+       isExistentialDataCon, classDataCon, dataConExistentialTyVars,
 
        splitProductType_maybe, splitProductType,
     ) where
@@ -63,6 +63,41 @@ Every constructor, C, comes with a
   The worker is very like a primop, in that it has no binding,
 
 
+A note about the stupid context
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Data types can have a context:
+       
+       data (Eq a, Ord b) => T a b = T1 a b | T2 a
+
+and that makes the constructors have a context too
+(notice that T2's context is "thinned"):
+
+       T1 :: (Eq a, Ord b) => a -> b -> T a b
+       T2 :: (Eq a) => a -> T a b
+
+Furthermore, this context pops up when pattern matching
+(though GHC hasn't implemented this, but it is in H98, and
+I've fixed GHC so that it now does):
+
+       f (T2 x) = x
+gets inferred type
+       f :: Eq a => T a b -> a
+
+I say the context is "stupid" because the dictionaries passed
+are immediately discarded -- they do nothing and have no benefit.
+It's a flaw in the language.
+
+Up to now [March 2002] I have put this stupid context into the type of
+the "wrapper" constructors functions, T1 and T2, but that turned out
+to be jolly inconvenient for generics, and record update, and other
+functions that build values of type T (because they don't have
+suitable dictionaries available).
+
+So now I've taken the stupid context out.  I simply deal with it
+separately in the type checker on occurrences of a constructor, either
+in an expression or in a pattern.
+
+
 
 %************************************************************************
 %*                                                                     *
@@ -83,9 +118,13 @@ data DataCon
        --      data Eq a => T a = forall b. Ord b => MkT a [b]
 
        dcRepType   :: Type,    -- Type of the constructor
-                               --      forall ab . Ord b => a -> [b] -> MkT a
-                               -- (this is *not* of the constructor Id:
+                               --      forall b a . Ord b => a -> [b] -> MkT a
+                               -- (this is *not* of the constructor wrapper Id:
                                --  see notes after this data type declaration)
+                               --
+                               -- Notice that the existential type parameters come
+                               -- *first*.  It doesn't really matter provided we are
+                               -- consistent.
 
        -- The next six fields express the type of the constructor, in pieces
        -- e.g.
@@ -97,11 +136,23 @@ data DataCon
        --      dcOrigArgTys   = [a,List b]
        --      dcTyCon    = T
 
-       dcTyVars :: [TyVar],            -- Type vars and context for the data type decl
+       dcTyVars :: [TyVar],            -- Type vars for the data type decl
                                        -- These are ALWAYS THE SAME AS THE TYVARS
                                        -- FOR THE PARENT TyCon.  We occasionally rely on
                                        -- this just to avoid redundant instantiation
-       dcTheta  ::  ThetaType,
+
+       dcStupidTheta  ::  ThetaType,   -- This is a "thinned" version of the context of 
+                                       -- the data decl.  
+               -- "Thinned", because the Report says
+               -- to eliminate any constraints that don't mention
+               -- tyvars free in the arg types for this constructor
+               --
+               -- "Stupid", because the dictionaries aren't used for anything.  
+               -- 
+               -- Indeed, [as of March 02] they are no 
+               -- longer in the type of the dataConWrapId, because
+               -- that makes it harder to use the wrap-id to rebuild
+               -- values after record selection or in generics.
 
        dcExTyVars :: [TyVar],          -- Ditto for the context of the constructor,
        dcExTheta  :: ThetaType,        -- the existentially quantified stuff
@@ -136,7 +187,7 @@ data DataCon
        --
        -- An entirely separate wrapper function is built in TcTyDecls
 
-       dcId :: Id,             -- The corresponding worker Id
+       dcWorkId :: Id,         -- The corresponding worker Id
                                -- Takes dcRepArgTys as its arguments
 
        dcWrapId :: Id          -- The wrapper Id
@@ -199,7 +250,7 @@ instance Show DataCon where
 
 %************************************************************************
 %*                                                                     *
-\subsection{Consruction}
+\subsection{Construction}
 %*                                                                     *
 %************************************************************************
 
@@ -223,13 +274,13 @@ mkDataCon name arg_stricts fields
     con
   where
     con = MkData {dcName = name, dcUnique = nameUnique name,
-                 dcTyVars = tyvars, dcTheta = theta,
+                 dcTyVars = tyvars, dcStupidTheta = theta,
                  dcOrigArgTys = orig_arg_tys,
                  dcRepArgTys = rep_arg_tys,
                  dcExTyVars = ex_tyvars, dcExTheta = ex_theta,
                  dcStrictMarks = real_stricts, dcRepStrictness = rep_arg_stricts,
                  dcFields = fields, dcTag = tag, dcTyCon = tycon, dcRepType = ty,
-                 dcId = work_id, dcWrapId = wrap_id}
+                 dcWorkId = work_id, dcWrapId = wrap_id}
 
        -- Strictness marks for source-args
        --      *after unboxing choices*, 
@@ -244,7 +295,7 @@ mkDataCon name arg_stricts fields
     (rep_arg_stricts, rep_arg_tys) = computeRep real_stricts real_arg_tys
 
     tag = assoc "mkDataCon" (tyConDataCons tycon `zip` [fIRST_TAG..]) con
-    ty  = mkForAllTys (tyvars ++ ex_tyvars)
+    ty  = mkForAllTys (ex_tyvars ++ tyvars)
                      (mkFunTys rep_arg_tys result_ty)
                -- NB: the existential dict args are already in rep_arg_tys
 
@@ -267,8 +318,8 @@ dataConTyCon = dcTyCon
 dataConRepType :: DataCon -> Type
 dataConRepType = dcRepType
 
-dataConId :: DataCon -> Id
-dataConId = dcId
+dataConWorkId :: DataCon -> Id
+dataConWorkId = dcWorkId
 
 dataConWrapId :: DataCon -> Id
 dataConWrapId = dcWrapId
@@ -305,7 +356,7 @@ dataConSig :: DataCon -> ([TyVar], ThetaType,
                          [TyVar], ThetaType,
                          [Type], TyCon)
 
-dataConSig (MkData {dcTyVars = tyvars, dcTheta = theta,
+dataConSig (MkData {dcTyVars = tyvars, dcStupidTheta = theta,
                     dcExTyVars = ex_tyvars, dcExTheta = ex_theta,
                     dcOrigArgTys = arg_tys, dcTyCon = tycon})
   = (tyvars, theta, ex_tyvars, ex_theta, arg_tys, tycon)
@@ -320,17 +371,20 @@ dataConArgTys :: DataCon
 
 dataConArgTys (MkData {dcRepArgTys = arg_tys, dcTyVars = tyvars,
                       dcExTyVars = ex_tyvars}) inst_tys
- = map (substTyWith (tyvars ++ ex_tyvars) inst_tys) arg_tys
+ = map (substTyWith (ex_tyvars ++ tyvars) inst_tys) arg_tys
 
 dataConTheta :: DataCon -> ThetaType
-dataConTheta dc = dcTheta dc
+dataConTheta dc = dcStupidTheta dc
+
+dataConExistentialTyVars :: DataCon -> [TyVar]
+dataConExistentialTyVars dc = dcExTyVars dc
 
 -- And the same deal for the original arg tys:
 
 dataConInstOrigArgTys :: DataCon -> [Type] -> [Type]
 dataConInstOrigArgTys (MkData {dcOrigArgTys = arg_tys, dcTyVars = tyvars,
                       dcExTyVars = ex_tyvars}) inst_tys
- = map (substTyWith (tyvars ++ ex_tyvars) inst_tys) arg_tys
+ = map (substTyWith (ex_tyvars ++ tyvars) inst_tys) arg_tys
 \end{code}
 
 These two functions get the real argument types of the constructor,
index 0be245e..e37848f 100644 (file)
@@ -14,12 +14,14 @@ 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, ghcPrimIds,
        unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId, seqId,
@@ -52,7 +54,7 @@ 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 )
@@ -61,9 +63,9 @@ 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,
@@ -92,6 +94,7 @@ import Util             ( dropList, isSingleton )
 import Outputable
 import ListSetOps      ( assoc, assocMaybe )
 import UnicodeUtil      ( stringToUtf8 )
+import List            ( nubBy )
 import Char             ( ord )
 \end{code}             
 
@@ -234,7 +237,7 @@ 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
           `setUnfoldingInfo`   wrap_unf
@@ -244,11 +247,9 @@ mkDataConWrapId data_con
                -- 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
@@ -265,10 +266,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
@@ -289,7 +290,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 []
@@ -297,20 +298,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
-    all_tyvars   = tyvars ++ ex_tyvars
+    (tyvars, _, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con
+    all_tyvars   = ex_tyvars ++ 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
@@ -401,13 +405,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
@@ -427,12 +440,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 $
@@ -489,18 +496,17 @@ 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
@@ -520,46 +526,63 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
     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 FSLIT("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}
 
 
index 802f6a7..69c6537 100644 (file)
@@ -42,7 +42,7 @@ module Unique (
        mkPreludeTyConUnique, mkPreludeClassUnique,
        mkPArrDataConUnique,
 
-       mkBuiltinUnique,
+       mkBuiltinUnique, builtinUniques,
        mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3
     ) where
 
@@ -339,6 +339,9 @@ initTidyUniques = (mkUnique 'g' 0, mkUnique 'x' 0)
 mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3, 
    mkBuiltinUnique :: Int -> Unique
 
+builtinUniques :: [Unique]
+builtinUniques = map mkBuiltinUnique [1..]
+
 mkBuiltinUnique i = mkUnique 'B' i
 mkPseudoUnique1 i = mkUnique 'C' i -- used for getUnique on Regs
 mkPseudoUnique2 i = mkUnique 'D' i -- used in NCG for getUnique on RealRegs
index 3b91214..b07e524 100644 (file)
@@ -45,7 +45,7 @@ import ClosureInfo    ( mkConLFInfo, mkLFArgument, closureLFInfo,
 import CostCentre      ( currentOrSubsumedCCS, dontCareCCS, CostCentreStack,
                          currentCCS )
 import DataCon         ( DataCon, dataConName, dataConTag, 
-                         isUnboxedTupleCon, isNullaryDataCon, dataConId, 
+                         isUnboxedTupleCon, isNullaryDataCon, dataConWorkId, 
                          dataConWrapId, dataConRepArity
                        )
 import Id              ( Id, idName, idPrimRep )
@@ -379,7 +379,7 @@ cgReturnDataCon con amodes
                -- temporary variable, if the closure is a CHARLIKE.
                -- funnily enough, this makes the unique always come
                -- out as '54' :-)
-         buildDynCon (dataConId con) currentCCS con amodes     `thenFC` \ idinfo ->
+         buildDynCon (dataConWorkId con) currentCCS con amodes `thenFC` \ idinfo ->
          idInfoToAmode PtrRep idinfo                           `thenFC` \ amode ->
 
 
index 957eeb0..5b18681 100644 (file)
@@ -27,7 +27,6 @@ import Id     ( mkSysLocal, idType, idNewDemandInfo, idArity,
                  isDataConId_maybe, idUnfolding
                )
 import HscTypes ( ModDetails(..), implicitTyThingIds, typeEnvElts )
-import Unique  ( mkBuiltinUnique )
 import BasicTypes ( TopLevelFlag(..), isTopLevel, isNotTopLevel,
                    RecFlag(..), isNonRec
                  )
@@ -160,8 +159,6 @@ mkImplicitBinds type_env
        -- The etaExpand is so that the manifest arity of the
        -- binding matches its claimed arity, which is an 
        -- invariant of top level bindings going into the code gen
-  where
-    tmpl_uniqs = map mkBuiltinUnique [1..]
 
 get_unfolding id       -- See notes above
   | Just data_con <- isDataConId_maybe id = Var id     -- The ice is thin here, but it works
index f941deb..42640f9 100644 (file)
@@ -54,7 +54,7 @@ import CostCentre     ( CostCentre, noCostCentre )
 import Var             ( Var, Id, TyVar, isTyVar, isId )
 import Type            ( Type, mkTyVarTy, seqType )
 import Literal         ( Literal, mkMachInt )
-import DataCon         ( DataCon, dataConId )
+import DataCon         ( DataCon, dataConWorkId )
 import BasicTypes      ( Activation )
 import VarSet
 import Outputable
@@ -376,7 +376,7 @@ mkLets            :: [Bind b] -> Expr b -> Expr b
 mkLams       :: [b] -> Expr b -> Expr b
 
 mkLit lit        = Lit lit
-mkConApp con args = mkApps (Var (dataConId con)) args
+mkConApp con args = mkApps (Var (dataConWorkId con)) args
 
 mkLams binders body = foldr Lam body binders
 mkLets binds body   = foldr Let body binds
index 7e7f808..b8e955c 100644 (file)
@@ -72,10 +72,10 @@ collect_tdefs _ tdefs = tdefs
 make_cdef :: DataCon -> C.Cdef
 make_cdef dcon =  C.Constr dcon_name existentials tys
   where 
-    dcon_name = make_con_qid (idName (dataConId dcon))
+    dcon_name    = make_con_qid (idName (dataConWorkId dcon))
     existentials = map make_tbind ex_tyvars
-          where (_,_,ex_tyvars,_,_,_) = dataConSig dcon
-    tys = map make_ty (dataConRepArgTys dcon)
+    ex_tyvars    = dataConExistentialTyVars dcon
+    tys         = map make_ty (dataConRepArgTys dcon)
 
 make_tbind :: TyVar -> C.Tbind
 make_tbind tv = (make_var_id (tyVarName tv), make_kind (tyVarKind tv))
@@ -113,7 +113,7 @@ make_exp _ = error "MkExternalCore died: make_exp"
 
 make_alt :: CoreAlt -> C.Alt
 make_alt (DataAlt dcon, vs, e) = 
-    C.Acon (make_con_qid (idName (dataConId dcon))) (map make_tbind tbs) (map make_vbind vbs) (make_exp e)
+    C.Acon (make_con_qid (idName (dataConWorkId dcon))) (map make_tbind tbs) (map make_vbind vbs) (make_exp e)
        where (tbs,vbs) = span isTyVar vs
 make_alt (LitAlt l,_,e) = C.Alit (make_lit l) (make_exp e)
 make_alt (DEFAULT,[],e) = C.Adefault (make_exp e)
index 45b02fb..72b799a 100644 (file)
@@ -451,10 +451,10 @@ might do some argument-evaluation first; and may have to throw away some
 dictionaries.
 
 \begin{code}
-dsExpr (RecordUpdOut record_expr record_in_ty record_out_ty dicts [])
+dsExpr (RecordUpdOut record_expr record_in_ty record_out_ty [])
   = dsExpr record_expr
 
-dsExpr expr@(RecordUpdOut record_expr record_in_ty record_out_ty dicts rbinds)
+dsExpr expr@(RecordUpdOut record_expr record_in_ty record_out_ty rbinds)
   = getSrcLocDs                        `thenDs` \ src_loc ->
     dsExpr record_expr         `thenDs` \ record_expr' ->
 
@@ -477,9 +477,7 @@ dsExpr expr@(RecordUpdOut record_expr record_in_ty record_out_ty dicts rbinds)
            let 
                val_args = zipWithEqual "dsExpr:RecordUpd" mk_val_arg
                                        (dataConFieldLabels con) arg_ids
-               rhs = foldl HsApp (DictApp (TyApp (HsVar (dataConWrapId con)) 
-                                                 out_inst_tys)
-                                          dicts)
+               rhs = foldl HsApp (TyApp (HsVar (dataConWrapId con)) out_inst_tys)
                                  val_args
            in
            returnDs (mkSimpleMatch [ConPat con record_in_ty [] [] (map VarPat arg_ids)]
index 9bb99a6..bad4e92 100644 (file)
@@ -40,12 +40,11 @@ import DsMonad
 
 import CoreUtils       ( exprType, mkIfThenElse )
 import PrelInfo                ( iRREFUT_PAT_ERROR_ID )
-import MkId            ( rebuildConArgs )
+import MkId            ( mkReboxingAlt, mkNewTypeBody )
 import Id              ( idType, Id, mkWildId )
 import Literal         ( Literal(..), inIntRange, tARGET_MAX_INT )
 import TyCon           ( isNewTyCon, tyConDataCons, isRecursiveTyCon )
-import DataCon         ( DataCon, dataConStrictMarks, dataConId,
-                         dataConSourceArity )
+import DataCon         ( DataCon, dataConSourceArity )
 import Type            ( mkFunTy, isUnLiftedType, Type, splitTyConApp )
 import TcType          ( tcTyConAppTyCon, isIntTy, isFloatTy, isDoubleTy )
 import TysPrim         ( intPrimTy, charPrimTy, floatPrimTy, doublePrimTy )
@@ -279,16 +278,11 @@ mkCoAlgCaseMatchResult var match_alts
        -- Stuff for newtype
     (_, arg_ids, match_result) = head match_alts
     arg_id                    = head arg_ids
-
-    newtype_rhs | isRecursiveTyCon tycon       -- Recursive case; need a case
-               = Note (Coerce (idType arg_id) scrut_ty) (Var var)
-               | otherwise                     -- Normal case (newtype is transparent)
-               = Var var
+    newtype_rhs               = mkNewTypeBody tycon (idType arg_id) (Var var)
                
        -- Stuff for data types
-    data_cons = tyConDataCons tycon
-
-    match_results             = [match_result | (_,_,match_result) <- match_alts]
+    data_cons      = tyConDataCons tycon
+    match_results  = [match_result | (_,_,match_result) <- match_alts]
 
     fail_flag | exhaustive_case
              = foldr1 orFail [can_it_fail | MatchResult can_it_fail _ <- match_results]
@@ -300,12 +294,9 @@ mkCoAlgCaseMatchResult var match_alts
                   returnDs (Case (Var var) wild_var (mk_default fail ++ alts))
 
     mk_alt fail (con, args, MatchResult _ body_fn)
-       = body_fn fail                                          `thenDs` \ body ->
-         getUniquesDs                                          `thenDs` \ us ->
-         let
-            (binds, real_args) = rebuildConArgs args (dataConStrictMarks con) us
-         in
-         returnDs (DataAlt con, real_args, mkDsLets binds body)
+       = body_fn fail                          `thenDs` \ body ->
+         getUniquesDs                          `thenDs` \ us ->
+         returnDs (mkReboxingAlt us con args body)
 
     mk_default fail | exhaustive_case = []
                    | otherwise       = [(DEFAULT, [], fail)]
@@ -606,10 +597,10 @@ interact well with rules.
 
 \begin{code}
 mkNilExpr :: Type -> CoreExpr
-mkNilExpr ty = App (Var (dataConId nilDataCon)) (Type ty)
+mkNilExpr ty = mkConApp nilDataCon [Type ty]
 
 mkConsExpr :: Type -> CoreExpr -> CoreExpr -> CoreExpr
-mkConsExpr ty hd tl = mkApps (Var (dataConId consDataCon)) [Type ty, hd, tl]
+mkConsExpr ty hd tl = mkConApp consDataCon [Type ty, hd, tl]
 \end{code}
 
 
index 419cb31..f006a38 100644 (file)
@@ -130,7 +130,6 @@ data HsExpr id pat
                 Type                   -- Type of *input* record
                 Type                   -- Type of *result* record (may differ from
                                        --      type of input record)
-                [id]                   -- Dicts needed for construction
                 (HsRecordBinds id pat)
 
   | ExprWithTySig                      -- signature binding
@@ -327,7 +326,7 @@ ppr_expr (RecordConOut data_con con rbinds)
 
 ppr_expr (RecordUpd aexp rbinds)
   = pp_rbinds (pprParendExpr aexp) rbinds
-ppr_expr (RecordUpdOut aexp _ _ _ rbinds)
+ppr_expr (RecordUpdOut aexp _ _ rbinds)
   = pp_rbinds (pprParendExpr aexp) rbinds
 
 ppr_expr (ExprWithTySig expr sig)
index b6fbc36..e46a1c6 100644 (file)
@@ -52,7 +52,7 @@ import Id     ( Id, isDataConId_maybe, isId, idName, isDeadBinder, idPrimRep
 import Name    ( NamedThing(..), getOccString, isExternalName, isInternalName
                , nameModule )
 import PrimRep  ( PrimRep(..) )
-import DataCon ( DataCon, dataConRepArity, dataConRepArgTys, dataConId )
+import DataCon ( DataCon, dataConRepArity, dataConRepArgTys, dataConWorkId )
 import qualified Type
 import qualified CoreSyn
 import CoreSyn ( CoreBind, CoreExpr, CoreAlt, CoreBndr,
@@ -755,7 +755,7 @@ shortName = reverse . takeWhile (/= '.') . reverse
 -- would return the name "Test.Foo".
 
 javaConstrWkrName :: DataCon -> TypeName
-javaConstrWkrName = javaIdTypeName . dataConId
+javaConstrWkrName = javaIdTypeName . dataConWorkId
 
 -- Makes x_inst for Rec decls
 -- They are *never* is primitive
index ad4344a..1800e84 100644 (file)
@@ -67,7 +67,7 @@ import CoreSyn                ( CoreBind )
 import Id              ( Id )
 import Class           ( Class, classSelIds )
 import TyCon           ( TyCon, isNewTyCon, tyConGenIds, tyConSelIds, tyConDataCons_maybe )
-import DataCon         ( dataConId, dataConWrapId )
+import DataCon         ( dataConWorkId, dataConWrapId )
 
 import BasicTypes      ( Version, initialVersion, Fixity, defaultFixity, IPName )
 
@@ -380,7 +380,7 @@ implicitTyThingIds things
     implicitConIds tc dc       -- Newtypes have a constructor wrapper,
                                -- but no worker
        | isNewTyCon tc = [dataConWrapId dc]
-       | otherwise     = [dataConId dc, dataConWrapId dc]
+       | otherwise     = [dataConWorkId dc, dataConWrapId dc]
 \end{code}
 
 
index 1bf3a35..8fe9e66 100644 (file)
@@ -38,7 +38,7 @@ import CmdLineOpts
 import Id              ( idType, idInfo, isImplicitId, idCgInfo,
                          isLocalId, idName,
                        )
-import DataCon         ( dataConId, dataConSig, dataConFieldLabels, dataConStrictMarks )
+import DataCon         ( dataConWorkId, dataConSig, dataConFieldLabels, dataConStrictMarks )
 import IdInfo          -- Lots
 import Var              ( Var )
 import CoreSyn         ( CoreRule(..), IdCoreRule )
@@ -219,7 +219,7 @@ ifaceTyThing (AClass clas) = cls_decl
     tycon     = classTyCon clas
     data_con  = head (tyConDataCons tycon)
     sys_names = mkClassDeclSysNames (getName tycon, getName data_con, 
-                                    getName (dataConId data_con), map getName sc_sels)
+                                    getName (dataConWorkId data_con), map getName sc_sels)
 
     toClassOpSig (sel_id, def_meth)
        = ASSERT(sel_tyvars == clas_tyvars)
@@ -278,7 +278,7 @@ ifaceTyThing (ATyCon tycon) = ty_decl
     ifaceConDecls (DataCons cs) = DataCons (map ifaceConDecl cs)
 
     ifaceConDecl data_con 
-       = ConDecl (getName data_con) (getName (dataConId data_con))
+       = ConDecl (getName data_con) (getName (dataConWorkId data_con))
                  (toHsTyVars ex_tyvars)
                  (toHsContext ex_theta)
                  details noSrcLoc
index ba53089..a7fa425 100644 (file)
@@ -33,7 +33,7 @@ import Literal                ( Literal(..), isLitLitLit, mkMachInt, mkMachWord
 import PrimOp          ( PrimOp(..), primOpOcc )
 import TysWiredIn      ( trueDataConId, falseDataConId )
 import TyCon           ( tyConDataCons_maybe, isEnumerationTyCon, isNewTyCon )
-import DataCon         ( dataConTag, dataConTyCon, dataConId, fIRST_TAG )
+import DataCon         ( dataConTag, dataConTyCon, dataConWorkId, fIRST_TAG )
 import CoreUtils       ( exprIsValue, cheapEqExpr, exprIsConApp_maybe )
 import Type            ( tyConAppTyCon, eqType )
 import OccName         ( occNameUserString)
@@ -424,7 +424,7 @@ tagToEnumRule [Type ty, Lit (MachInt i)]
 
        []        -> Nothing    -- Abstract type
        (dc:rest) -> ASSERT( null rest )
-                    Just (Var (dataConId dc))
+                    Just (Var (dataConWorkId dc))
   where 
     correct_tag dc = (dataConTag dc - fIRST_TAG) == tag
     tag   = fromInteger i
index 9d743a5..872681e 100644 (file)
@@ -92,7 +92,7 @@ import Name           ( Name, nameRdrName, nameUnique, nameOccName,
                          nameModule, mkWiredInName )
 import OccName         ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
 import RdrName         ( rdrNameOcc )
-import DataCon         ( DataCon, mkDataCon, dataConId, dataConSourceArity )
+import DataCon         ( DataCon, mkDataCon, dataConWorkId, dataConSourceArity )
 import Var             ( TyVar, tyVarKind )
 import TyCon           ( TyCon, AlgTyConFlavour(..), DataConDetails(..), tyConDataCons,
                          mkTupleTyCon, mkAlgTyCon, tyConName
@@ -258,7 +258,7 @@ mk_tuple boxity arity = (tycon, tuple_con)
        gen_info  = mk_tc_gen_info mod tc_uniq tc_name tycon
 
 unitTyCon     = tupleTyCon Boxed 0
-unitDataConId = dataConId (head (tyConDataCons unitTyCon))
+unitDataConId = dataConWorkId (head (tyConDataCons unitTyCon))
 
 pairTyCon = tupleTyCon Boxed 2
 
@@ -457,8 +457,8 @@ boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
 trueDataCon  = pcDataCon trueDataConName  [] [] [] boolTyCon
 
-falseDataConId = dataConId falseDataCon
-trueDataConId  = dataConId trueDataCon
+falseDataConId = dataConWorkId falseDataCon
+trueDataConId  = dataConWorkId trueDataCon
 \end{code}
 
 %************************************************************************
index 5b0bf5a..adb0c37 100644 (file)
@@ -33,7 +33,7 @@ import RnMonad
 
 import Class           ( FunDep, DefMeth (..) )
 import TyCon           ( DataConDetails(..), visibleDataCons )
-import DataCon         ( dataConId )
+import DataCon         ( dataConWorkId )
 import Name            ( Name, NamedThing(..) )
 import NameSet
 import PrelNames       ( deRefStablePtrName, newStablePtrName,
@@ -597,7 +597,7 @@ rnCoreExpr (UfTuple (HsTupCon _ boxity arity) args)
   = mapRn rnCoreExpr args              `thenRn` \ args' ->
     returnRn (UfTuple (HsTupCon tup_name boxity arity) args')
   where
-    tup_name = getName (dataConId (tupleCon boxity arity))
+    tup_name = getName (dataConWorkId (tupleCon boxity arity))
        -- Get the *worker* name and use that
 
 rnCoreExpr (UfApp fun arg)
index aeaa760..63a3c89 100644 (file)
@@ -42,7 +42,7 @@ import Type           ( Type, seqType, splitFunTys, dropForAlls, isStrictType,
 import TcType          ( isDictTy )
 import OccName         ( EncodedFS )
 import TyCon           ( tyConDataCons_maybe, isAlgTyCon, isNewTyCon )
-import DataCon         ( dataConRepArity, dataConSig, dataConArgTys )
+import DataCon         ( dataConRepArity, dataConExistentialTyVars, dataConArgTys )
 import Var             ( mkSysTyVar, tyVarKind )
 import Util            ( lengthExceeds, mapAccumL )
 import Outputable
@@ -885,7 +885,7 @@ mk_args missing_con inst_tys
   = getUniquesSmpl             `thenSmpl` \ tv_uniqs ->
     getUniquesSmpl             `thenSmpl` \ id_uniqs ->
     let
-       (_,_,ex_tyvars,_,_,_) = dataConSig missing_con
+       ex_tyvars   = dataConExistentialTyVars missing_con
        ex_tyvars'  = zipWith mk tv_uniqs ex_tyvars
        mk uniq tv  = mkSysTyVar uniq (tyVarKind tv)
        arg_tys     = dataConArgTys missing_con (inst_tys ++ mkTyVarTys ex_tyvars')
index f7a8472..6b25d8a 100644 (file)
@@ -13,7 +13,7 @@ module Inst (
 
        newDictsFromOld, newDicts, cloneDict,
        newMethod, newMethodWithGivenTy, newMethodAtLoc,
-       newOverloadedLit, newIPDict, tcInstCall,
+       newOverloadedLit, newIPDict, tcInstCall, tcInstDataCon,
 
        tyVarsOfInst, tyVarsOfInsts, tyVarsOfLIE, 
        ipNamesOfInst, ipNamesOfInsts, predsOfInst, predsOfInsts,
@@ -42,11 +42,11 @@ import TcMonad
 import TcEnv   ( TcIdSet, tcGetInstEnv, tcLookupId )
 import InstEnv ( InstLookupResult(..), lookupInstEnv )
 import TcMType ( zonkTcType, zonkTcTypes, zonkTcPredType, zapToType,
-                 zonkTcThetaType, tcInstTyVar, tcInstType,
+                 zonkTcThetaType, tcInstTyVar, tcInstType, tcInstTyVars
                )
 import TcType  ( Type, TcType, TcThetaType, TcPredType, TcTauType, TcTyVarSet,
                  SourceType(..), PredType, ThetaType, TyVarDetails(VanillaTv),
-                 tcSplitForAllTys, tcSplitForAllTys, 
+                 tcSplitForAllTys, tcSplitForAllTys, mkTyConApp,
                  tcSplitMethodTy, tcSplitPhiTy, tcFunArgTy,
                  isIntTy,isFloatTy, isIntegerTy, isDoubleTy,
                  tcIsTyVarTy, mkPredTy, mkTyVarTy, mkTyVarTys,
@@ -58,6 +58,7 @@ import TcType ( Type, TcType, TcThetaType, TcPredType, TcTauType, TcTyVarSet,
                )
 import CoreFVs ( idFreeTyVars )
 import Class   ( Class )
+import DataCon ( dataConSig )
 import Id      ( Id, idName, idType, mkUserLocal, mkSysLocal, mkLocalId, setIdUnique )
 import PrelInfo        ( isStandardClass, isCcallishClass, isNoDictClass )
 import Name    ( Name, mkMethodOcc, getOccName )
@@ -365,6 +366,31 @@ tcInstCall orig fun_ty     -- fun_ty is usually a sigma-type
     in
     returnNF_Tc (inst_fn, mkLIE dicts, tau)
 
+tcInstDataCon orig data_con
+  = let 
+       (tvs, stupid_theta, ex_tvs, ex_theta, arg_tys, tycon) = dataConSig data_con
+            -- We generate constraints for the stupid theta even when 
+            -- pattern matching (as the Report requires)
+    in
+    tcInstTyVars VanillaTv (ex_tvs ++ tvs)     `thenNF_Tc` \ (all_tvs', ty_args', tenv) ->
+    let
+       stupid_theta' = substTheta tenv stupid_theta
+       ex_theta'     = substTheta tenv ex_theta
+       arg_tys'      = map (substTy tenv) arg_tys
+
+       n_ex_tvs  = length ex_tvs
+       ex_tvs'   = take n_ex_tvs all_tvs'
+       result_ty = mkTyConApp tycon (drop n_ex_tvs ty_args')
+    in
+    newDicts orig stupid_theta'        `thenNF_Tc` \ stupid_dicts ->
+    newDicts orig ex_theta'    `thenNF_Tc` \ ex_dicts ->
+
+       -- Note that we return the stupid theta *only* in the LIE;
+       -- we don't otherwise use it at all
+    returnNF_Tc (ty_args', map instToId ex_dicts, arg_tys', result_ty,
+                mkLIE stupid_dicts, mkLIE ex_dicts, ex_tvs')
+
+
 newMethod :: InstOrigin
          -> TcId
          -> [TcType]
index 08403bc..a074eb5 100644 (file)
@@ -33,16 +33,17 @@ import TcBinds              ( tcMonoBinds )
 import TcMonoType      ( TcSigInfo(..), tcHsType, tcHsTheta, mkTcSig )
 import TcSimplify      ( tcSimplifyCheck )
 import TcUnify         ( checkSigTyVars, sigCtxt )
-import TcMType         ( tcInstTyVars, checkValidTheta, checkValidType, SourceTyCtxt(..), UserTypeCtxt(..) )
+import TcMType         ( tcInstTyVars )
 import TcType          ( Type, TyVarDetails(..), TcType, TcThetaType, TcTyVar, 
                          mkTyVarTys, mkPredTys, mkClassPred, 
-                         tcIsTyVarTy, tcSplitTyConApp_maybe, tcSplitSigmaTy
+                         tcIsTyVarTy, tcSplitTyConApp_maybe
                        )
 import TcMonad
 import Generics                ( mkGenericRhs )
 import PrelInfo                ( nO_METHOD_BINDING_ERROR_ID )
-import Class           ( classTyVars, classBigSig, classTyCon, className,
+import Class           ( classTyVars, classBigSig, classTyCon, 
                          Class, ClassOpItem, DefMeth (..) )
+import TyCon           ( tyConGenInfo )
 import MkId            ( mkDictSelId, mkDataConId, mkDataConWrapId, mkDefaultMethodId )
 import DataCon         ( mkDataCon )
 import Id              ( Id, idType, idName, setIdLocalExported )
@@ -54,8 +55,9 @@ import Outputable
 import Var             ( TyVar )
 import CmdLineOpts
 import ErrUtils                ( dumpIfSet )
-import Util            ( count, isSingleton, lengthIs, equalLength )
-import Maybes          ( seqMaybe, maybeToBool )
+import Util            ( count, lengthIs, equalLength )
+import Maybes          ( seqMaybe )
+import Maybe           ( isJust )
 \end{code}
 
 
@@ -191,7 +193,7 @@ checkDefaultBinds clas ops (Just mbs)
 
        returnTc (unitNameEnv op all_generic)
       where
-       n_generic    = count (maybeToBool . maybeGenericMatch) matches
+       n_generic    = count (isJust . maybeGenericMatch) matches
        none_generic = n_generic == 0
        all_generic  = matches `lengthIs` n_generic
 \end{code}
@@ -535,8 +537,12 @@ mkDefMethRhs origin clas inst_tys sel_id loc GenDefMeth
        -- instance declaration is for a single-parameter type class with
        -- a type constructor applied to type arguments in the instance decl
        --      (checkTc, so False provokes the error)
-     checkTc (not (isInstDecl origin) || simple_inst)
-            (badGenericInstance sel_id)                        `thenTc_`
+     ASSERT( isInstDecl origin )       -- We never get here from a class decl
+
+     checkTc (isJust maybe_tycon)
+            (badGenericInstance sel_id (notSimple inst_tys))   `thenTc_`
+     checkTc (isJust (tyConGenInfo tycon))
+            (badGenericInstance sel_id (notGeneric tycon))                     `thenTc_`
 
      ioToTc (dumpIfSet opt_PprStyle_Debug "Generic RHS" stuff) `thenNF_Tc_`
      returnTc rhs
@@ -550,7 +556,6 @@ mkDefMethRhs origin clas inst_tys sel_id loc GenDefMeth
          -- case we require that the instance decl is for a single-parameter
          -- type class with type variable arguments:
          --    instance (...) => C (T a b)
-    simple_inst   = maybeToBool maybe_tycon
     clas_tyvar    = head (classTyVars clas)
     Just tycon   = maybe_tycon
     maybe_tycon   = case inst_tys of 
@@ -600,10 +605,18 @@ badMethodErr clas op
 omittedMethodWarn sel_id
   = ptext SLIT("No explicit method nor default method for") <+> quotes (ppr sel_id)
 
-badGenericInstance sel_id
+badGenericInstance sel_id because
   = sep [ptext SLIT("Can't derive generic code for") <+> quotes (ppr sel_id),
-        ptext SLIT("because the instance declaration is not for a simple type (T a b c)"),
-        ptext SLIT("(where T is a derivable type constructor)")]
+        because]
+
+notSimple inst_tys
+  = vcat [ptext SLIT("because the instance type(s)"), 
+         nest 2 (ppr inst_tys),
+         ptext SLIT("is not a simple type of form (T a b c)")]
+
+notGeneric tycon
+  = vcat [ptext SLIT("because the instance type constructor") <+> quotes (ppr tycon) <+> 
+         ptext SLIT("was not compiled with -fgenerics")]
 
 mixedGenericErr op
   = ptext SLIT("Can't mix generic and non-generic equations for class method") <+> quotes (ppr op)
index da56ca9..6108d15 100644 (file)
@@ -178,6 +178,12 @@ context to the instance decl.  The "offending classes" are
 
        Read, Enum?
 
+FURTHER NOTE ADDED March 2002.  In fact, Haskell98 now requires that
+pattern matching against a constructor from a data type with a context
+gives rise to the constraints for that context -- or at least the thinned
+version.  So now all classes are "offending".
+
+
 
 %************************************************************************
 %*                                                                     *
@@ -348,12 +354,12 @@ makeDerivEqns tycl_decls
                        not (isUnLiftedType arg_ty)     -- No constraints for unlifted types?
                      ]
 
-       
         -- "extra_constraints": see notes above about contexts on data decls
-       extra_constraints | offensive_class = tyConTheta tycon
-                         | otherwise       = []
-       
-       offensive_class = classKey clas `elem` needsDataDeclCtxtClassKeys
+       extra_constraints = tyConTheta tycon
+
+       --    | offensive_class = tyConTheta tycon
+       --    | otherwise           = []
+       -- offensive_class = classKey clas `elem` needsDataDeclCtxtClassKeys
 
 
     mk_eqn_help NewType tycon clas tys
index 1e21034..32f687f 100644 (file)
@@ -9,10 +9,11 @@ module TcExpr ( tcExpr, tcMonoExpr, tcId ) where
 #include "HsVersions.h"
 
 import HsSyn           ( HsExpr(..), HsLit(..), ArithSeqInfo(..), 
-                         HsMatchContext(..), HsDoContext(..), mkMonoBind
+                         HsMatchContext(..), HsDoContext(..), 
+                         mkMonoBind 
                        )
 import RnHsSyn         ( RenamedHsExpr, RenamedRecordBinds )
-import TcHsSyn         ( TcExpr, TcRecordBinds, simpleHsLitTy  )
+import TcHsSyn         ( TcExpr, TcRecordBinds, simpleHsLitTy, mkHsDictApp, mkHsTyApp )
 
 import TcMonad
 import TcUnify         ( tcSubExp, tcGen, (<$>),
@@ -23,7 +24,7 @@ import Inst           ( InstOrigin(..),
                          LIE, mkLIE, emptyLIE, unitLIE, plusLIE, plusLIEs,
                          newOverloadedLit, newMethod, newIPDict,
                          newDicts, newMethodWithGivenTy,
-                         instToId, tcInstCall
+                         instToId, tcInstCall, tcInstDataCon
                        )
 import TcBinds         ( tcBindsAndThen )
 import TcEnv           ( tcLookupClass, tcLookupGlobalId, tcLookupGlobal_maybe,
@@ -37,7 +38,7 @@ import TcMType                ( tcInstTyVars, tcInstType, newHoleTyVarTy, zapToType,
                          newTyVarTy, newTyVarTys, zonkTcType, readHoleResult )
 import TcType          ( TcType, TcSigmaType, TcRhoType, TyVarDetails(VanillaTv),
                          tcSplitFunTys, tcSplitTyConApp, mkTyVarTys,
-                         isSigmaTy, mkFunTy, mkAppTy, mkTyConTy,
+                         isSigmaTy, mkFunTy, mkAppTy, mkTyConTy, mkFunTys,
                          mkTyConApp, mkClassPred, tcFunArgTy,
                          tyVarsOfTypes, isLinearPred,
                          liftedTypeKind, openTypeKind, mkArrowKind,
@@ -45,12 +46,12 @@ import TcType               ( TcType, TcSigmaType, TcRhoType, TyVarDetails(VanillaTv),
                          tidyOpenType
                        )
 import FieldLabel      ( FieldLabel, fieldLabelName, fieldLabelType, fieldLabelTyCon )
-import Id              ( idType, recordSelectorFieldLabel, isRecordSelector )
+import Id              ( idType, recordSelectorFieldLabel, isRecordSelector, isDataConWrapId_maybe )
 import DataCon         ( dataConFieldLabels, dataConSig, 
                          dataConStrictMarks
                        )
 import Name            ( Name )
-import TyCon           ( TyCon, tyConTyVars, isAlgTyCon, tyConDataCons )
+import TyCon           ( TyCon, tyConTyVars, tyConTheta, isAlgTyCon, tyConDataCons )
 import Subst           ( mkTopTyVarSubst, substTheta, substTy )
 import VarSet          ( emptyVarSet, elemVarSet )
 import TysWiredIn      ( boolTy, mkListTy, mkPArrTy, listTyCon, parrTyCon )
@@ -443,15 +444,16 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
        -- Figure out the tycon and data cons from the first field name
     let
                -- It's OK to use the non-tc splitters here (for a selector)
-       (Just (AnId sel_id) : _)    = maybe_sel_ids
-       (_, _, tau)                 = tcSplitSigmaTy (idType sel_id)    -- Selectors can be overloaded
-                                                                       -- when the data type has a context
-       data_ty                     = tcFunArgTy tau                    -- Must succeed since sel_id is a selector
-       tycon                       = tcTyConAppTyCon data_ty
-       data_cons                   = tyConDataCons tycon
-       (con_tyvars, _, _, _, _, _) = dataConSig (head data_cons)
+       (Just (AnId sel_id) : _) = maybe_sel_ids
+
+       (_, _, tau)  = tcSplitSigmaTy (idType sel_id)   -- Selectors can be overloaded
+                                                       -- when the data type has a context
+       data_ty      = tcFunArgTy tau                   -- Must succeed since sel_id is a selector
+       tycon        = tcTyConAppTyCon data_ty
+       data_cons    = tyConDataCons tycon
+       tycon_tyvars = tyConTyVars tycon                -- The data cons use the same type vars
     in
-    tcInstTyVars VanillaTv con_tyvars          `thenNF_Tc` \ (_, result_inst_tys, _) ->
+    tcInstTyVars VanillaTv tycon_tyvars                `thenNF_Tc` \ (_, result_inst_tys, inst_env) ->
 
        -- STEP 2
        -- Check that at least one constructor has all the named fields
@@ -491,33 +493,29 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
          | tyvar `elemVarSet` common_tyvars = returnNF_Tc result_inst_ty       -- Same as result type
          | otherwise                        = newTyVarTy liftedTypeKind        -- Fresh type
     in
-    mapNF_Tc mk_inst_ty (zip con_tyvars result_inst_tys)       `thenNF_Tc` \ inst_tys ->
+    mapNF_Tc mk_inst_ty (zip tycon_tyvars result_inst_tys)     `thenNF_Tc` \ inst_tys ->
 
        -- STEP 5
        -- Typecheck the expression to be updated
     let
        record_ty = mkTyConApp tycon inst_tys
     in
-    tcMonoExpr record_expr record_ty                   `thenTc`    \ (record_expr', record_lie) ->
+    tcMonoExpr record_expr record_ty           `thenTc`    \ (record_expr', record_lie) ->
 
        -- STEP 6
        -- Figure out the LIE we need.  We have to generate some 
        -- dictionaries for the data type context, since we are going to
-       -- do some construction.
+       -- do pattern matching over the data cons.
        --
-       -- What dictionaries do we need?  For the moment we assume that all
-       -- data constructors have the same context, and grab it from the first
-       -- constructor.  If they have varying contexts then we'd have to 
-       -- union the ones that could participate in the update.
+       -- What dictionaries do we need?  
+       -- We just take the context of the type constructor
     let
-       (tyvars, theta, _, _, _, _) = dataConSig (head data_cons)
-       inst_env = mkTopTyVarSubst tyvars result_inst_tys
-       theta'   = substTheta inst_env theta
+       theta' = substTheta inst_env (tyConTheta tycon)
     in
     newDicts RecordUpdOrigin theta'    `thenNF_Tc` \ dicts ->
 
        -- Phew!
-    returnTc (RecordUpdOut record_expr' record_ty result_record_ty (map instToId dicts) rbinds', 
+    returnTc (RecordUpdOut record_expr' record_ty result_record_ty rbinds', 
              mkLIE dicts `plusLIE` record_lie `plusLIE` rbinds_lie)
 
 tcMonoExpr (ArithSeqIn seq@(From expr)) res_ty
@@ -746,20 +744,24 @@ This gets a bit less sharing, but
 tcId :: Name -> NF_TcM (TcExpr, LIE, TcType)
 tcId name      -- Look up the Id and instantiate its type
   = tcLookupId name                    `thenNF_Tc` \ id ->
-    loop (OccurrenceOf id) (HsVar id) emptyLIE (idType id)
+    case isDataConWrapId_maybe id of
+       Nothing       -> loop (HsVar id) emptyLIE (idType id)
+       Just data_con -> inst_data_con id data_con
   where
-    loop orig (HsVar fun_id) lie fun_ty
+    orig = OccurrenceOf name
+
+    loop (HsVar fun_id) lie fun_ty
        | want_method_inst fun_ty
        = tcInstType VanillaTv fun_ty           `thenNF_Tc` \ (tyvars, theta, tau) ->
          newMethodWithGivenTy orig fun_id 
                (mkTyVarTys tyvars) theta tau   `thenNF_Tc` \ meth ->
-         loop orig (HsVar (instToId meth)) 
+         loop (HsVar (instToId meth)) 
               (unitLIE meth `plusLIE` lie) tau
 
-    loop orig fun lie fun_ty 
+    loop fun lie fun_ty 
        | isSigmaTy fun_ty
        = tcInstCall orig fun_ty        `thenNF_Tc` \ (inst_fn, inst_lie, tau) ->
-         loop orig (inst_fn fun) (inst_lie `plusLIE` lie) tau
+         loop (inst_fn fun) (inst_lie `plusLIE` lie) tau
 
        | otherwise
        = returnNF_Tc (fun, lie, fun_ty)
@@ -777,6 +779,15 @@ tcId name  -- Look up the Id and instantiate its type
        -- because that loses the linearity of the constraint.
        -- The simplest thing to do is never to construct a method constraint
        -- in the first place that has a linear implicit parameter in it.
+
+       -- We treat data constructors differently, because we have to generate
+       -- constraints for their silly theta, which no longer appears in
+       -- the type of dataConWrapId.  It's dual to TcPat.tcConstructor
+    inst_data_con id data_con
+      = tcInstDataCon orig data_con    `thenNF_Tc` \ (ty_args, ex_dicts, arg_tys, result_ty, stupid_lie, ex_lie, _) ->
+       returnNF_Tc (mkHsDictApp (mkHsTyApp (HsVar id) ty_args) ex_dicts, 
+                    stupid_lie `plusLIE` ex_lie, 
+                    mkFunTys arg_tys result_ty)
 \end{code}
 
 Typecheck expression which in most cases will be an Id.
index 0e8748f..8c23d8a 100644 (file)
@@ -514,13 +514,12 @@ zonkExpr (RecordConOut data_con con_expr rbinds)
 
 zonkExpr (RecordUpd _ _) = panic "zonkExpr:RecordUpd"
 
-zonkExpr (RecordUpdOut expr in_ty out_ty dicts rbinds)
+zonkExpr (RecordUpdOut expr in_ty out_ty rbinds)
   = zonkExpr expr              `thenNF_Tc` \ new_expr ->
     zonkTcTypeToType in_ty     `thenNF_Tc` \ new_in_ty ->
     zonkTcTypeToType out_ty    `thenNF_Tc` \ new_out_ty ->
-    mapNF_Tc zonkIdOcc dicts   `thenNF_Tc` \ new_dicts ->
     zonkRbinds rbinds  `thenNF_Tc` \ new_rbinds ->
-    returnNF_Tc (RecordUpdOut new_expr new_in_ty new_out_ty new_dicts new_rbinds)
+    returnNF_Tc (RecordUpdOut new_expr new_in_ty new_out_ty new_rbinds)
 
 zonkExpr (ExprWithTySig _ _) = panic "zonkExpr:ExprWithTySig"
 zonkExpr (ArithSeqIn _)      = panic "zonkExpr:ArithSeqIn"
index efaac5c..50f2e8a 100644 (file)
@@ -223,7 +223,7 @@ tcCoreExpr (UfTuple (HsTupCon _ boxity arity) args)
     in
     returnTc (mkApps (Var con_id) con_args)
   where
-    con_id = dataConId (tupleCon boxity arity)
+    con_id = dataConWorkId (tupleCon boxity arity)
     
 
 tcCoreExpr (UfLam bndr body)
@@ -335,14 +335,14 @@ tcCoreAlt scrut_ty (UfLitLitAlt str ty, names, rhs)
 tcCoreAlt scrut_ty alt@(con, names, rhs)
   = tcConAlt con       `thenTc` \ con ->
     let
-       (main_tyvars, _, ex_tyvars, _, _, _) = dataConSig con
-
-       (tycon, inst_tys)   = splitTyConApp scrut_ty    -- NB: not tcSplitTyConApp
+       ex_tyvars         = dataConExistentialTyVars con
+       (tycon, inst_tys) = splitTyConApp scrut_ty      -- NB: not tcSplitTyConApp
                                                        -- We are looking at Core here
-       ex_tyvars'          = [mkTyVar name (tyVarKind tv) | (name,tv) <- names `zip` ex_tyvars] 
-       ex_tys'             = mkTyVarTys ex_tyvars'
-       arg_tys             = dataConArgTys con (inst_tys ++ ex_tys')
-       id_names            = dropList ex_tyvars names
+       main_tyvars       = tyConTyVars tycon
+       ex_tyvars'        = [mkTyVar name (tyVarKind tv) | (name,tv) <- names `zip` ex_tyvars] 
+       ex_tys'           = mkTyVarTys ex_tyvars'
+       arg_tys           = dataConArgTys con (inst_tys ++ ex_tys')
+       id_names          = dropList ex_tyvars names
        arg_ids
 #ifdef DEBUG
                | not (equalLength id_names arg_tys)
index a351875..de83f05 100644 (file)
@@ -51,7 +51,7 @@ import Bag            ( Bag, emptyBag, isEmptyBag,
                          foldBag, unitBag, unionBags, snocBag )
 import Class           ( Class )
 import Name            ( Name )
-import Var             ( Id, TyVar, newMutTyVar, readMutTyVar, writeMutTyVar )
+import Var             ( TyVar, newMutTyVar, readMutTyVar, writeMutTyVar )
 import VarEnv          ( TidyEnv, emptyTidyEnv )
 import UniqSupply      ( UniqSupply, uniqFromSupply, uniqsFromSupply,
                          splitUniqSupply, mkSplitUniqSupply,
@@ -643,7 +643,7 @@ functions that deal with it.
 type InstLoc = (InstOrigin, SrcLoc, ErrCtxt)
 
 data InstOrigin
-  = OccurrenceOf Id            -- Occurrence of an overloaded identifier
+  = OccurrenceOf Name          -- Occurrence of an overloaded identifier
 
   | IPOcc (IPName Name)                -- Occurrence of an implicit parameter
   | IPBind (IPName Name)       -- Binding site of an implicit parameter
@@ -698,8 +698,8 @@ pprInstLoc :: InstLoc -> SDoc
 pprInstLoc (orig, locn, ctxt)
   = hsep [text "arising from", pp_orig orig, text "at", ppr locn]
   where
-    pp_orig (OccurrenceOf id)
-       = hsep [ptext SLIT("use of"), quotes (ppr id)]
+    pp_orig (OccurrenceOf name)
+       = hsep [ptext SLIT("use of"), quotes (ppr name)]
     pp_orig (IPOcc name)
        = hsep [ptext SLIT("use of implicit parameter"), quotes (ppr name)]
     pp_orig (IPBind name)
index ea64699..0d098fc 100644 (file)
@@ -17,16 +17,15 @@ import TcHsSyn              ( TcPat, TcId, simpleHsLitTy )
 import TcMonad
 import Inst            ( InstOrigin(..),
                          emptyLIE, plusLIE, LIE, mkLIE, unitLIE, instToId, isEmptyLIE,
-                         newMethod, newOverloadedLit, newDicts
+                         newMethod, newOverloadedLit, newDicts, tcInstDataCon
                        )
 import Id              ( mkLocalId, mkSysLocal )
 import Name            ( Name )
 import FieldLabel      ( fieldLabelName )
 import TcEnv           ( tcLookupClass, tcLookupDataCon, tcLookupGlobalId, tcLookupId )
-import TcMType                 ( tcInstTyVars, newTyVarTy, getTcTyVar, putTcTyVar, zapToType )
-import TcType          ( TcType, TcTyVar, TcSigmaType, TyVarDetails(VanillaTv),
-                         mkTyConApp, mkClassPred, liftedTypeKind, tcGetTyVar_maybe,
-                         isHoleTyVar, openTypeKind )
+import TcMType                 ( newTyVarTy, zapToType )
+import TcType          ( TcType, TcTyVar, TcSigmaType, 
+                         mkClassPred, liftedTypeKind )
 import TcUnify         ( tcSubOff, TcHoleType, 
                          unifyTauTy, unifyListTy, unifyPArrTy, unifyTupleTy,  
                          mkCoercion, idCoercion, isIdCoercion,
@@ -35,10 +34,7 @@ import TcMonoType    ( tcHsSigType, UserTypeCtxt(..) )
 
 import TysWiredIn      ( stringTy )
 import CmdLineOpts     ( opt_IrrefutableTuples )
-import DataCon         ( dataConSig, dataConFieldLabels, 
-                         dataConSourceArity
-                       )
-import Subst           ( substTy, substTheta )
+import DataCon         ( dataConFieldLabels, dataConSourceArity )
 import PrelNames       ( eqStringName, eqName, geName, cCallableClassName )
 import BasicTypes      ( isBoxed )
 import Bag
@@ -227,10 +223,10 @@ tcPat tc_bndr pat@(RecPatIn name rpats) pat_ty
   = tcAddErrCtxt (patCtxt pat) $
 
        -- Check the constructor itself
-    tcConstructor pat name             `thenTc` \ (data_con, ex_tvs, dicts, lie_avail1, arg_tys, con_res_ty) ->
+    tcConstructor pat name             `thenTc` \ (data_con, lie_req1, ex_tvs, ex_dicts, lie_avail1, arg_tys, con_res_ty) ->
 
        -- Check overall type matches (c.f. tcConPat)
-    tcSubPat con_res_ty pat_ty                 `thenTc` \ (co_fn, lie_req1) ->
+    tcSubPat con_res_ty pat_ty                 `thenTc` \ (co_fn, lie_req2) ->
     let
        -- Don't use zipEqual! If the constructor isn't really a record, then
        -- dataConFieldLabels will be empty (and each field in the pattern
@@ -240,10 +236,10 @@ tcPat tc_bndr pat@(RecPatIn name rpats) pat_ty
     in
 
        -- Check the fields
-    tc_fields field_tys rpats          `thenTc` \ (rpats', lie_req2, tvs, ids, lie_avail2) ->
+    tc_fields field_tys rpats          `thenTc` \ (rpats', lie_req3, tvs, ids, lie_avail2) ->
 
-    returnTc (RecPat data_con pat_ty ex_tvs dicts rpats',
-             lie_req1 `plusLIE` lie_req2,
+    returnTc (RecPat data_con pat_ty ex_tvs ex_dicts rpats',
+             lie_req1 `plusLIE` lie_req2 `plusLIE` lie_req3,
              listToBag ex_tvs `unionBags` tvs,
              ids,
              lie_avail1 `plusLIE` lie_avail2)
@@ -384,24 +380,9 @@ tcConstructor pat con_name
     tcLookupDataCon con_name           `thenNF_Tc` \ data_con ->
 
        -- Instantiate it
-    let 
-       (tvs, _, ex_tvs, ex_theta, arg_tys, tycon) = dataConSig data_con
-            -- Ignore the theta; overloaded constructors only
-            -- behave differently when called, not when used for
-            -- matching.
-    in
-    tcInstTyVars VanillaTv (ex_tvs ++ tvs)     `thenNF_Tc` \ (all_tvs', ty_args', tenv) ->
-    let
-       ex_theta' = substTheta tenv ex_theta
-       arg_tys'  = map (substTy tenv) arg_tys
-
-       n_ex_tvs  = length ex_tvs
-       ex_tvs'   = take n_ex_tvs all_tvs'
-       result_ty = mkTyConApp tycon (drop n_ex_tvs ty_args')
-    in
-    newDicts (PatOrigin pat) ex_theta' `thenNF_Tc` \ dicts ->
+    tcInstDataCon (PatOrigin pat) data_con     `thenNF_Tc` \ (_, ex_dicts, arg_tys, result_ty, lie_req, ex_lie, ex_tvs) ->
 
-    returnTc (data_con, ex_tvs', map instToId dicts, mkLIE dicts, arg_tys', result_ty)
+    returnTc (data_con, lie_req, ex_tvs, ex_dicts, ex_lie, arg_tys, result_ty)
 \end{code}           
 
 ------------------------------------------------------
@@ -410,12 +391,12 @@ tcConPat tc_bndr pat con_name arg_pats pat_ty
   = tcAddErrCtxt (patCtxt pat) $
 
        -- Check the constructor itself
-    tcConstructor pat con_name         `thenTc` \ (data_con, ex_tvs, dicts, lie_avail1, arg_tys, con_res_ty) ->
+    tcConstructor pat con_name         `thenTc` \ (data_con, lie_req1, ex_tvs, ex_dicts, lie_avail1, arg_tys, con_res_ty) ->
 
        -- Check overall type matches.
        -- The pat_ty might be a for-all type, in which
        -- case we must instantiate to match
-    tcSubPat con_res_ty pat_ty         `thenTc` \ (co_fn, lie_req1) ->
+    tcSubPat con_res_ty pat_ty         `thenTc` \ (co_fn, lie_req2) ->
 
        -- Check correct arity
     let
@@ -426,10 +407,10 @@ tcConPat tc_bndr pat con_name arg_pats pat_ty
            (arityErr "Constructor" data_con con_arity no_of_args)      `thenTc_`
 
        -- Check arguments
-    tcPats tc_bndr arg_pats arg_tys    `thenTc` \ (arg_pats', lie_req2, tvs, ids, lie_avail2) ->
+    tcPats tc_bndr arg_pats arg_tys    `thenTc` \ (arg_pats', lie_req3, tvs, ids, lie_avail2) ->
 
-    returnTc (co_fn <$> ConPat data_con pat_ty ex_tvs dicts arg_pats',
-             lie_req1 `plusLIE` lie_req2,
+    returnTc (co_fn <$> ConPat data_con pat_ty ex_tvs ex_dicts arg_pats',
+             lie_req1 `plusLIE` lie_req2 `plusLIE` lie_req3,
              listToBag ex_tvs `unionBags` tvs,
              ids,
              lie_avail1 `plusLIE` lie_avail2)
index 636e67b..ce9112d 100644 (file)
@@ -21,7 +21,7 @@ import TcEnv          ( tcExtendTyVarEnv,
                          tcLookupTyCon, tcLookupRecId, 
                          TyThingDetails(..), RecTcEnv
                        )
-import TcType          ( tcEqType, tyVarsOfTypes, tyVarsOfPred, ThetaType )
+import TcType          ( tyVarsOfTypes, tyVarsOfPred, ThetaType )
 import TcMonad
 
 import DataCon         ( DataCon, mkDataCon, dataConFieldLabels )
@@ -31,8 +31,7 @@ import Var            ( TyVar )
 import Name            ( Name, NamedThing(..) )
 import Outputable
 import TyCon           ( TyCon, DataConDetails(..), visibleDataCons,
-                         tyConName, tyConTheta, 
-                         tyConTyVars, isSynTyCon )
+                         tyConTyVars )
 import VarSet          ( intersectVarSet, isEmptyVarSet )
 import PrelNames       ( unpackCStringName, unpackCStringUtf8Name )
 import List            ( nubBy )
index ca05c39..d961aa8 100644 (file)
@@ -13,7 +13,7 @@ import Type             ( Type, isUnLiftedType, tyVarsOfType, tyVarsOfTypes,
                          funTyCon
                        )
 import TcType          ( tcSplitTyConApp_maybe, tcSplitSigmaTy, tcSplitSigmaTy )
-import DataCon          ( DataCon, dataConOrigArgTys, dataConWrapId, dataConId, isExistentialDataCon )
+import DataCon          ( DataCon, dataConOrigArgTys, dataConWrapId, isExistentialDataCon )
 
 import TyCon            ( TyCon, tyConTyVars, tyConDataCons_maybe, 
                          tyConGenInfo, isNewTyCon, newTyConRep, isBoxedTupleTyCon
@@ -25,9 +25,8 @@ import CoreUtils      ( exprArity )
 import BasicTypes       ( EP(..), Boxity(..) )
 import Var              ( TyVar )
 import VarSet          ( varSetElems )
-import Id               ( Id, mkVanillaGlobal, idType, idName, 
-                         mkTemplateLocal, mkTemplateLocalsNum
-                       ) 
+import Id               ( Id, mkVanillaGlobal, idType, idName, mkSysLocal )
+import MkId            ( mkReboxingAlt, mkNewTypeBody )
 import TysWiredIn       ( genericTyCons,
                          genUnitTyCon, genUnitDataCon, plusTyCon, inrDataCon,
                          inlDataCon, crossTyCon, crossDataCon
@@ -37,8 +36,8 @@ import CoreUnfold       ( mkTopUnfolding )
 
 import Maybe           ( isNothing )
 import SrcLoc          ( builtinSrcLoc )
-import Unique          ( mkBuiltinUnique )
-import Util             ( takeList )
+import Unique          ( Unique, builtinUniques, mkBuiltinUnique )
+import Util             ( takeList, dropList )
 import Outputable 
 
 #include "HsVersions.h"
@@ -238,6 +237,10 @@ mkTyConGenInfo :: TyCon -> [Name] -> Maybe (EP Id)
 -- The two names are the names constructed by the renamer
 -- for the fromT and toT conversion functions.
 
+mkTyConGenInfo tycon []
+  = Nothing    -- This happens when we deal with the interface-file type
+               -- decl for a module compiled without -fgenerics
+
 mkTyConGenInfo tycon [from_name, to_name]
   | isNothing maybe_datacons   -- Abstractly imported types don't have
   = Nothing                    -- to/from operations, (and should not need them)
@@ -275,7 +278,7 @@ mkTyConGenInfo tycon [from_name, to_name]
 
     (from_fn, to_fn, rep_ty) 
        | isNewTyCon tycon
-       = ( mkLams tyvars $ Lam x  $ Var x,
+       = ( mkLams tyvars $ Lam x  $ mkNewTypeBody tycon newrep_ty (Var x),
            Var (dataConWrapId the_datacon),
            newrep_ty )
 
@@ -285,7 +288,8 @@ mkTyConGenInfo tycon [from_name, to_name]
            idType rep_var )
 
     -- x :: T a b c
-    x  = mkTemplateLocal 1 tycon_ty
+    x = mkGenericLocal u1 tycon_ty
+    (u1 : uniqs) = builtinUniques
 
            ----------------------
            --  Newtypes only
@@ -296,14 +300,15 @@ mkTyConGenInfo tycon [from_name, to_name]
            --  Non-newtypes only
     -- Recurse over the sum first
     -- The "2" is the first free unique
-    (from_alts, to_inner, rep_var) = mk_sum_stuff 2 tyvars datacons
+    (from_alts, to_inner, rep_var) = mk_sum_stuff uniqs tyvars datacons
     
+mkTyConGenInfo tycon names = pprPanic "mkTyConGenInfo" (ppr tycon <+> ppr names)
     
 
 ----------------------------------------------------
 --     Dealing with sums
 ----------------------------------------------------
-mk_sum_stuff :: Int            -- Base for generating unique names
+mk_sum_stuff :: [Unique]       -- Base for generating unique names
             -> [TyVar]         -- Type variables over which the tycon is abstracted
             -> [DataCon]       -- The data constructors
             -> ([Alt Id], CoreExpr, Id)
@@ -318,29 +323,36 @@ mk_sum_stuff :: Int               -- Base for generating unique names
 --                                                D a b c }} },
 --                        cd)
 
-mk_sum_stuff i tyvars [datacon]
+mk_sum_stuff us tyvars [datacon]
    = ([from_alt], to_body_fn app_exp, rep_var)
    where
-     types        = dataConOrigArgTys datacon 
-     datacon_vars = mkTemplateLocalsNum i types
-     new_i        = i + length types 
-     app_exp      = mkVarApps (Var (dataConId datacon)) (tyvars ++ datacon_vars)
-     from_alt     = (DataAlt datacon, datacon_vars, from_alt_rhs)
+     types        = dataConOrigArgTys datacon  -- Existentials already excluded
+     datacon_vars = zipWith mkGenericLocal us types
+     us'          = dropList types us
+
+     app_exp      = mkVarApps (Var (dataConWrapId datacon)) (tyvars ++ datacon_vars)
+     from_alt     = mkReboxingAlt us' datacon datacon_vars from_alt_rhs
+                       -- We are talking about *user* datacons here; hence
+                       --      dataConWrapId
+                       --      mkReboxingAlt
+
+     (_,args',_)  = from_alt
+     us''        = dropList args' us'  -- Conservative, but safe
      
-     (_, from_alt_rhs, to_body_fn, rep_var) = mk_prod_stuff new_i datacon_vars
+     (_, from_alt_rhs, to_body_fn, rep_var) = mk_prod_stuff us'' datacon_vars
 
-mk_sum_stuff i tyvars datacons
+mk_sum_stuff (u:us) tyvars datacons
   = (wrap inlDataCon l_from_alts ++ wrap inrDataCon r_from_alts,
      Case (Var rep_var) rep_var [(DataAlt inlDataCon, [l_rep_var], l_to_body),
                                 (DataAlt inrDataCon, [r_rep_var], r_to_body)],
      rep_var)
   where
     (l_datacons, r_datacons)           = splitInHalf datacons
-    (l_from_alts, l_to_body, l_rep_var) = mk_sum_stuff (i+2) tyvars l_datacons
-    (r_from_alts, r_to_body, r_rep_var) = mk_sum_stuff (i+2) tyvars r_datacons
+    (l_from_alts, l_to_body, l_rep_var) = mk_sum_stuff us tyvars l_datacons
+    (r_from_alts, r_to_body, r_rep_var) = mk_sum_stuff us tyvars r_datacons
     rep_tys                            = [idType l_rep_var, idType r_rep_var]
     rep_ty                             = mkTyConApp plusTyCon rep_tys
-    rep_var                            = mkTemplateLocal i rep_ty
+    rep_var                            = mkGenericLocal u rep_ty
 
     wrap :: DataCon -> [Alt Id] -> [Alt Id] 
        -- Wrap an application of the Inl or Inr constructor round each alternative
@@ -352,11 +364,11 @@ mk_sum_stuff i tyvars datacons
 ----------------------------------------------------
 --     Dealing with products
 ----------------------------------------------------
-mk_prod_stuff :: Int                   -- Base for unique names
+mk_prod_stuff :: [Unique]              -- Base for unique names
              -> [Id]                   -- arg-ids; args of the original user-defined constructor
                                        --      They are bound enclosing from_rhs
                                        --      Please bind these in the to_body_fn 
-             -> (Int,                  -- Depleted unique-name supply
+             -> ([Unique],             -- Depleted unique-name supply
                  CoreExpr,             -- from-rhs: puts together the representation from the arg_ids
                  CoreExpr -> CoreExpr, -- to_body_fn: takes apart the representation
                  Id)                   -- The rep-id; please bind this to the representation
@@ -372,26 +384,26 @@ mk_prod_stuff :: Int                      -- Base for unique names
 -- because the returned to_body_fns are nested.  
 -- Hence the returned unqique-name supply
 
-mk_prod_stuff i []             -- Unit case
-  = (i,
+mk_prod_stuff (u:us) []                -- Unit case
+  = (us,
      Var (dataConWrapId genUnitDataCon),
      \x -> x, 
-     mkTemplateLocal i (mkTyConApp genUnitTyCon []))
+     mkGenericLocal u (mkTyConApp genUnitTyCon []))
 
-mk_prod_stuff i [arg_var]      -- Singleton case
-  = (i, Var arg_var, \x -> x, arg_var)
+mk_prod_stuff us [arg_var]     -- Singleton case
+  = (us, Var arg_var, \x -> x, arg_var)
 
-mk_prod_stuff i arg_vars       -- Two or more
-  = (r_i, 
+mk_prod_stuff (u:us) arg_vars  -- Two or more
+  = (us'', 
      mkConApp crossDataCon (map Type rep_tys ++ [l_alt_rhs, r_alt_rhs]),
      \x -> Case (Var rep_var) rep_var 
                [(DataAlt crossDataCon, [l_rep_var, r_rep_var], l_to_body_fn (r_to_body_fn x))],
      rep_var)
   where
     (l_arg_vars, r_arg_vars)            = splitInHalf arg_vars
-    (l_i, l_alt_rhs, l_to_body_fn, l_rep_var) = mk_prod_stuff (i+1) l_arg_vars
-    (r_i, r_alt_rhs, r_to_body_fn, r_rep_var) = mk_prod_stuff l_i   r_arg_vars
-    rep_var = mkTemplateLocal i (mkTyConApp crossTyCon rep_tys)
+    (us', l_alt_rhs, l_to_body_fn, l_rep_var) = mk_prod_stuff us  l_arg_vars
+    (us'', r_alt_rhs, r_to_body_fn, r_rep_var) = mk_prod_stuff us' r_arg_vars
+    rep_var = mkGenericLocal u (mkTyConApp crossTyCon rep_tys)
     rep_tys = [idType l_rep_var, idType r_rep_var]
 \end{code}
 
@@ -404,6 +416,9 @@ splitInHalf list = (left, right)
                   half  = length list `div` 2
                   left  = take half list
                   right = drop half list
+
+mkGenericLocal :: Unique -> Type -> Id
+mkGenericLocal uniq ty = mkSysLocal FSLIT("g") uniq ty
 \end{code}
 
 %************************************************************************