[project @ 2000-09-22 15:56:12 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcExpr.lhs
index 7e5f033..da6a5be 100644 (file)
@@ -9,71 +9,63 @@ module TcExpr ( tcApp, tcExpr, tcPolyExpr, tcId ) where
 #include "HsVersions.h"
 
 import HsSyn           ( HsExpr(..), HsLit(..), ArithSeqInfo(..), 
-                         HsBinds(..), Stmt(..), StmtCtxt(..),
-                         mkMonoBind
+                         MonoBinds(..), StmtCtxt(..),
+                         mkMonoBind, nullMonoBinds 
                        )
 import RnHsSyn         ( RenamedHsExpr, RenamedRecordBinds )
-import TcHsSyn         ( TcExpr, TcRecordBinds,
-                         mkHsTyApp, mkHsLet, maybeBoxedPrimType
-                       )
+import TcHsSyn         ( TcExpr, TcRecordBinds, mkHsTyApp, mkHsLet )
 
 import TcMonad
 import BasicTypes      ( RecFlag(..) )
 
-import Inst            ( Inst, InstOrigin(..), OverloadedLit(..),
-                         LIE, emptyLIE, unitLIE, plusLIE, plusLIEs, newOverloadedLit,
-                         newMethod, instOverloadedFun, newDicts )
+import Inst            ( InstOrigin(..), 
+                         LIE, emptyLIE, unitLIE, plusLIE, plusLIEs,
+                         newOverloadedLit, newMethod, newIPDict,
+                         instOverloadedFun, newDicts, newClassDicts,
+                         getIPsOfLIE, instToId, ipToId
+                       )
 import TcBinds         ( tcBindsAndThen )
 import TcEnv           ( tcInstId,
                          tcLookupValue, tcLookupClassByKey,
                          tcLookupValueByKey,
                          tcExtendGlobalTyVars, tcLookupValueMaybe,
-                         tcLookupTyCon, tcLookupDataCon
+                         tcLookupTyConByKey, tcLookupDataCon
                        )
 import TcMatches       ( tcMatchesCase, tcMatchLambda, tcStmts )
-import TcMonoType      ( tcHsType, checkSigTyVars, sigCtxt )
-import TcPat           ( badFieldCon )
-import TcSimplify      ( tcSimplifyAndCheck )
+import TcMonoType      ( tcHsSigType, checkSigTyVars, sigCtxt )
+import TcPat           ( badFieldCon, simpleHsLitTy )
+import TcSimplify      ( tcSimplifyAndCheck, partitionPredsOfLIE )
+import TcImprove       ( tcImprove )
 import TcType          ( TcType, TcTauType,
                          tcInstTyVars,
                          tcInstTcType, tcSplitRhoTy,
-                         newTyVarTy, newTyVarTy_OpenKind, zonkTcType )
+                         newTyVarTy, newTyVarTys, zonkTcType )
 
-import Class           ( Class )
-import FieldLabel      ( FieldLabel, fieldLabelName, fieldLabelType
-                       )
-import Id              ( idType, recordSelectorFieldLabel,
-                         isRecordSelector,
-                         Id
-                       )
-import DataCon         ( dataConFieldLabels, dataConSig, dataConId,
+import FieldLabel      ( fieldLabelName, fieldLabelType, fieldLabelTyCon )
+import Id              ( idType, recordSelectorFieldLabel, isRecordSelector, mkVanillaId )
+import DataCon         ( dataConFieldLabels, dataConSig, 
                          dataConStrictMarks, StrictnessMark(..)
                        )
-import Name            ( Name )
-import Type            ( mkFunTy, mkAppTy, mkTyVarTy, mkTyVarTys,
+import Name            ( Name, getName )
+import Type            ( mkFunTy, mkAppTy, mkTyVarTys, ipName_maybe,
                          splitFunTy_maybe, splitFunTys, isNotUsgTy,
-                         mkTyConApp,
-                         splitForAllTys, splitRhoTy,
+                         mkTyConApp, splitSigmaTy, 
+                         splitRhoTy,
                          isTauTy, tyVarsOfType, tyVarsOfTypes, 
-                         isForAllTy, splitAlgTyConApp, splitAlgTyConApp_maybe,
-                         boxedTypeKind, mkArrowKind,
+                         isSigmaTy, splitAlgTyConApp, splitAlgTyConApp_maybe,
+                         boxedTypeKind, openTypeKind, mkArrowKind,
                          tidyOpenType
                        )
-import Subst           ( mkTopTyVarSubst, substTheta )
+import TyCon           ( TyCon, tyConTyVars )
+import Subst           ( mkTopTyVarSubst, substClasses, substTy )
 import UsageSPUtils     ( unannotTy )
 import VarSet          ( elemVarSet, mkVarSet )
-import TyCon           ( tyConDataCons )
-import TysPrim         ( intPrimTy, charPrimTy, doublePrimTy,
-                         floatPrimTy, addrPrimTy
-                       )
-import TysWiredIn      ( boolTy, charTy, stringTy )
-import PrelInfo                ( ioTyCon_NAME )
-import TcUnify         ( unifyTauTy, unifyFunTy, unifyListTy, unifyTupleTy,
-                         unifyUnboxedTupleTy )
+import TysWiredIn      ( boolTy )
+import TcUnify         ( unifyTauTy, unifyFunTy, unifyListTy, unifyTupleTy )
 import Unique          ( cCallableClassKey, cReturnableClassKey, 
                          enumFromClassOpKey, enumFromThenClassOpKey,
                          enumFromToClassOpKey, enumFromThenToClassOpKey,
-                         thenMClassOpKey, failMClassOpKey, returnMClassOpKey
+                         thenMClassOpKey, failMClassOpKey, returnMClassOpKey, ioTyConKey
                        )
 import Outputable
 import Maybes          ( maybeToBool, mapMaybe )
@@ -94,12 +86,12 @@ tcExpr :: RenamedHsExpr                     -- Expession to type check
        -> TcType                       -- Expected type (could be a polytpye)
        -> TcM s (TcExpr, LIE)
 
-tcExpr expr ty | isForAllTy ty = -- Polymorphic case
-                                tcPolyExpr expr ty     `thenTc` \ (expr', lie, _, _, _) ->
+tcExpr expr ty | isSigmaTy ty = -- Polymorphic case
+                               tcPolyExpr expr ty      `thenTc` \ (expr', lie, _, _, _) ->
                                 returnTc (expr', lie)
 
-              | otherwise     = -- Monomorphic case
-                                tcMonoExpr expr ty
+              | otherwise    = -- Monomorphic case
+                               tcMonoExpr expr ty
 \end{code}
 
 
@@ -126,6 +118,7 @@ tcPolyExpr arg expected_arg_ty
     tcInstTcType expected_arg_ty       `thenNF_Tc` \ (sig_tyvars, sig_rho) ->
     let
        (sig_theta, sig_tau) = splitRhoTy sig_rho
+       free_tyvars          = tyVarsOfType expected_arg_ty
     in
        -- Type-check the arg and unify with expected type
     tcMonoExpr arg sig_tau                             `thenTc` \ (arg', lie_arg) ->
@@ -141,12 +134,13 @@ tcPolyExpr arg expected_arg_ty
        -- Conclusion: include the free vars of the expected arg type in the
        -- list of "free vars" for the signature check.
 
-    tcExtendGlobalTyVars (tyVarsOfType expected_arg_ty)                $
-    tcAddErrCtxtM (sigCtxt sig_msg expected_arg_ty)            $
+    tcExtendGlobalTyVars free_tyvars                             $
+    tcAddErrCtxtM (sigCtxt sig_msg sig_tyvars sig_theta sig_tau)  $
 
-    checkSigTyVars sig_tyvars                  `thenTc` \ zonked_sig_tyvars ->
+    checkSigTyVars sig_tyvars free_tyvars      `thenTc` \ zonked_sig_tyvars ->
 
     newDicts SignatureOrigin sig_theta         `thenNF_Tc` \ (sig_dicts, dict_ids) ->
+    tcImprove (sig_dicts `plusLIE` lie_arg)    `thenTc_`
        -- ToDo: better origin
     tcSimplifyAndCheck 
        (text "the type signature of an expression")
@@ -165,8 +159,7 @@ tcPolyExpr arg expected_arg_ty
     returnTc ( generalised_arg, free_insts,
               arg', sig_tau, lie_arg )
   where
-    sig_msg ty = sep [ptext SLIT("In an expression with expected type:"),
-                     nest 4 (ppr ty)]
+    sig_msg = ptext SLIT("When checking an expression type signature")
 \end{code}
 
 %************************************************************************
@@ -177,7 +170,7 @@ tcPolyExpr arg expected_arg_ty
 
 \begin{code}
 tcMonoExpr :: RenamedHsExpr            -- Expession to type check
-          -> TcTauType                         -- Expected type (could be a type variable)
+          -> TcTauType                 -- Expected type (could be a type variable)
           -> TcM s (TcExpr, LIE)
 
 tcMonoExpr (HsVar name) res_ty
@@ -193,69 +186,13 @@ tcMonoExpr (HsVar name) res_ty
     returnTc (expr', lie)
 \end{code}
 
-%************************************************************************
-%*                                                                     *
-\subsection{Literals}
-%*                                                                     *
-%************************************************************************
-
-Overloaded literals.
-
 \begin{code}
-tcMonoExpr (HsLit (HsInt i)) res_ty
-  = newOverloadedLit (LiteralOrigin (HsInt i))
-                    (OverloadedIntegral i)
-                    res_ty  `thenNF_Tc` \ stuff ->
-    returnTc stuff
-
-tcMonoExpr (HsLit (HsFrac f)) res_ty
-  = newOverloadedLit (LiteralOrigin (HsFrac f))
-                    (OverloadedFractional f)
-                    res_ty  `thenNF_Tc` \ stuff ->
-    returnTc stuff
-
-
-tcMonoExpr (HsLit lit@(HsLitLit s)) res_ty
-  = tcLookupClassByKey cCallableClassKey               `thenNF_Tc` \ cCallableClass ->
-    newDicts (LitLitOrigin (_UNPK_ s))
-            [(cCallableClass, [res_ty])]               `thenNF_Tc` \ (dicts, _) ->
-    returnTc (HsLitOut lit res_ty, dicts)
-\end{code}
-
-Primitive literals:
-
-\begin{code}
-tcMonoExpr (HsLit lit@(HsCharPrim c)) res_ty
-  = unifyTauTy res_ty charPrimTy               `thenTc_`
-    returnTc (HsLitOut lit charPrimTy, emptyLIE)
-
-tcMonoExpr (HsLit lit@(HsStringPrim s)) res_ty
-  = unifyTauTy res_ty addrPrimTy               `thenTc_`
-    returnTc (HsLitOut lit addrPrimTy, emptyLIE)
-
-tcMonoExpr (HsLit lit@(HsIntPrim i)) res_ty
-  = unifyTauTy res_ty intPrimTy                `thenTc_`
-    returnTc (HsLitOut lit intPrimTy, emptyLIE)
-
-tcMonoExpr (HsLit lit@(HsFloatPrim f)) res_ty
-  = unifyTauTy res_ty floatPrimTy              `thenTc_`
-    returnTc (HsLitOut lit floatPrimTy, emptyLIE)
-
-tcMonoExpr (HsLit lit@(HsDoublePrim d)) res_ty
-  = unifyTauTy res_ty doublePrimTy             `thenTc_`
-    returnTc (HsLitOut lit doublePrimTy, emptyLIE)
-\end{code}
-
-Unoverloaded literals:
-
-\begin{code}
-tcMonoExpr (HsLit lit@(HsChar c)) res_ty
-  = unifyTauTy res_ty charTy           `thenTc_`
-    returnTc (HsLitOut lit charTy, emptyLIE)
-
-tcMonoExpr (HsLit lit@(HsString str)) res_ty
-  = unifyTauTy res_ty stringTy                 `thenTc_`
-    returnTc (HsLitOut lit stringTy, emptyLIE)
+tcMonoExpr (HsIPVar name) res_ty
+  -- ZZ What's the `id' used for here...
+  = let id = mkVanillaId name res_ty in
+    tcGetInstLoc (OccurrenceOf id)     `thenNF_Tc` \ loc ->
+    newIPDict name res_ty loc          `thenNF_Tc` \ ip ->
+    returnNF_Tc (HsIPVar (instToId ip), unitLIE ip)
 \end{code}
 
 %************************************************************************
@@ -265,18 +202,12 @@ tcMonoExpr (HsLit lit@(HsString str)) res_ty
 %************************************************************************
 
 \begin{code}
-tcMonoExpr (HsPar expr) res_ty -- preserve parens so printing needn't guess where they go
-  = tcMonoExpr expr res_ty
-
--- perform the negate *before* overloading the integer, since the case
--- of minBound on Ints fails otherwise.  Could be done elsewhere, but
--- convenient to do it here.
+tcMonoExpr (HsLit lit)     res_ty = tcLit lit res_ty
+tcMonoExpr (HsOverLit lit) res_ty = newOverloadedLit (LiteralOrigin lit) lit res_ty
+tcMonoExpr (HsPar expr)    res_ty = tcMonoExpr expr res_ty
 
-tcMonoExpr (NegApp (HsLit (HsInt i)) neg) res_ty
-  = tcMonoExpr (HsLit (HsInt (-i))) res_ty
-
-tcMonoExpr (NegApp expr neg) res_ty 
-  = tcMonoExpr (HsApp neg expr) res_ty
+tcMonoExpr (NegApp expr neg) res_ty
+  = tcMonoExpr (HsApp (HsVar neg) expr) res_ty
 
 tcMonoExpr (HsLam match) res_ty
   = tcMatchLambda match res_ty                 `thenTc` \ (match',lie) ->
@@ -340,15 +271,15 @@ arg/result types); unify them with the args/result; and store them for
 later use.
 
 \begin{code}
-tcMonoExpr (CCall lbl args may_gc is_asm ignored_fake_result_ty) res_ty
+tcMonoExpr (HsCCall lbl args may_gc is_asm ignored_fake_result_ty) res_ty
   =    -- Get the callable and returnable classes.
     tcLookupClassByKey cCallableClassKey       `thenNF_Tc` \ cCallableClass ->
     tcLookupClassByKey cReturnableClassKey     `thenNF_Tc` \ cReturnableClass ->
-    tcLookupTyCon ioTyCon_NAME                 `thenNF_Tc` \ ioTyCon ->
+    tcLookupTyConByKey ioTyConKey              `thenNF_Tc` \ ioTyCon ->
     let
        new_arg_dict (arg, arg_ty)
-         = newDicts (CCallOrigin (_UNPK_ lbl) (Just arg))
-                    [(cCallableClass, [arg_ty])]       `thenNF_Tc` \ (arg_dicts, _) ->
+         = newClassDicts (CCallOrigin (_UNPK_ lbl) (Just arg))
+                         [(cCallableClass, [arg_ty])]  `thenNF_Tc` \ (arg_dicts, _) ->
            returnNF_Tc arg_dicts       -- Actually a singleton bag
 
        result_origin = CCallOrigin (_UNPK_ lbl) Nothing {- Not an arg -}
@@ -359,7 +290,7 @@ tcMonoExpr (CCall lbl args may_gc is_asm ignored_fake_result_ty) res_ty
        tv_idxs | n_args == 0 = []
                | otherwise   = [1..n_args]
     in
-    mapNF_Tc (\ _ -> newTyVarTy_OpenKind) tv_idxs      `thenNF_Tc` \ arg_tys ->
+    newTyVarTys (length tv_idxs) openTypeKind          `thenNF_Tc` \ arg_tys ->
     tcMonoExprs args arg_tys                           `thenTc`    \ (args', args_lie) ->
 
        -- The argument types can be unboxed or boxed; the result
@@ -368,17 +299,14 @@ tcMonoExpr (CCall lbl args may_gc is_asm ignored_fake_result_ty) res_ty
     newTyVarTy boxedTypeKind           `thenNF_Tc` \ result_ty ->
     let
        io_result_ty = mkTyConApp ioTyCon [result_ty]
-       [ioDataCon]  = tyConDataCons ioTyCon
     in
     unifyTauTy res_ty io_result_ty             `thenTc_`
 
        -- Construct the extra insts, which encode the
        -- constraints on the argument and result types.
     mapNF_Tc new_arg_dict (zipEqual "tcMonoExpr:CCall" args arg_tys)   `thenNF_Tc` \ ccarg_dicts_s ->
-    newDicts result_origin [(cReturnableClass, [result_ty])]           `thenNF_Tc` \ (ccres_dict, _) ->
-    returnTc (HsApp (HsVar (dataConId ioDataCon) `TyApp` [result_ty])
-                   (CCall lbl args' may_gc is_asm result_ty),
-                     -- do the wrapping in the newtype constructor here
+    newClassDicts result_origin [(cReturnableClass, [result_ty])]      `thenNF_Tc` \ (ccres_dict, _) ->
+    returnTc (HsCCall lbl args' may_gc is_asm io_result_ty,
              foldr plusLIE ccres_dict ccarg_dicts_s `plusLIE` args_lie)
 \end{code}
 
@@ -450,27 +378,25 @@ tcMonoExpr in_expr@(ExplicitList exprs) res_ty    -- Non-empty list
       = tcAddErrCtxt (listCtxt expr) $
        tcMonoExpr expr elt_ty
 
-tcMonoExpr (ExplicitTuple exprs boxed) res_ty
-  = (if boxed
-       then unifyTupleTy (length exprs) res_ty
-       else unifyUnboxedTupleTy (length exprs) res_ty
-                                               ) `thenTc` \ arg_tys ->
+tcMonoExpr (ExplicitTuple exprs boxity) res_ty
+  = unifyTupleTy boxity (length exprs) res_ty  `thenTc` \ arg_tys ->
     mapAndUnzipTc (\ (expr, arg_ty) -> tcMonoExpr expr arg_ty)
                (exprs `zip` arg_tys) -- we know they're of equal length.
                                                        `thenTc` \ (exprs', lies) ->
-    returnTc (ExplicitTuple exprs' boxed, plusLIEs lies)
+    returnTc (ExplicitTuple exprs' boxity, plusLIEs lies)
 
 tcMonoExpr expr@(RecordCon con_name rbinds) res_ty
   = tcAddErrCtxt (recordConCtxt expr)          $
     tcId con_name                      `thenNF_Tc` \ (con_expr, con_lie, con_tau) ->
     let
        (_, record_ty) = splitFunTys con_tau
+       (tycon, ty_args, _) = splitAlgTyConApp record_ty
     in
-       -- Con is syntactically constrained to be a data constructor
     ASSERT( maybeToBool (splitAlgTyConApp_maybe record_ty ) )
     unifyTauTy res_ty record_ty          `thenTc_`
 
        -- Check that the record bindings match the constructor
+       -- con_name is syntactically constrained to be a data constructor
     tcLookupDataCon con_name   `thenTc` \ (data_con, _, _) ->
     let
        bad_fields = badFields rbinds data_con
@@ -481,7 +407,7 @@ tcMonoExpr expr@(RecordCon con_name rbinds) res_ty
     else
 
        -- Typecheck the record bindings
-    tcRecordBinds record_ty rbinds             `thenTc` \ (rbinds', rbinds_lie) ->
+    tcRecordBinds tycon ty_args rbinds         `thenTc` \ (rbinds', rbinds_lie) ->
     
     let
       missing_s_fields = missingStrictFields rbinds data_con
@@ -550,11 +476,12 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
        -- Figure out the tycon and data cons from the first field name
     let
        (Just sel_id : _)         = maybe_sel_ids
-       (_, tau)                  = ASSERT( isNotUsgTy (idType sel_id) )
-                                    splitForAllTys (idType sel_id)
+       (_, _, tau)               = ASSERT( isNotUsgTy (idType sel_id) )
+                                    splitSigmaTy (idType sel_id)       -- Selectors can be overloaded
+                                                                       -- when the data type has a context
        Just (data_ty, _)         = splitFunTy_maybe tau        -- Must succeed since sel_id is a selector
-       (tycon, _, data_cons)     = splitAlgTyConApp data_ty
-       (con_tyvars, theta, _, _, _, _) = dataConSig (head data_cons)
+       (tycon, _, data_cons)       = splitAlgTyConApp data_ty
+       (con_tyvars, _, _, _, _, _) = dataConSig (head data_cons)
     in
     tcInstTyVars con_tyvars                    `thenNF_Tc` \ (_, result_inst_tys, _) ->
 
@@ -572,7 +499,7 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
        result_record_ty = mkTyConApp tycon result_inst_tys
     in
     unifyTauTy res_ty result_record_ty          `thenTc_`
-    tcRecordBinds result_record_ty rbinds      `thenTc` \ (rbinds', rbinds_lie) ->
+    tcRecordBinds tycon result_inst_tys rbinds `thenTc` \ (rbinds', rbinds_lie) ->
 
        -- STEP 4
        -- Use the un-updated fields to find a vector of booleans saying
@@ -617,9 +544,9 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
     let
        (tyvars, theta, _, _, _, _) = dataConSig (head data_cons)
        inst_env = mkTopTyVarSubst tyvars result_inst_tys
-       theta'   = substTheta inst_env theta
+       theta'   = substClasses inst_env theta
     in
-    newDicts RecordUpdOrigin theta'            `thenNF_Tc` \ (con_lie, dicts) ->
+    newClassDicts RecordUpdOrigin theta'       `thenNF_Tc` \ (con_lie, dicts) ->
 
        -- Phew!
     returnTc (RecordUpdOut record_expr' result_record_ty dicts rbinds', 
@@ -686,9 +613,9 @@ tcMonoExpr in_expr@(ArithSeqIn seq@(FromThenTo expr1 expr2 expr3)) res_ty
 \begin{code}
 tcMonoExpr in_expr@(ExprWithTySig expr poly_ty) res_ty
  = tcSetErrCtxt (exprSigCtxt in_expr)  $
-   tcHsType  poly_ty           `thenTc` \ sig_tc_ty ->
+   tcHsSigType  poly_ty                `thenTc` \ sig_tc_ty ->
 
-   if not (isForAllTy sig_tc_ty) then
+   if not (isSigmaTy sig_tc_ty) then
        -- Easy case
        unifyTauTy sig_tc_ty res_ty     `thenTc_`
        tcMonoExpr expr sig_tc_ty
@@ -711,6 +638,58 @@ tcMonoExpr in_expr@(ExprWithTySig expr poly_ty) res_ty
        returnTc (expr, lie)
 \end{code}
 
+Implicit Parameter bindings.
+
+\begin{code}
+tcMonoExpr (HsWith expr binds) res_ty
+  = tcMonoExpr expr res_ty             `thenTc` \ (expr', lie) ->
+    tcIPBinds binds                    `thenTc` \ (binds', types, lie2) ->
+    partitionPredsOfLIE isBound lie    `thenTc` \ (ips, lie', dict_binds) ->
+    let expr'' = if nullMonoBinds dict_binds
+                then expr'
+                else HsLet (mkMonoBind (revBinds dict_binds) [] NonRecursive)
+                           expr'
+    in
+    tcCheckIPBinds binds' types ips    `thenTc_`
+    returnTc (HsWith expr'' binds', lie' `plusLIE` lie2)
+  where isBound p
+         = case ipName_maybe p of
+           Just n -> n `elem` names
+           Nothing -> False
+       names = map fst binds
+       -- revBinds is used because tcSimplify outputs the bindings
+       -- out-of-order.  it's not a problem elsewhere because these
+       -- bindings are normally used in a recursive let
+       -- ZZ probably need to find a better solution
+       revBinds (b1 `AndMonoBinds` b2) =
+           (revBinds b2) `AndMonoBinds` (revBinds b1)
+       revBinds b = b
+
+tcIPBinds ((name, expr) : binds)
+  = newTyVarTy openTypeKind    `thenTc` \ ty ->
+    tcGetSrcLoc                        `thenTc` \ loc ->
+    let id = ipToId name ty loc in
+    tcMonoExpr expr ty         `thenTc` \ (expr', lie) ->
+    zonkTcType ty              `thenTc` \ ty' ->
+    tcIPBinds binds            `thenTc` \ (binds', types, lie2) ->
+    returnTc ((id, expr') : binds', ty : types, lie `plusLIE` lie2)
+tcIPBinds [] = returnTc ([], [], emptyLIE)
+
+tcCheckIPBinds binds types ips
+  = foldrTc tcCheckIPBind (getIPsOfLIE ips) (zip binds types)
+
+-- ZZ how do we use the loc?
+tcCheckIPBind bt@((v, _), t1) ((n, t2) : ips) | getName v == n
+  = unifyTauTy t1 t2           `thenTc_`
+    tcCheckIPBind bt ips       `thenTc` \ ips' ->
+    returnTc ips'
+tcCheckIPBind bt (ip : ips)
+  = tcCheckIPBind bt ips       `thenTc` \ ips' ->
+    returnTc (ip : ips')
+tcCheckIPBind bt []
+  = returnTc []
+\end{code}
+
 Typecheck expression which in most cases will be an Id.
 
 \begin{code}
@@ -722,7 +701,7 @@ tcExpr_id id_expr
  = case id_expr of
        HsVar name -> tcId name                 `thenNF_Tc` \ stuff -> 
                      returnTc stuff
-       other      -> newTyVarTy_OpenKind       `thenNF_Tc` \ id_ty ->
+       other      -> newTyVarTy openTypeKind   `thenNF_Tc` \ id_ty ->
                      tcMonoExpr id_expr id_ty  `thenTc`    \ (id_expr', lie_id) ->
                      returnTc (id_expr', lie_id, id_ty) 
 \end{code}
@@ -831,11 +810,11 @@ tcId name
     tcLookupValueMaybe name    `thenNF_Tc` \ maybe_local ->
 
     case maybe_local of
-      Just tc_id -> instantiate_it (OccurrenceOf tc_id) (HsVar tc_id) (unannotTy (idType tc_id))
+      Just tc_id -> instantiate_it (OccurrenceOf tc_id) tc_id (unannotTy (idType tc_id))
 
       Nothing ->    tcLookupValue name         `thenNF_Tc` \ id ->
                    tcInstId id                 `thenNF_Tc` \ (tyvars, theta, tau) ->
-                   instantiate_it2 (OccurrenceOf id) (HsVar id) tyvars theta tau
+                   instantiate_it2 (OccurrenceOf id) id tyvars theta tau
 
   where
        -- The instantiate_it loop runs round instantiating the Id.
@@ -851,7 +830,7 @@ tcId name
 
     instantiate_it2 orig fun tyvars theta tau
       = if null theta then     -- Is it overloaded?
-               returnNF_Tc (mkHsTyApp fun arg_tys, emptyLIE, tau)
+               returnNF_Tc (mkHsTyApp (HsVar fun) arg_tys, emptyLIE, tau)
        else
                -- Yes, it's overloaded
        instOverloadedFun orig fun arg_tys theta tau    `thenNF_Tc` \ (fun', lie1) ->
@@ -918,54 +897,50 @@ tcDoStmts do_or_lc stmts src_loc res_ty
 
 Game plan for record bindings
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-For each binding 
-       field = value
-1. look up "field", to find its selector Id, which must have type
-       forall a1..an. T a1 .. an -> tau
-   where tau is the type of the field.  
+1. Find the TyCon for the bindings, from the first field label.
 
-2. Instantiate this type
+2. Instantiate its tyvars and unify (T a1 .. an) with expected_ty.
 
-3. Unify the (T a1 .. an) part with the "expected result type", which
-   is passed in.  This checks that all the field labels come from the
-   same type.
+For each binding field = value
 
-4. Type check the value using tcArg, passing tau as the expected
-   argument type.
+3. Instantiate the field type (from the field label) using the type
+   envt from step 2.
+
+4  Type check the value using tcArg, passing the field type as 
+   the expected argument type.
 
 This extends OK when the field types are universally quantified.
 
-Actually, to save excessive creation of fresh type variables,
-we 
        
 \begin{code}
 tcRecordBinds
-       :: TcType               -- Expected type of whole record
+       :: TyCon                -- Type constructor for the record
+       -> [TcType]             -- Args of this type constructor
        -> RenamedRecordBinds
        -> TcM s (TcRecordBinds, LIE)
 
-tcRecordBinds expected_record_ty rbinds
+tcRecordBinds tycon ty_args rbinds
   = mapAndUnzipTc do_bind rbinds       `thenTc` \ (rbinds', lies) ->
     returnTc (rbinds', plusLIEs lies)
   where
-    do_bind (field_label, rhs, pun_flag)
-      = tcLookupValue field_label      `thenNF_Tc` \ sel_id ->
+    tenv = mkTopTyVarSubst (tyConTyVars tycon) ty_args
+
+    do_bind (field_lbl_name, rhs, pun_flag)
+      = tcLookupValue field_lbl_name   `thenNF_Tc` \ sel_id ->
+       let
+           field_lbl = recordSelectorFieldLabel sel_id
+           field_ty  = substTy tenv (fieldLabelType field_lbl)
+       in
        ASSERT( isRecordSelector sel_id )
                -- This lookup and assertion will surely succeed, because
                -- we check that the fields are indeed record selectors
                -- before calling tcRecordBinds
+       ASSERT2( fieldLabelTyCon field_lbl == tycon, ppr field_lbl )
+               -- The caller of tcRecordBinds has already checked
+               -- that all the fields come from the same type
 
-       tcInstId sel_id                 `thenNF_Tc` \ (_, _, tau) ->
+       tcPolyExpr rhs field_ty         `thenTc` \ (rhs', lie, _, _, _) ->
 
-               -- Record selectors all have type
-               --      forall a1..an.  T a1 .. an -> tau
-       ASSERT( maybeToBool (splitFunTy_maybe tau) )
-       let
-               -- Selector must have type RecordType -> FieldType
-         Just (record_ty, field_ty) = splitFunTy_maybe tau
-       in
-       unifyTauTy expected_record_ty record_ty         `thenTc_`
-       tcPolyExpr rhs field_ty                         `thenTc` \ (rhs', lie, _, _, _) ->
        returnTc ((sel_id, rhs', pun_flag), lie)
 
 badFields rbinds data_con
@@ -1023,12 +998,36 @@ tcMonoExprs (expr:exprs) (ty:tys)
 \end{code}
 
 
-% =================================================
+%************************************************************************
+%*                                                                     *
+\subsection{Literals}
+%*                                                                     *
+%************************************************************************
 
-Errors and contexts
-~~~~~~~~~~~~~~~~~~~
+Overloaded literals.
+
+\begin{code}
+tcLit :: HsLit -> TcType -> TcM s (TcExpr, LIE)
+tcLit (HsLitLit s _) res_ty
+  = tcLookupClassByKey cCallableClassKey               `thenNF_Tc` \ cCallableClass ->
+    newClassDicts (LitLitOrigin (_UNPK_ s))
+                 [(cCallableClass,[res_ty])]           `thenNF_Tc` \ (dicts, _) ->
+    returnTc (HsLit (HsLitLit s res_ty), dicts)
+
+tcLit lit res_ty 
+  = unifyTauTy res_ty (simpleHsLitTy lit)              `thenTc_`
+    returnTc (HsLit lit, emptyLIE)
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Errors and contexts}
+%*                                                                     *
+%************************************************************************
 
 Mini-utils:
+
 \begin{code}
 pp_nest_hang :: String -> SDoc -> SDoc
 pp_nest_hang lbl stuff = nest 2 (hang (text lbl) 4 stuff)
@@ -1084,9 +1083,6 @@ lurkingRank2Err fun fun_ty
         4 (vcat [ptext SLIT("It is applied to too few arguments"),  
                  ptext SLIT("so that the result type has for-alls in it")])
 
-rank2ArgCtxt arg expected_arg_ty
-  = ptext SLIT("In a polymorphic function argument:") <+> ppr arg
-
 badFieldsUpd rbinds
   = hang (ptext SLIT("No constructor has all these fields:"))
         4 (pprQuotedList fields)
@@ -1099,15 +1095,6 @@ recordConCtxt expr = ptext SLIT("In the record construction:") <+> ppr expr
 notSelector field
   = hsep [quotes (ppr field), ptext SLIT("is not a record selector")]
 
-illegalCcallTyErr isArg ty
-  = hang (hsep [ptext SLIT("Unacceptable"), arg_or_res, ptext SLIT("type in _ccall_ or _casm_:")])
-        4 (hsep [ppr ty])
-  where
-   arg_or_res
-    | isArg     = ptext SLIT("argument")
-    | otherwise = ptext SLIT("result")
-
-
 missingStrictFieldCon :: Name -> Name -> SDoc
 missingStrictFieldCon con field
   = hsep [ptext SLIT("Constructor") <+> quotes (ppr con),