[project @ 2003-04-16 13:34:13 by simonpj]
authorsimonpj <unknown>
Wed, 16 Apr 2003 13:34:17 +0000 (13:34 +0000)
committersimonpj <unknown>
Wed, 16 Apr 2003 13:34:17 +0000 (13:34 +0000)
----------------------------------
 Use the Infer/Check idea for typechecking higher-rank types
----------------------------------

The main idea is that

data Expected ty = Infer (TcRef ty) | Check ty

tcMonoExpr :: Expr -> Expected TcRhoType -> TcM Expra

This "Expected" type tells tcMonoExpr whether it's doing inference or
checking.  It replaces the "HoleTv" flavour of type variable.

This actually leads to slightly more lines of code, but it's much
clearer, and the new type distinctions showed up several subtle bugs
in the previous implementation.  It all arose out of writing the
prototype implementation for the paper.

Error messages wibble around a little bit.  I'm not quite certain why!  But the
changes look like improvements to me.

14 files changed:
ghc/compiler/typecheck/Inst.lhs
ghc/compiler/typecheck/TcBinds.lhs
ghc/compiler/typecheck/TcExpr.hi-boot-6
ghc/compiler/typecheck/TcExpr.lhs
ghc/compiler/typecheck/TcForeign.lhs
ghc/compiler/typecheck/TcMType.lhs
ghc/compiler/typecheck/TcMatches.hi-boot-6
ghc/compiler/typecheck/TcMatches.lhs
ghc/compiler/typecheck/TcPat.lhs
ghc/compiler/typecheck/TcRnDriver.lhs
ghc/compiler/typecheck/TcRules.lhs
ghc/compiler/typecheck/TcSplice.lhs
ghc/compiler/typecheck/TcType.lhs
ghc/compiler/typecheck/TcUnify.lhs

index 86522ad..dc96759 100644 (file)
@@ -36,7 +36,7 @@ module Inst (
 
 #include "HsVersions.h"
 
-import {-# SOURCE #-}  TcExpr( tcExpr )
+import {-# SOURCE #-}  TcExpr( tcCheckSigma )
 
 import HsSyn   ( HsLit(..), HsOverLit(..), HsExpr(..) )
 import TcHsSyn ( TcExpr, TcId, TcIdSet, 
@@ -46,7 +46,7 @@ import TcHsSyn        ( TcExpr, TcId, TcIdSet,
 import TcRnMonad
 import TcEnv   ( tcGetInstEnv, tcLookupId, tcLookupTyCon, checkWellStaged, topIdLvl )
 import InstEnv ( InstLookupResult(..), lookupInstEnv )
-import TcMType ( zonkTcType, zonkTcTypes, zonkTcPredType, zapToType,
+import TcMType ( zonkTcType, zonkTcTypes, zonkTcPredType, 
                  zonkTcThetaType, tcInstTyVar, tcInstType, tcInstTyVars
                )
 import TcType  ( Type, TcType, TcThetaType, TcTyVarSet,
@@ -353,13 +353,7 @@ newOverloadedLit :: InstOrigin
                 -> HsOverLit
                 -> TcType
                 -> TcM TcExpr
-newOverloadedLit orig lit expected_ty
-  = zapToType expected_ty      `thenM_` 
-       -- The expected type might be a 'hole' type variable, 
-       -- in which case we must zap it to an ordinary type variable
-    new_over_lit orig lit expected_ty
-
-new_over_lit orig lit@(HsIntegral i fi) expected_ty
+newOverloadedLit orig lit@(HsIntegral i fi) expected_ty
   | fi /= fromIntegerName      -- Do not generate a LitInst for rebindable
                                -- syntax.  Reason: tcSyntaxName does unification
                                -- which is very inconvenient in tcSimplify
@@ -372,7 +366,7 @@ new_over_lit orig lit@(HsIntegral i fi) expected_ty
   | otherwise
   = newLitInst orig lit expected_ty
 
-new_over_lit orig lit@(HsFractional r fr) expected_ty
+newOverloadedLit orig lit@(HsFractional r fr) expected_ty
   | fr /= fromRationalName     -- c.f. HsIntegral case
   = tcSyntaxName orig expected_ty fromRationalName fr  `thenM` \ (expr, _) ->
     mkRatLit r                                         `thenM` \ rat_lit ->
@@ -665,9 +659,11 @@ tcSyntaxName orig ty std_nm user_nm
        -- C.f. newMethodAtLoc
        ([tv], _, tau)  = tcSplitSigmaTy (idType std_id)
        tau1            = substTyWith [tv] [ty] tau
+       -- Actually, the "tau-type" might be a sigma-type in the
+       -- case of locally-polymorphic methods.
     in
     addErrCtxtM (syntaxNameCtxt user_nm orig tau1)     $
-    tcExpr (HsVar user_nm) tau1                                `thenM` \ user_fn ->
+    tcCheckSigma (HsVar user_nm) tau1                  `thenM` \ user_fn ->
     returnM (user_fn, tau1)
 
 syntaxNameCtxt name orig ty tidy_env
index 7171ed2..ce66850 100644 (file)
@@ -9,7 +9,7 @@ module TcBinds ( tcBindsAndThen, tcTopBinds, tcMonoBinds, tcSpecSigs ) where
 #include "HsVersions.h"
 
 import {-# SOURCE #-} TcMatches ( tcGRHSs, tcMatchesFun )
-import {-# SOURCE #-} TcExpr  ( tcExpr, tcMonoExpr )
+import {-# SOURCE #-} TcExpr  ( tcCheckSigma, tcCheckRho )
 
 import CmdLineOpts     ( DynFlag(Opt_NoMonomorphismRestriction) )
 import HsSyn           ( HsExpr(..), HsBinds(..), MonoBinds(..), Sig(..), 
@@ -23,7 +23,7 @@ import TcHsSyn                ( TcHsBinds, TcMonoBinds, TcId, zonkId, mkHsLet )
 import TcRnMonad
 import Inst            ( InstOrigin(..), newDicts, newIPDict, instToId )
 import TcEnv           ( tcExtendLocalValEnv, tcExtendLocalValEnv2, newLocalName )
-import TcUnify         ( unifyTauTyLists, checkSigTyVarsWrt, sigCtxt )
+import TcUnify         ( Expected(..), newHole, unifyTauTyLists, checkSigTyVarsWrt, sigCtxt )
 import TcSimplify      ( tcSimplifyInfer, tcSimplifyInferCheck, tcSimplifyRestricted, 
                          tcSimplifyToDicts, tcSimplifyIPs )
 import TcMonoType      ( tcHsSigType, UserTypeCtxt(..), TcSigInfo(..), 
@@ -31,9 +31,7 @@ import TcMonoType     ( tcHsSigType, UserTypeCtxt(..), TcSigInfo(..),
                        )
 import TcPat           ( tcPat, tcSubPat, tcMonoPatBndr )
 import TcSimplify      ( bindInstsOfLocalFuns )
-import TcMType         ( newTyVar, newTyVarTy, newHoleTyVarTy,
-                         zonkTcTyVarToTyVar, readHoleResult
-                       )
+import TcMType         ( newTyVar, newTyVarTy, zonkTcTyVarToTyVar )
 import TcType          ( TcTyVar, mkTyVarTy, mkForAllTys, mkFunTys, tyVarsOfType, 
                          mkPredTy, mkForAllTy, isUnLiftedType, 
                          unliftedTypeKind, liftedTypeKind, openTypeKind, eqKind
@@ -141,7 +139,7 @@ tc_binds_and_then top_lvl combiner (IPBinds binds is_with) do_next
       = newTyVarTy openTypeKind                `thenM` \ ty ->
        getSrcLocM                      `thenM` \ loc ->
        newIPDict (IPBind ip) ip ty     `thenM` \ (ip', ip_inst) ->
-       tcMonoExpr expr ty              `thenM` \ expr' ->
+       tcCheckRho expr ty              `thenM` \ expr' ->
        returnM (ip_inst, (ip', expr'))
 
 tc_binds_and_then top_lvl combiner (MonoBind bind sigs is_rec) do_next
@@ -660,8 +658,8 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
                -- the RHS has the appropriate type (with outer for-alls stripped off)
           mono_id = tcSigMonoId sig
           mono_ty = idType mono_id
-          complete_it = addSrcLoc locn                         $
-                        tcMatchesFun name mono_ty matches      `thenM` \ matches' ->
+          complete_it = addSrcLoc locn                                 $
+                        tcMatchesFun name matches (Check mono_ty)      `thenM` \ matches' ->
                         returnM (FunMonoBind mono_id inf matches' locn, 
                                  unitBag (name, mono_id))
        in
@@ -676,8 +674,8 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
        newTyVarTy openTypeKind         `thenM` \ mono_ty ->
        let
           mono_id     = mkLocalId mono_name mono_ty
-          complete_it = addSrcLoc locn                         $
-                        tcMatchesFun name mono_ty matches      `thenM` \ matches' ->
+          complete_it = addSrcLoc locn                                 $
+                        tcMatchesFun name matches (Check mono_ty)      `thenM` \ matches' ->
                         returnM (FunMonoBind mono_id inf matches' locn, 
                                  unitBag (name, mono_id))
        in
@@ -686,13 +684,13 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
       | otherwise      -- (c) No type signature, and non-recursive
       =        let             -- So we can use a 'hole' type to infer a higher-rank type
           complete_it 
-               = addSrcLoc locn                        $
-                 newHoleTyVarTy                        `thenM` \ fun_ty -> 
-                 tcMatchesFun name fun_ty matches      `thenM` \ matches' ->
-                 readHoleResult fun_ty                 `thenM` \ fun_ty' ->
-                 newLocalName name                     `thenM` \ mono_name ->
+               = addSrcLoc locn                                $
+                 newHole                                       `thenM` \ hole -> 
+                 tcMatchesFun name matches (Infer hole)        `thenM` \ matches' ->
+                 readMutVar hole                               `thenM` \ fun_ty ->
+                 newLocalName name                             `thenM` \ mono_name ->
                  let
-                    mono_id = mkLocalId mono_name fun_ty'
+                    mono_id = mkLocalId mono_name fun_ty
                  in
                  returnM (FunMonoBind mono_id inf matches' locn, 
                           unitBag (name, mono_id))
@@ -710,18 +708,18 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
                -- The type variables are brought into scope in tc_binds_and_then,
                -- so we don't have to do anything here.
 
-       newHoleTyVarTy                  `thenM` \ pat_ty -> 
-       tcPat tc_pat_bndr pat pat_ty    `thenM` \ (pat', tvs, ids, lie_avail) ->
-       readHoleResult pat_ty           `thenM` \ pat_ty' ->
+       newHole                                 `thenM` \ hole -> 
+       tcPat tc_pat_bndr pat (Infer hole)      `thenM` \ (pat', tvs, ids, lie_avail) ->
+       readMutVar hole                         `thenM` \ pat_ty ->
 
        -- Don't know how to deal with pattern-bound existentials yet
         checkTc (isEmptyBag tvs && null lie_avail) 
                (existentialExplode bind)       `thenM_` 
 
        let
-          complete_it = addSrcLoc locn                         $
-                        addErrCtxt (patMonoBindsCtxt bind)     $
-                        tcGRHSs PatBindRhs grhss pat_ty'       `thenM` \ grhss' ->
+          complete_it = addSrcLoc locn                                 $
+                        addErrCtxt (patMonoBindsCtxt bind)             $
+                        tcGRHSs PatBindRhs grhss (Check pat_ty)        `thenM` \ grhss' ->
                         returnM (PatMonoBind pat' grhss' locn, ids)
        in
        returnM (complete_it, if isRec is_rec then ids else emptyBag)
@@ -800,7 +798,7 @@ tcSpecSigs (SpecSig name poly_ty src_loc : sigs)
 
        -- Check that f has a more general type, and build a RHS for
        -- the spec-pragma-id at the same time
-    getLIE (tcExpr (HsVar name) sig_ty)                `thenM` \ (spec_expr, spec_lie) ->
+    getLIE (tcCheckSigma (HsVar name) sig_ty)  `thenM` \ (spec_expr, spec_lie) ->
 
        -- Squeeze out any Methods (see comments with tcSimplifyToDicts)
     tcSimplifyToDicts spec_lie                 `thenM` \ spec_binds ->
index 68bf94d..8be65cd 100644 (file)
@@ -1,11 +1,16 @@
 module TcExpr where
 
-tcExpr :: 
+tcCheckSigma :: 
          RnHsSyn.RenamedHsExpr
        -> TcType.TcType
        -> TcRnTypes.TcM TcHsSyn.TcExpr
 
-tcMonoExpr :: 
+tcCheckRho :: 
          RnHsSyn.RenamedHsExpr
        -> TcType.TcType
        -> TcRnTypes.TcM TcHsSyn.TcExpr
+
+tcMonoExpr :: 
+         RnHsSyn.RenamedHsExpr
+       -> TcUnify.Expected TcType.TcType
+       -> TcRnTypes.TcM TcHsSyn.TcExpr
index 8230d2e..bb8d181 100644 (file)
@@ -4,7 +4,7 @@
 \section[TcExpr]{Typecheck an expression}
 
 \begin{code}
-module TcExpr ( tcExpr, tcExpr_id, tcMonoExpr ) where
+module TcExpr ( tcCheckSigma, tcCheckRho, tcInferRho, tcMonoExpr ) where
 
 #include "HsVersions.h"
 
@@ -21,8 +21,8 @@ import HsSyn          ( HsExpr(..), HsLit(..), ArithSeqInfo(..), recBindFields )
 import RnHsSyn         ( RenamedHsExpr, RenamedRecordBinds )
 import TcHsSyn         ( TcExpr, TcRecordBinds, hsLitType, mkHsDictApp, mkHsTyApp, mkHsLet, (<$>) )
 import TcRnMonad
-import TcUnify         ( tcSubExp, tcGen,
-                         unifyTauTy, unifyFunTy, unifyListTy, unifyPArrTy, unifyTupleTy )
+import TcUnify         ( Expected(..), newHole, zapExpectedType, zapExpectedTo, tcSubExp, tcGen,
+                         unifyFunTy, zapToListTy, zapToPArrTy, zapToTupleTy )
 import BasicTypes      ( isMarkedStrict )
 import Inst            ( InstOrigin(..), 
                          newOverloadedLit, newMethodFromName, newIPDict,
@@ -36,8 +36,7 @@ import TcEnv          ( tcLookupClass, tcLookupGlobal_maybe, tcLookupIdLvl,
 import TcMatches       ( tcMatchesCase, tcMatchLambda, tcDoStmts, tcThingWithSig )
 import TcMonoType      ( tcHsSigType, UserTypeCtxt(..) )
 import TcPat           ( badFieldCon )
-import TcMType         ( tcInstTyVars, tcInstType, newHoleTyVarTy, zapToType,
-                         newTyVarTy, newTyVarTys, zonkTcType, readHoleResult )
+import TcMType         ( tcInstTyVars, tcInstType, newTyVarTy, newTyVarTys, zonkTcType )
 import TcType          ( TcType, TcSigmaType, TcRhoType, TyVarDetails(VanillaTv),
                          tcSplitFunTys, tcSplitTyConApp, mkTyVarTys,
                          isSigmaTy, mkFunTy, mkFunTys,
@@ -76,26 +75,45 @@ import FastString
 %************************************************************************
 
 \begin{code}
-tcExpr :: RenamedHsExpr                -- Expession to type check
-       -> TcSigmaType          -- Expected type (could be a polytpye)
-       -> TcM TcExpr           -- Generalised expr with expected type
+-- tcCheckSigma does type *checking*; it's passed the expected type of the result
+tcCheckSigma :: RenamedHsExpr          -- Expession to type check
+                    -> TcSigmaType             -- Expected type (could be a polytpye)
+                    -> TcM TcExpr              -- Generalised expr with expected type
 
-tcExpr expr expected_ty 
+tcCheckSigma expr expected_ty 
   = traceTc (text "tcExpr" <+> (ppr expected_ty $$ ppr expr)) `thenM_`
     tc_expr' expr expected_ty
 
-tc_expr' expr expected_ty
-  | not (isSigmaTy expected_ty)  -- Monomorphic case
-  = tcMonoExpr expr expected_ty
-
-  | otherwise
-  = tcGen expected_ty emptyVarSet (
-       tcMonoExpr expr
+tc_expr' expr sigma_ty
+  | isSigmaTy sigma_ty
+  = tcGen sigma_ty emptyVarSet (
+       \ rho_ty -> tcCheckRho expr rho_ty
     )                          `thenM` \ (gen_fn, expr') ->
     returnM (gen_fn <$> expr')
+
+tc_expr' expr rho_ty   -- Monomorphic case
+  = tcCheckRho expr rho_ty
+\end{code}
+
+Typecheck expression which in most cases will be an Id.
+The expression can return a higher-ranked type, such as
+       (forall a. a->a) -> Int
+so we must create a hole to pass in as the expected tyvar.
+
+\begin{code}
+tcCheckRho :: RenamedHsExpr -> TcRhoType -> TcM TcExpr
+tcCheckRho expr rho_ty = tcMonoExpr expr (Check rho_ty)
+
+tcInferRho :: RenamedHsExpr -> TcM (TcExpr, TcRhoType)
+tcInferRho (HsVar name) = tcId name
+tcInferRho expr         = newHole                      `thenM` \ hole ->
+                         tcMonoExpr expr (Infer hole)  `thenM` \ expr' ->
+                         readMutVar hole               `thenM` \ rho_ty ->
+                         returnM (expr', rho_ty) 
 \end{code}
 
 
+
 %************************************************************************
 %*                                                                     *
 \subsection{The TAUT rules for variables}
@@ -104,7 +122,7 @@ tc_expr' expr expected_ty
 
 \begin{code}
 tcMonoExpr :: RenamedHsExpr            -- Expession to type check
-          -> TcRhoType                 -- Expected type (could be a type variable)
+          -> Expected TcRhoType        -- Expected type (could be a type variable)
                                        -- Definitely no foralls at the top
                                        -- Can be a 'hole'.
           -> TcM TcExpr
@@ -137,7 +155,7 @@ tcMonoExpr (HsIPVar ip) res_ty
 tcMonoExpr in_expr@(ExprWithTySig expr poly_ty) res_ty
  = addErrCtxt (exprSigCtxt in_expr)                    $
    tcHsSigType ExprSigCtxt poly_ty                     `thenM` \ sig_tc_ty ->
-   tcThingWithSig sig_tc_ty (tcMonoExpr expr) res_ty   `thenM` \ (co_fn, expr') ->
+   tcThingWithSig sig_tc_ty (tcCheckRho expr) res_ty   `thenM` \ (co_fn, expr') ->
    returnM (co_fn <$> expr')
 
 tcMonoExpr (HsType ty) res_ty
@@ -158,7 +176,8 @@ tcMonoExpr (HsType ty) res_ty
 
 \begin{code}
 tcMonoExpr (HsLit lit)     res_ty  = tcLit lit res_ty
-tcMonoExpr (HsOverLit lit) res_ty  = newOverloadedLit (LiteralOrigin lit) lit res_ty
+tcMonoExpr (HsOverLit lit) res_ty  = zapExpectedType res_ty    `thenM` \ res_ty' ->
+                                    newOverloadedLit (LiteralOrigin lit) lit res_ty'
 tcMonoExpr (HsPar expr)    res_ty  = tcMonoExpr expr res_ty    `thenM` \ expr' -> 
                                     returnM (HsPar expr')
 tcMonoExpr (HsSCC lbl expr) res_ty = tcMonoExpr expr res_ty    `thenM` \ expr' ->
@@ -190,7 +209,7 @@ a type error will occur if they aren't.
 --     op e
 
 tcMonoExpr in_expr@(SectionL arg1 op) res_ty
-  = tcExpr_id op                               `thenM` \ (op', op_ty) ->
+  = tcInferRho op                              `thenM` \ (op', op_ty) ->
     split_fun_ty op_ty 2 {- two args -}                `thenM` \ ([arg1_ty, arg2_ty], op_res_ty) ->
     tcArg op (arg1, arg1_ty, 1)                        `thenM` \ arg1' ->
     addErrCtxt (exprCtxt in_expr)              $
@@ -201,7 +220,7 @@ tcMonoExpr in_expr@(SectionL arg1 op) res_ty
 --     \ x -> op x expr
 
 tcMonoExpr in_expr@(SectionR op arg2) res_ty
-  = tcExpr_id op                               `thenM` \ (op', op_ty) ->
+  = tcInferRho op                              `thenM` \ (op', op_ty) ->
     split_fun_ty op_ty 2 {- two args -}                `thenM` \ ([arg1_ty, arg2_ty], op_res_ty) ->
     tcArg op (arg2, arg2_ty, 2)                        `thenM` \ arg2' ->
     addErrCtxt (exprCtxt in_expr)              $
@@ -211,7 +230,7 @@ tcMonoExpr in_expr@(SectionR op arg2) res_ty
 -- equivalent to (op e1) e2:
 
 tcMonoExpr in_expr@(OpApp arg1 op fix arg2) res_ty
-  = tcExpr_id op                               `thenM` \ (op', op_ty) ->
+  = tcInferRho op                              `thenM` \ (op', op_ty) ->
     split_fun_ty op_ty 2 {- two args -}                `thenM` \ ([arg1_ty, arg2_ty], op_res_ty) ->
     tcArg op (arg1, arg1_ty, 1)                        `thenM` \ arg1' ->
     tcArg op (arg2, arg2_ty, 2)                        `thenM` \ arg2' ->
@@ -237,19 +256,11 @@ tcMonoExpr in_expr@(HsCase scrut matches src_loc) res_ty
        --      case (map f) of
        --        (x:xs) -> ...
        -- will report that map is applied to too few arguments
-       --
-       -- Not only that, but it's better to check the matches on their
-       -- own, so that we get the expected results for scoped type variables.
-       --      f x = case x of
-       --              (p::a, q::b) -> (q,p)
-       -- The above should work: the match (p,q) -> (q,p) is polymorphic as
-       -- claimed by the pattern signatures.  But if we typechecked the
-       -- match with x in scope and x's type as the expected type, we'd be hosed.
 
     tcMatchesCase matches res_ty       `thenM`    \ (scrut_ty, matches') ->
 
     addErrCtxt (caseScrutCtxt scrut)   (
-      tcMonoExpr scrut scrut_ty
+      tcCheckRho scrut scrut_ty
     )                                  `thenM`    \ scrut' ->
 
     returnM (HsCase scrut' matches' src_loc)
@@ -257,41 +268,43 @@ tcMonoExpr in_expr@(HsCase scrut matches src_loc) res_ty
 tcMonoExpr (HsIf pred b1 b2 src_loc) res_ty
   = addSrcLoc src_loc  $
     addErrCtxt (predCtxt pred) (
-    tcMonoExpr pred boolTy     )       `thenM`    \ pred' ->
+    tcCheckRho pred boolTy     )       `thenM`    \ pred' ->
 
-    zapToType res_ty                   `thenM`    \ res_ty' ->
+    zapExpectedType res_ty             `thenM`    \ res_ty' ->
        -- C.f. the call to zapToType in TcMatches.tcMatches
 
-    tcMonoExpr b1 res_ty'              `thenM`    \ b1' ->
-    tcMonoExpr b2 res_ty'              `thenM`    \ b2' ->
+    tcCheckRho b1 res_ty'              `thenM`    \ b1' ->
+    tcCheckRho b2 res_ty'              `thenM`    \ b2' ->
     returnM (HsIf pred' b1' b2' src_loc)
 
 tcMonoExpr (HsDo do_or_lc stmts method_names _ src_loc) res_ty
-  = addSrcLoc src_loc          $
-    tcDoStmts do_or_lc stmts method_names res_ty       `thenM` \ (binds, stmts', methods') ->
-    returnM (mkHsLet binds (HsDo do_or_lc stmts' methods' res_ty src_loc))
+  = addSrcLoc src_loc                                  $
+    zapExpectedType res_ty                             `thenM` \ res_ty' ->
+       -- All comprehensions yield a monotype
+    tcDoStmts do_or_lc stmts method_names res_ty'      `thenM` \ (binds, stmts', methods') ->
+    returnM (mkHsLet binds (HsDo do_or_lc stmts' methods' res_ty' src_loc))
 
 tcMonoExpr in_expr@(ExplicitList _ exprs) res_ty       -- Non-empty list
-  = unifyListTy res_ty                `thenM` \ elt_ty ->  
+  = zapToListTy res_ty                `thenM` \ elt_ty ->  
     mappM (tc_elt elt_ty) exprs              `thenM` \ exprs' ->
     returnM (ExplicitList elt_ty exprs')
   where
     tc_elt elt_ty expr
       = addErrCtxt (listCtxt expr) $
-       tcMonoExpr expr elt_ty
+       tcCheckRho expr elt_ty
 
 tcMonoExpr in_expr@(ExplicitPArr _ exprs) res_ty       -- maybe empty
-  = unifyPArrTy res_ty                `thenM` \ elt_ty ->  
+  = zapToPArrTy res_ty                `thenM` \ elt_ty ->  
     mappM (tc_elt elt_ty) exprs              `thenM` \ exprs' ->
     returnM (ExplicitPArr elt_ty exprs')
   where
     tc_elt elt_ty expr
       = addErrCtxt (parrCtxt expr) $
-       tcMonoExpr expr elt_ty
+       tcCheckRho expr elt_ty
 
 tcMonoExpr (ExplicitTuple exprs boxity) res_ty
-  = unifyTupleTy boxity (length exprs) res_ty  `thenM` \ arg_tys ->
-    tcMonoExprs exprs arg_tys                  `thenM` \ exprs' ->
+  = zapToTupleTy boxity (length exprs) res_ty  `thenM` \ arg_tys ->
+    tcCheckRhos exprs arg_tys                  `thenM` \ exprs' ->
     returnM (ExplicitTuple exprs' boxity)
 \end{code}
 
@@ -339,7 +352,7 @@ tcMonoExpr e0@(HsCCall lbl args may_gc is_casm ignored_fake_result_ty) res_ty
                | otherwise  = [1..length args]
     in
     newTyVarTys (length tv_idxs) openTypeKind          `thenM` \ arg_tys ->
-    tcMonoExprs args arg_tys                           `thenM` \ args' ->
+    tcCheckRhos args arg_tys                           `thenM` \ args' ->
 
        -- The argument types can be unlifted or lifted; the result
        -- type must, however, be lifted since it's an argument to the IO
@@ -348,7 +361,7 @@ tcMonoExpr e0@(HsCCall lbl args may_gc is_casm ignored_fake_result_ty) res_ty
     let
        io_result_ty = mkTyConApp ioTyCon [result_ty]
     in
-    unifyTauTy res_ty io_result_ty             `thenM_`
+    zapExpectedTo res_ty io_result_ty  `thenM_`
 
        -- Construct the extra insts, which encode the
        -- constraints on the argument and result types.
@@ -374,11 +387,11 @@ tcMonoExpr expr@(RecordCon con_name rbinds) res_ty
        (tycon, ty_args) = tcSplitTyConApp record_ty
     in
     ASSERT( isAlgTyCon tycon )
-    unifyTauTy res_ty record_ty          `thenM_`
+    zapExpectedTo res_ty record_ty      `thenM_`
 
        -- Check that the record bindings match the constructor
        -- con_name is syntactically constrained to be a data constructor
-    tcLookupDataCon con_name   `thenM` \ data_con ->
+    tcLookupDataCon con_name           `thenM` \ data_con ->
     let
        bad_fields = badFields rbinds data_con
     in
@@ -466,7 +479,7 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
     let
        result_record_ty = mkTyConApp tycon result_inst_tys
     in
-    unifyTauTy res_ty result_record_ty          `thenM_`
+    zapExpectedTo res_ty result_record_ty      `thenM_`
     tcRecordBinds tycon result_inst_tys rbinds `thenM` \ rbinds' ->
 
        -- STEP 4
@@ -498,7 +511,7 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
     let
        record_ty = mkTyConApp tycon inst_tys
     in
-    tcMonoExpr record_expr record_ty           `thenM` \ record_expr' ->
+    tcCheckRho record_expr record_ty           `thenM` \ record_expr' ->
 
        -- STEP 6
        -- Figure out the LIE we need.  We have to generate some 
@@ -528,8 +541,8 @@ tcMonoExpr expr@(RecordUpd record_expr rbinds) res_ty
 
 \begin{code}
 tcMonoExpr (ArithSeqIn seq@(From expr)) res_ty
-  = unifyListTy res_ty                                 `thenM` \ elt_ty ->  
-    tcMonoExpr expr elt_ty                     `thenM` \ expr' ->
+  = zapToListTy res_ty                                 `thenM` \ elt_ty ->  
+    tcCheckRho expr elt_ty                     `thenM` \ expr' ->
 
     newMethodFromName (ArithSeqOrigin seq) 
                      elt_ty enumFromName       `thenM` \ enum_from ->
@@ -538,9 +551,9 @@ tcMonoExpr (ArithSeqIn seq@(From expr)) res_ty
 
 tcMonoExpr in_expr@(ArithSeqIn seq@(FromThen expr1 expr2)) res_ty
   = addErrCtxt (arithSeqCtxt in_expr) $ 
-    unifyListTy  res_ty                                `thenM`    \ elt_ty ->  
-    tcMonoExpr expr1 elt_ty                            `thenM`    \ expr1' ->
-    tcMonoExpr expr2 elt_ty                            `thenM`    \ expr2' ->
+    zapToListTy  res_ty                                `thenM`    \ elt_ty ->  
+    tcCheckRho expr1 elt_ty                            `thenM`    \ expr1' ->
+    tcCheckRho expr2 elt_ty                            `thenM`    \ expr2' ->
     newMethodFromName (ArithSeqOrigin seq) 
                      elt_ty enumFromThenName           `thenM` \ enum_from_then ->
 
@@ -549,9 +562,9 @@ tcMonoExpr in_expr@(ArithSeqIn seq@(FromThen expr1 expr2)) res_ty
 
 tcMonoExpr in_expr@(ArithSeqIn seq@(FromTo expr1 expr2)) res_ty
   = addErrCtxt (arithSeqCtxt in_expr) $
-    unifyListTy  res_ty                                `thenM`    \ elt_ty ->  
-    tcMonoExpr expr1 elt_ty                            `thenM`    \ expr1' ->
-    tcMonoExpr expr2 elt_ty                            `thenM`    \ expr2' ->
+    zapToListTy  res_ty                                `thenM`    \ elt_ty ->  
+    tcCheckRho expr1 elt_ty                            `thenM`    \ expr1' ->
+    tcCheckRho expr2 elt_ty                            `thenM`    \ expr2' ->
     newMethodFromName (ArithSeqOrigin seq) 
                      elt_ty enumFromToName             `thenM` \ enum_from_to ->
 
@@ -559,10 +572,10 @@ tcMonoExpr in_expr@(ArithSeqIn seq@(FromTo expr1 expr2)) res_ty
 
 tcMonoExpr in_expr@(ArithSeqIn seq@(FromThenTo expr1 expr2 expr3)) res_ty
   = addErrCtxt  (arithSeqCtxt in_expr) $
-    unifyListTy  res_ty                                `thenM`    \ elt_ty ->  
-    tcMonoExpr expr1 elt_ty                            `thenM`    \ expr1' ->
-    tcMonoExpr expr2 elt_ty                            `thenM`    \ expr2' ->
-    tcMonoExpr expr3 elt_ty                            `thenM`    \ expr3' ->
+    zapToListTy  res_ty                                `thenM`    \ elt_ty ->  
+    tcCheckRho expr1 elt_ty                            `thenM`    \ expr1' ->
+    tcCheckRho expr2 elt_ty                            `thenM`    \ expr2' ->
+    tcCheckRho expr3 elt_ty                            `thenM`    \ expr3' ->
     newMethodFromName (ArithSeqOrigin seq) 
                      elt_ty enumFromThenToName         `thenM` \ eft ->
 
@@ -570,9 +583,9 @@ tcMonoExpr in_expr@(ArithSeqIn seq@(FromThenTo expr1 expr2 expr3)) res_ty
 
 tcMonoExpr in_expr@(PArrSeqIn seq@(FromTo expr1 expr2)) res_ty
   = addErrCtxt (parrSeqCtxt in_expr) $
-    unifyPArrTy  res_ty                                `thenM`    \ elt_ty ->  
-    tcMonoExpr expr1 elt_ty                            `thenM`    \ expr1' ->
-    tcMonoExpr expr2 elt_ty                            `thenM`    \ expr2' ->
+    zapToPArrTy  res_ty                                `thenM`    \ elt_ty ->  
+    tcCheckRho expr1 elt_ty                            `thenM`    \ expr1' ->
+    tcCheckRho expr2 elt_ty                            `thenM`    \ expr2' ->
     newMethodFromName (PArrSeqOrigin seq) 
                      elt_ty enumFromToPName            `thenM` \ enum_from_to ->
 
@@ -580,10 +593,10 @@ tcMonoExpr in_expr@(PArrSeqIn seq@(FromTo expr1 expr2)) res_ty
 
 tcMonoExpr in_expr@(PArrSeqIn seq@(FromThenTo expr1 expr2 expr3)) res_ty
   = addErrCtxt  (parrSeqCtxt in_expr) $
-    unifyPArrTy  res_ty                                `thenM`    \ elt_ty ->  
-    tcMonoExpr expr1 elt_ty                            `thenM`    \ expr1' ->
-    tcMonoExpr expr2 elt_ty                            `thenM`    \ expr2' ->
-    tcMonoExpr expr3 elt_ty                            `thenM`    \ expr3' ->
+    zapToPArrTy  res_ty                                `thenM`    \ elt_ty ->  
+    tcCheckRho expr1 elt_ty                            `thenM`    \ expr1' ->
+    tcCheckRho expr2 elt_ty                            `thenM`    \ expr2' ->
+    tcCheckRho expr3 elt_ty                            `thenM`    \ expr3' ->
     newMethodFromName (PArrSeqOrigin seq)
                      elt_ty enumFromThenToPName        `thenM` \ eft ->
 
@@ -611,8 +624,8 @@ tcMonoExpr (HsBracket brack loc) res_ty = addSrcLoc loc (tcBracket brack res_ty)
 
 tcMonoExpr (HsReify (Reify flavour name)) res_ty
   = addErrCtxt (ptext SLIT("At the reification of") <+> ppr name)      $
-    tcMetaTy  tycon_name       `thenM` \ reify_ty ->
-    unifyTauTy res_ty reify_ty `thenM_`
+    tcMetaTy  tycon_name               `thenM` \ reify_ty ->
+    zapExpectedTo res_ty reify_ty      `thenM_`
     returnM (HsReify (ReifyOut flavour name))
   where
     tycon_name = case flavour of
@@ -643,7 +656,7 @@ tcMonoExpr other _ = pprPanic "tcMonoExpr" (ppr other)
 \begin{code}
 
 tcApp :: RenamedHsExpr -> [RenamedHsExpr]      -- Function and args
-      -> TcType                                        -- Expected result type of application
+      -> Expected TcRhoType                    -- Expected result type of application
       -> TcM TcExpr                            -- Translated fun and args
 
 tcApp (HsApp e1 e2) args res_ty 
@@ -651,7 +664,7 @@ tcApp (HsApp e1 e2) args res_ty
 
 tcApp fun args res_ty
   =    -- First type-check the function
-    tcExpr_id fun                              `thenM` \ (fun', fun_ty) ->
+    tcInferRho fun                             `thenM` \ (fun', fun_ty) ->
 
     addErrCtxt (wrongArgsCtxt "too many" fun args) (
        traceTc (text "tcApp" <+> (ppr fun $$ ppr fun_ty))      `thenM_`
@@ -691,8 +704,10 @@ tcApp fun args res_ty
 
 -- If an error happens we try to figure out whether the
 -- function has been given too many or too few arguments,
--- and say so
-checkArgsCtxt fun args expected_res_ty actual_res_ty tidy_env
+-- and say so.
+-- The ~(Check...) is because in the Infer case the tcSubExp 
+-- definitely won't fail, so we can be certain we're in the Check branch
+checkArgsCtxt fun args ~(Check expected_res_ty) actual_res_ty tidy_env
   = zonkTcType expected_res_ty   `thenM` \ exp_ty' ->
     zonkTcType actual_res_ty     `thenM` \ act_ty' ->
     let
@@ -711,7 +726,7 @@ checkArgsCtxt fun args expected_res_ty actual_res_ty tidy_env
     returnM (env2, message)
 
 
-split_fun_ty :: TcType         -- The type of the function
+split_fun_ty :: TcRhoType      -- The type of the function
             -> Int             -- Number of arguments
             -> TcM ([TcType],  -- Function argument types
                     TcType)    -- Function result types
@@ -733,7 +748,7 @@ tcArg :: RenamedHsExpr                              -- The function (for error messages)
 
 tcArg the_fun (arg, expected_arg_ty, arg_no)
   = addErrCtxt (funAppCtxt the_fun arg arg_no) $
-    tcExpr arg expected_arg_ty
+    tcCheckSigma arg expected_arg_ty
 \end{code}
 
 
@@ -766,7 +781,7 @@ This gets a bit less sharing, but
        b) perhaps fewer separated lambdas
 
 \begin{code}
-tcId :: Name -> TcM (TcExpr, TcType)
+tcId :: Name -> TcM (TcExpr, TcRhoType)
 tcId name      -- Look up the Id and instantiate its type
   =    -- First check whether it's a DataCon
        -- Reason: we must not forget to chuck in the
@@ -871,21 +886,6 @@ tcId name  -- Look up the Id and instantiate its type
                 mkFunTys arg_tys result_ty)
 \end{code}
 
-Typecheck expression which in most cases will be an Id.
-The expression can return a higher-ranked type, such as
-       (forall a. a->a) -> Int
-so we must create a HoleTyVarTy to pass in as the expected tyvar.
-
-\begin{code}
-tcExpr_id :: RenamedHsExpr -> TcM (TcExpr, TcType)
-tcExpr_id (HsVar name) = tcId name
-tcExpr_id expr         = newHoleTyVarTy                        `thenM` \ id_ty ->
-                        tcMonoExpr expr id_ty          `thenM` \ expr' ->
-                        readHoleResult id_ty           `thenM` \ id_ty' ->
-                        returnM (expr', id_ty') 
-\end{code}
-
-
 %************************************************************************
 %*                                                                     *
 \subsection{Record bindings}
@@ -936,7 +936,7 @@ tcRecordBinds tycon ty_args rbinds
                -- The caller of tcRecordBinds has already checked
                -- that all the fields come from the same type
 
-       tcExpr rhs field_ty                     `thenM` \ rhs' ->
+       tcCheckSigma rhs field_ty               `thenM` \ rhs' ->
 
        returnM (sel_id, rhs')
 
@@ -990,17 +990,17 @@ checkMissingFields data_con rbinds
 
 %************************************************************************
 %*                                                                     *
-\subsection{@tcMonoExprs@ typechecks a {\em list} of expressions}
+\subsection{@tcCheckRhos@ typechecks a {\em list} of expressions}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-tcMonoExprs :: [RenamedHsExpr] -> [TcType] -> TcM [TcExpr]
+tcCheckRhos :: [RenamedHsExpr] -> [TcType] -> TcM [TcExpr]
 
-tcMonoExprs [] [] = returnM []
-tcMonoExprs (expr:exprs) (ty:tys)
- = tcMonoExpr  expr  ty                `thenM` \ expr' ->
-   tcMonoExprs exprs tys       `thenM` \ exprs' ->
+tcCheckRhos [] [] = returnM []
+tcCheckRhos (expr:exprs) (ty:tys)
+ = tcCheckRho  expr  ty                `thenM` \ expr' ->
+   tcCheckRhos exprs tys       `thenM` \ exprs' ->
    returnM (expr':exprs')
 \end{code}
 
@@ -1014,16 +1014,17 @@ tcMonoExprs (expr:exprs) (ty:tys)
 Overloaded literals.
 
 \begin{code}
-tcLit :: HsLit -> TcType -> TcM TcExpr
+tcLit :: HsLit -> Expected TcRhoType -> TcM TcExpr
 tcLit (HsLitLit s _) res_ty
-  = tcLookupClass cCallableClassName                   `thenM` \ cCallableClass ->
+  = zapExpectedType res_ty                             `thenM` \ res_ty' ->
+    tcLookupClass cCallableClassName                   `thenM` \ cCallableClass ->
     newDicts (LitLitOrigin (unpackFS s))
-            [mkClassPred cCallableClass [res_ty]]      `thenM` \ dicts ->
+            [mkClassPred cCallableClass [res_ty']]     `thenM` \ dicts ->
     extendLIEs dicts                                   `thenM_`
-    returnM (HsLit (HsLitLit s res_ty))
+    returnM (HsLit (HsLitLit s res_ty'))
 
 tcLit lit res_ty 
-  = unifyTauTy res_ty (hsLitType lit)          `thenM_`
+  = zapExpectedTo res_ty (hsLitType lit)               `thenM_`
     returnM (HsLit lit)
 \end{code}
 
index 1748128..6fe8bdc 100644 (file)
@@ -28,7 +28,7 @@ import RnHsSyn                ( RenamedForeignDecl )
 import TcRnMonad
 import TcMonoType      ( tcHsSigType, UserTypeCtxt(..) )
 import TcHsSyn         ( TcMonoBinds, TypecheckedForeignDecl, TcForeignDecl )
-import TcExpr          ( tcExpr )                      
+import TcExpr          ( tcCheckSigma )                        
 
 import ErrUtils                ( Message )
 import Id              ( Id, mkLocalId, mkVanillaGlobal, setIdLocalExported )
@@ -197,7 +197,7 @@ tcFExport fo@(ForeignExport nm hs_ty spec isDeprec src_loc) =
    addErrCtxt (foreignDeclCtxt fo)     $
 
    tcHsSigType (ForSigCtxt nm) hs_ty   `thenM` \ sig_ty ->
-   tcExpr (HsVar nm) sig_ty            `thenM` \ rhs ->
+   tcCheckSigma (HsVar nm) sig_ty      `thenM` \ rhs ->
 
    tcCheckFEType sig_ty spec           `thenM_`
 
index 9947d82..3d9f210 100644 (file)
@@ -18,8 +18,6 @@ module TcMType (
   putTcTyVar, getTcTyVar,
   newMutTyVar, readMutTyVar, writeMutTyVar, 
 
-  newHoleTyVarTy, readHoleResult, zapToType,
-
   --------------------------------
   -- Instantiation
   tcInstTyVar, tcInstTyVars, tcInstType, 
@@ -54,7 +52,7 @@ import TcType         ( TcType, TcThetaType, TcTauType, TcPredType,
                          tcSplitPhiTy, tcSplitPredTy_maybe, tcSplitAppTy_maybe, 
                          tcSplitTyConApp_maybe, tcSplitForAllTys,
                          tcIsTyVarTy, tcSplitSigmaTy, mkTyConApp,
-                         isUnLiftedType, isIPPred, isHoleTyVar, isTyVarTy,
+                         isUnLiftedType, isIPPred, isTyVarTy,
 
                          mkAppTy, mkTyVarTy, mkTyVarTys, 
                          tyVarsOfPred, getClassPredTys_maybe,
@@ -85,7 +83,7 @@ import PprType                ( pprPred, pprSourceType, pprTheta, pprClassPred )
 import Name            ( Name, setNameUnique, mkSystemTvNameEncoded )
 import VarSet
 import CmdLineOpts     ( dopt, DynFlag(..) )
-import Util            ( nOfThem, isSingleton, equalLength, notNull )
+import Util            ( nOfThem, isSingleton, equalLength, notNull, lengthExceeds )
 import ListSetOps      ( equivClasses, removeDups )
 import Outputable
 \end{code}
@@ -141,42 +139,6 @@ newOpenTypeKind
 
 %************************************************************************
 %*                                                                     *
-\subsection{'hole' type variables}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-newHoleTyVarTy :: TcM TcType
-  = newUnique  `thenM` \ uniq ->
-    newMutTyVar (mkSystemTvNameEncoded uniq FSLIT("h")) openTypeKind HoleTv    `thenM` \ tv ->
-    returnM (TyVarTy tv)
-
-readHoleResult :: TcType -> TcM TcType
--- Read the answer out of a hole, constructed by newHoleTyVarTy
-readHoleResult (TyVarTy tv)
-  = ASSERT( isHoleTyVar tv )
-    getTcTyVar tv              `thenM` \ maybe_res ->
-    case maybe_res of
-       Just ty -> returnM ty
-       Nothing ->  pprPanic "readHoleResult: empty" (ppr tv)
-readHoleResult ty = pprPanic "readHoleResult: not hole" (ppr ty)
-
-zapToType :: TcType -> TcM TcType
-zapToType (TyVarTy tv)
-  | isHoleTyVar tv
-  = getTcTyVar tv              `thenM` \ maybe_res ->
-    case maybe_res of
-       Nothing -> newTyVarTy openTypeKind      `thenM` \ ty ->
-                  putTcTyVar tv ty             `thenM_`
-                  returnM ty
-       Just ty  -> returnM ty  -- No need to loop; we never
-                                       -- have chains of holes
-
-zapToType other_ty = returnM other_ty
-\end{code}                
-
-%************************************************************************
-%*                                                                     *
 \subsection{Type instantiation}
 %*                                                                     *
 %************************************************************************
index 624f36b..bc2ecf5 100644 (file)
@@ -1,12 +1,12 @@
 module TcMatches where
 
-tcGRHSs ::  HsExpr.HsMatchContext Name.Name
+tcGRHSs       :: HsExpr.HsMatchContext Name.Name
              -> RnHsSyn.RenamedGRHSs
-             -> TcType.TcType
+             -> TcUnify.Expected TcType.TcType
              -> TcRnTypes.TcM TcHsSyn.TcGRHSs
 
 tcMatchesFun :: Name.Name
-            -> TcType.TcType
             -> [RnHsSyn.RenamedMatch]
+            -> TcUnify.Expected TcType.TcType
             -> TcRnTypes.TcM [TcHsSyn.TcMatch]
 
index 55c7a0c..dd2c4a8 100644 (file)
@@ -10,7 +10,7 @@ module TcMatches ( tcMatchesFun, tcMatchesCase, tcMatchLambda,
 
 #include "HsVersions.h"
 
-import {-# SOURCE #-}  TcExpr( tcMonoExpr )
+import {-# SOURCE #-}  TcExpr( tcCheckRho, tcMonoExpr )
 
 import HsSyn           ( HsExpr(..), HsBinds(..), Match(..), GRHSs(..), GRHS(..),
                          MonoBinds(..), Stmt(..), HsMatchContext(..), HsStmtContext(..),
@@ -29,13 +29,14 @@ import TcMonoType   ( tcAddScopedTyVars, tcHsSigType, UserTypeCtxt(..) )
 import Inst            ( tcSyntaxName, tcInstCall )
 import TcEnv           ( TcId, tcLookupLocalIds, tcLookupId, tcExtendLocalValEnv, tcExtendLocalValEnv2 )
 import TcPat           ( tcPat, tcMonoPatBndr )
-import TcMType         ( newTyVarTy, newTyVarTys, zonkTcType, zapToType )
+import TcMType         ( newTyVarTy, newTyVarTys, zonkTcType ) 
 import TcType          ( TcType, TcTyVar, TcSigmaType, TcRhoType,
                          tyVarsOfType, tidyOpenTypes, tidyOpenType, isSigmaTy,
                          mkFunTy, isOverloadedTy, liftedTypeKind, openTypeKind, 
                          mkArrowKind, mkAppTy )
 import TcBinds         ( tcBindsAndThen )
-import TcUnify         ( unifyPArrTy,subFunTy, unifyListTy, unifyTauTy,
+import TcUnify         ( Expected(..), newHole, zapExpectedType, zapExpectedBranches, readExpectedType,
+                         unifyTauTy, subFunTy, unifyPArrTy, unifyListTy, unifyFunTy,
                          checkSigTyVarsWrt, tcSubExp, tcGen )
 import TcSimplify      ( tcSimplifyCheck, bindInstsOfLocalFuns )
 import Name            ( Name )
@@ -66,11 +67,11 @@ same number of arguments before using @tcMatches@ to do the work.
 
 \begin{code}
 tcMatchesFun :: Name
-            -> TcType          -- Expected type
             -> [RenamedMatch]
+            -> Expected TcRhoType              -- Expected type
             -> TcM [TcMatch]
 
-tcMatchesFun fun_name expected_ty matches@(first_match:_)
+tcMatchesFun fun_name matches@(first_match:_) expected_ty
   =     -- Check that they all have the same no of arguments
         -- Set the location to that of the first equation, so that
         -- any inter-equation error messages get some vaguely
@@ -95,16 +96,29 @@ parser guarantees that each equation has exactly one argument.
 
 \begin{code}
 tcMatchesCase :: [RenamedMatch]                -- The case alternatives
-             -> TcType                 -- Type of whole case expressions
-             -> TcM (TcType,           -- Inferred type of the scrutinee
-                       [TcMatch])      -- Translated alternatives
+             -> Expected TcRhoType     -- Type of whole case expressions
+             -> TcM (TcRhoType,        -- Inferred type of the scrutinee
+                     [TcMatch])        -- Translated alternatives
+
+tcMatchesCase matches (Check expr_ty)
+  =    -- This case is a bit yukky, because it prevents the
+       -- scrutinee being higher-ranked, which might just possible
+       -- matter if we were seq'ing on it.  But it's awkward to fix.
+    newTyVarTy openTypeKind                                            `thenM` \ scrut_ty ->
+    tcMatches CaseAlt matches (Check (mkFunTy scrut_ty expr_ty))       `thenM` \ matches' ->
+    returnM (scrut_ty, matches')
 
-tcMatchesCase matches expr_ty
-  = newTyVarTy openTypeKind                                    `thenM` \ scrut_ty ->
-    tcMatches CaseAlt matches (mkFunTy scrut_ty expr_ty)       `thenM` \ matches' ->
+tcMatchesCase matches (Infer hole)
+  = newHole                                    `thenM` \ fun_hole ->
+    tcMatches CaseAlt matches (Infer fun_hole) `thenM` \ matches' ->
+    readMutVar fun_hole                                `thenM` \ fun_ty ->
+       -- The result of tcMatches is bound to be a function type
+    unifyFunTy fun_ty                          `thenM` \ (scrut_ty, res_ty) ->
+    writeMutVar hole res_ty                    `thenM_` 
     returnM (scrut_ty, matches')
+    
 
-tcMatchLambda :: RenamedMatch -> TcType -> TcM TcMatch
+tcMatchLambda :: RenamedMatch -> Expected TcRhoType -> TcM TcMatch
 tcMatchLambda match res_ty = tcMatch LambdaExpr match res_ty
 \end{code}
 
@@ -112,21 +126,17 @@ tcMatchLambda match res_ty = tcMatch LambdaExpr match res_ty
 \begin{code}
 tcMatches :: RenamedMatchContext 
          -> [RenamedMatch]
-         -> TcType
+         -> Expected TcRhoType
          -> TcM [TcMatch]
 
-tcMatches ctxt matches expected_ty
-  =    -- If there is more than one branch, and expected_ty is a 'hole',
+tcMatches ctxt matches exp_ty
+  =    -- If there is more than one branch, and exp_ty is a 'hole',
        -- all branches must be types, not type schemes, otherwise the
-       -- in which we check them would affect the result.
-    (if lengthExceeds matches 1 then
-       zapToType expected_ty
-     else
-       returnM expected_ty)                    `thenM` \ expected_ty' ->
-
-    mappM (tc_match expected_ty') matches
+       -- order in which we check them would affect the result.
+    zapExpectedBranches matches exp_ty         `thenM` \ exp_ty' ->
+    mappM (tc_match exp_ty') matches
   where
-    tc_match expected_ty match = tcMatch ctxt match expected_ty
+    tc_match exp_ty match = tcMatch ctxt match exp_ty
 \end{code}
 
 
@@ -139,7 +149,7 @@ tcMatches ctxt matches expected_ty
 \begin{code}
 tcMatch :: RenamedMatchContext
        -> RenamedMatch
-       -> TcType       -- Expected result-type of the Match.
+       -> Expected TcRhoType   -- Expected result-type of the Match.
                        -- Early unification with this guy gives better error messages
                        -- We regard the Match as having type 
                        --      (ty1 -> ... -> tyn -> result_ty)
@@ -160,14 +170,17 @@ tcMatch ctxt match@(Match pats maybe_rhs_sig grhss) expected_ty
 
            Just sig ->  tcAddScopedTyVars [sig]        $
                                -- Bring into scope the type variables in the signature
-                        tcHsSigType ResSigCtxt sig                             `thenM` \ sig_ty ->
-                        tcThingWithSig sig_ty (tcGRHSs ctxt grhss) rhs_ty      `thenM` \ (co_fn, grhss') ->
-                        returnM (lift_grhss co_fn rhs_ty grhss')
-
--- lift_grhss pushes the coercion down to the right hand sides,
--- because there is no convenient place to hang it otherwise.
-lift_grhss co_fn rhs_ty grhss 
-  | isIdCoercion co_fn = grhss
+                        tcHsSigType ResSigCtxt sig                                     `thenM` \ sig_ty ->
+                        tcThingWithSig sig_ty (tcGRHSs ctxt grhss . Check) rhs_ty      `thenM` \ (co_fn, grhss') ->
+
+                       -- Pushes the coercion down to the right hand sides,
+                       -- because there is no convenient place to hang it otherwise.
+                        if isIdCoercion co_fn then
+                               returnM grhss'
+                        else
+                        readExpectedType rhs_ty                `thenM` \ rhs_ty' ->
+                        returnM (lift_grhss co_fn rhs_ty' grhss')
+
 lift_grhss co_fn rhs_ty (GRHSs grhss binds ty)
   = GRHSs (map lift_grhs grhss) binds rhs_ty   -- Change the type, since the coercion does
   where
@@ -183,29 +196,44 @@ glue_on binds1 (GRHSs grhss binds2 ty)
 
 
 tcGRHSs :: RenamedMatchContext -> RenamedGRHSs
-       -> TcType
+       -> Expected TcRhoType
        -> TcM TcGRHSs
 
-tcGRHSs ctxt (GRHSs grhss binds _) expected_ty
-  = tcBindsAndThen glue_on binds (tc_grhss grhss)
-  where
-    m_ty =  (\ty -> ty, expected_ty) 
-
-    tc_grhss grhss
-       = mappM tc_grhs grhss       `thenM` \ grhss' ->
-         returnM (GRHSs grhss' EmptyBinds expected_ty)
-
-    tc_grhs (GRHS guarded locn)
+  -- Special case when there is just one equation with a degenerate 
+  -- guard; then we pass in the full Expected type, so that we get
+  -- good inference from simple things like
+  --   f = \(x::forall a.a->a) -> <stuff>
+  -- This is a consequence of the fact that tcStmts takes a TcType,
+  -- not a Expected TcType, a decision we could revisit if necessary
+tcGRHSs ctxt (GRHSs [GRHS [ResultStmt rhs loc1] loc2] binds _) exp_ty
+  = tcBindsAndThen glue_on binds       $
+    tcMonoExpr rhs exp_ty              `thenM` \ rhs' ->
+    readExpectedType exp_ty            `thenM` \ exp_ty' ->
+    returnM (GRHSs [GRHS [ResultStmt rhs' loc1] loc2] EmptyBinds exp_ty')
+
+tcGRHSs ctxt (GRHSs grhss binds _) exp_ty
+  = tcBindsAndThen glue_on binds       $
+    zapExpectedType exp_ty             `thenM` \ exp_ty' ->
+       -- Even if there is only one guard, we zap the RHS type to
+       -- a monotype.  Reason: it makes tcStmts much easier,
+       -- and even a one-armed guard has a notional second arm
+    let
+      tc_grhs (GRHS guarded locn)
        = addSrcLoc locn                        $
          tcStmts (PatGuard ctxt) m_ty guarded  `thenM` \ guarded' ->
          returnM (GRHS guarded' locn)
+
+      m_ty =  (\ty -> ty, exp_ty') 
+    in
+    mappM tc_grhs grhss                        `thenM` \ grhss' ->
+    returnM (GRHSs grhss' EmptyBinds exp_ty')
 \end{code}
 
 
 \begin{code}
 tcThingWithSig :: TcSigmaType          -- Type signature
               -> (TcRhoType -> TcM r)  -- How to type check the thing inside
-              -> TcRhoType             -- Overall expected result type
+              -> Expected TcRhoType    -- Overall expected result type
               -> TcM (ExprCoFn, r)
 -- Used for expressions with a type signature, and for result type signatures
 
@@ -235,8 +263,8 @@ tcThingWithSig sig_ty thing_inside res_ty
 
 \begin{code}     
 tcMatchPats
-       :: [RenamedPat] -> TcType
-       -> (TcType -> TcM a)
+       :: [RenamedPat] -> Expected TcRhoType
+       -> (Expected TcRhoType -> TcM a)
        -> TcM ([TcPat], a, TcHsBinds)
 -- Typecheck the patterns, extend the environment to bind the variables,
 -- do the thing inside, use any existentially-bound dictionaries to 
@@ -260,8 +288,9 @@ tcMatchPats pats expected_ty thing_inside
        -- I'm a bit concerned that lie_req1 from an 'inner' pattern in the list
        -- might need (via lie_req2) something made available from an 'outer' 
        -- pattern.  But it's inconvenient to deal with, and I can't find an example
-    tcCheckExistentialPat ex_tvs ex_ids ex_lie lie_req expected_ty     `thenM` \ ex_binds ->
-       -- NB: we *must* pass "expected_ty" not "result_ty" to tcCheckExistentialPat
+    readExpectedType expected_ty                               `thenM` \ exp_ty ->
+    tcCheckExistentialPat ex_tvs ex_ids ex_lie lie_req exp_ty  `thenM` \ ex_binds ->
+       -- NB: we *must* pass "exp_ty" not "result_ty" to tcCheckExistentialPat
        -- For example, we must reject this program:
        --      data C = forall a. C (a -> Int) 
        --      f (C g) x = g x
@@ -341,7 +370,8 @@ tcCheckExistentialPat ex_tvs ex_ids ex_lie lie_req match_ty
 %************************************************************************
 
 \begin{code}
-tcDoStmts :: HsStmtContext Name -> [RenamedStmt] -> [Name] -> TcType
+tcDoStmts :: HsStmtContext Name -> [RenamedStmt] -> [Name] 
+         -> TcRhoType          -- To keep it simple, we don't have an "expected" type here
          -> TcM (TcMonoBinds, [TcStmt], [Id])
 tcDoStmts PArrComp stmts method_names res_ty
   = unifyPArrTy res_ty                           `thenM` \elt_ty ->
@@ -425,7 +455,9 @@ tcStmtsAndThen
        :: (TcStmt -> thing -> thing)   -- Combiner
        -> HsStmtContext Name
         -> (TcType -> TcType, TcType)  -- m, the relationship type of pat and rhs in pat <- rhs
-                                       -- elt_ty, where type of the comprehension is (m elt_ty)
+                                       -- res_ty, the type of the entire comprehension
+                                       --         used at the end for the type of (return x)
+                                       --         or the final expression in do-notation
         -> [RenamedStmt]
        -> TcM thing
         -> TcM thing
@@ -446,11 +478,11 @@ tcStmtAndThen combine do_or_lc m_ty (LetStmt binds) thing_inside
        thing_inside
 
 tcStmtAndThen combine do_or_lc m_ty@(m,elt_ty) stmt@(BindStmt pat exp src_loc) thing_inside
-  = addSrcLoc src_loc                                  $
-    addErrCtxt (stmtCtxt do_or_lc stmt)                $
-    newTyVarTy liftedTypeKind                          `thenM` \ pat_ty ->
-    tcMonoExpr exp (m pat_ty)                          `thenM` \ exp' ->
-    tcMatchPats [pat] (mkFunTy pat_ty (m elt_ty))      (\ _ ->
+  = addSrcLoc src_loc                                          $
+    addErrCtxt (stmtCtxt do_or_lc stmt)                                $
+    newTyVarTy liftedTypeKind                                  `thenM` \ pat_ty ->
+    tcCheckRho exp (m pat_ty)                                  `thenM` \ exp' ->
+    tcMatchPats [pat] (Check (mkFunTy pat_ty (m elt_ty)))      (\ _ ->
        popErrCtxt thing_inside
     )                                                  `thenM` \ ([pat'], thing, dict_binds) ->
     returnM (combine (BindStmt pat' exp' src_loc)
@@ -499,21 +531,21 @@ tcStmtAndThen combine do_or_lc m_ty (RecStmt recNames stmts _) thing_inside
 
     -- Unify the types of the "final" Ids with those of "knot-tied" Ids
     tc_ret (rec_name, mono_ty)
-       = tcLookupId rec_name                   `thenM` \ poly_id ->
+       = tcLookupId rec_name                           `thenM` \ poly_id ->
                -- poly_id may have a polymorphic type
                -- but mono_ty is just a monomorphic type variable
-         tcSubExp mono_ty (idType poly_id)     `thenM` \ co_fn ->
+         tcSubExp (Check mono_ty) (idType poly_id)     `thenM` \ co_fn ->
          returnM (co_fn <$> HsVar poly_id) 
 
        -- ExprStmt
-tcStmtAndThen combine do_or_lc m_ty@(m, res_elt_ty) stmt@(ExprStmt exp _ locn) thing_inside
+tcStmtAndThen combine do_or_lc m_ty@(m, _) stmt@(ExprStmt exp _ locn) thing_inside
   = addErrCtxt (stmtCtxt do_or_lc stmt) (
        if isDoExpr do_or_lc then
                newTyVarTy openTypeKind         `thenM` \ any_ty ->
-               tcMonoExpr exp (m any_ty)       `thenM` \ exp' ->
+               tcCheckRho exp (m any_ty)       `thenM` \ exp' ->
                returnM (ExprStmt exp' any_ty locn)
        else
-               tcMonoExpr exp boolTy           `thenM` \ exp' ->
+               tcCheckRho exp boolTy           `thenM` \ exp' ->
                returnM (ExprStmt exp' boolTy locn)
     )                                          `thenM` \ stmt' ->
 
@@ -525,9 +557,9 @@ tcStmtAndThen combine do_or_lc m_ty@(m, res_elt_ty) stmt@(ExprStmt exp _ locn) t
 tcStmtAndThen combine do_or_lc m_ty@(m, res_elt_ty) stmt@(ResultStmt exp locn) thing_inside
   = addErrCtxt (resCtxt do_or_lc stmt) (
        if isDoExpr do_or_lc then
-               tcMonoExpr exp (m res_elt_ty)
+               tcCheckRho exp (m res_elt_ty)
        else
-               tcMonoExpr exp res_elt_ty
+               tcCheckRho exp res_elt_ty
     )                                          `thenM` \ exp' ->
 
     thing_inside                               `thenM` \ thing ->
index bfd90a6..c353085 100644 (file)
@@ -21,15 +21,15 @@ import Inst         ( InstOrigin(..),
                          newMethodFromName, newOverloadedLit, newDicts,
                          instToId, tcInstDataCon, tcSyntaxName
                        )
-import Id              ( mkLocalId, mkSysLocal )
+import Id              ( idType, mkLocalId, mkSysLocal )
 import Name            ( Name )
 import FieldLabel      ( fieldLabelName )
 import TcEnv           ( tcLookupClass, tcLookupDataCon, tcLookupId )
-import TcMType                 ( newTyVarTy, zapToType, arityErr )
+import TcMType                 ( newTyVarTy, arityErr )
 import TcType          ( TcType, TcTyVar, TcSigmaType, 
                          mkClassPred, liftedTypeKind )
-import TcUnify         ( tcSubOff, TcHoleType, 
-                         unifyTauTy, unifyListTy, unifyPArrTy, unifyTupleTy )  
+import TcUnify         ( tcSubOff, Expected(..), readExpectedType, zapExpectedType, 
+                         unifyTauTy, zapToListTy, zapToPArrTy, zapToTupleTy )  
 import TcMonoType      ( tcHsSigType, UserTypeCtxt(..) )
 
 import TysWiredIn      ( stringTy )
@@ -50,7 +50,7 @@ import FastString
 %************************************************************************
 
 \begin{code}
-type BinderChecker = Name -> TcSigmaType -> TcM (PatCoFn, TcId)
+type BinderChecker = Name -> Expected TcSigmaType -> TcM (PatCoFn, TcId)
                        -- How to construct a suitable (monomorphic)
                        -- Id for variables found in the pattern
                        -- The TcSigmaType is the expected type 
@@ -67,7 +67,7 @@ tcMonoPatBndr :: BinderChecker
   -- so there's no polymorphic guy to worry about
 
 tcMonoPatBndr binder_name pat_ty 
-  = zapToType pat_ty   `thenM` \ pat_ty' ->
+  = zapExpectedType pat_ty     `thenM` \ pat_ty' ->
        -- If there are *no constraints* on the pattern type, we
        -- revert to good old H-M typechecking, making
        -- the type of the binder into an *ordinary* 
@@ -91,9 +91,9 @@ tcMonoPatBndr binder_name pat_ty
 tcPat :: BinderChecker
       -> RenamedPat
 
-      -> TcHoleType    -- Expected type derived from the context
-                       --      In the case of a function with a rank-2 signature,
-                       --      this type might be a forall type.
+      -> Expected TcSigmaType  -- Expected type derived from the context
+                               --      In the case of a function with a rank-2 signature,
+                               --      this type might be a forall type.
 
       -> TcM (TcPat, 
                Bag TcTyVar,    -- TyVars bound by the pattern
@@ -129,13 +129,18 @@ tcPat tc_bndr (LazyPat pat) pat_ty
     returnM (LazyPat pat', tvs, ids, lie_avail)
 
 tcPat tc_bndr pat_in@(AsPat name pat) pat_ty
-  = tc_bndr name pat_ty                        `thenM` \ (co_fn, bndr_id) ->
-    tcPat tc_bndr pat pat_ty           `thenM` \ (pat', tvs, ids, lie_avail) ->
+  = tc_bndr name pat_ty                                `thenM` \ (co_fn, bndr_id) ->
+    tcPat tc_bndr pat (Check (idType bndr_id)) `thenM` \ (pat', tvs, ids, lie_avail) ->
+       -- NB: if we have:
+       --      \ (y@(x::forall a. a->a)) = e
+       -- we'll fail.  The as-pattern infers a monotype for 'y', which then
+       -- fails to unify with the polymorphic type for 'x'.  This could be
+       -- fixed, but only with a bit more work.
     returnM (co_fn <$> (AsPat bndr_id pat'), 
              tvs, (name, bndr_id) `consBag` ids, lie_avail)
 
 tcPat tc_bndr (WildPat _) pat_ty
-  = zapToType pat_ty                   `thenM` \ pat_ty' ->
+  = zapExpectedType pat_ty             `thenM` \ pat_ty' ->
        -- We might have an incoming 'hole' type variable; no annotation
        -- so zap it to a type.  Rather like tcMonoPatBndr.
     returnM (WildPat pat_ty', emptyBag, emptyBag, [])
@@ -150,7 +155,7 @@ tcPat tc_bndr pat_in@(SigPatIn pat sig) pat_ty
   = addErrCtxt (patCtxt pat_in)        $
     tcHsSigType PatSigCtxt sig         `thenM` \ sig_ty ->
     tcSubPat sig_ty pat_ty             `thenM` \ co_fn ->
-    tcPat tc_bndr pat sig_ty           `thenM` \ (pat', tvs, ids, lie_avail) ->
+    tcPat tc_bndr pat (Check sig_ty)   `thenM` \ (pat', tvs, ids, lie_avail) ->
     returnM (co_fn <$> pat', tvs, ids, lie_avail)
 \end{code}
 
@@ -164,20 +169,20 @@ tcPat tc_bndr pat_in@(SigPatIn pat sig) pat_ty
 \begin{code}
 tcPat tc_bndr pat_in@(ListPat pats _) pat_ty
   = addErrCtxt (patCtxt pat_in)                $
-    unifyListTy pat_ty                         `thenM` \ elem_ty ->
+    zapToListTy pat_ty                         `thenM` \ elem_ty ->
     tcPats tc_bndr pats (repeat elem_ty)       `thenM` \ (pats', tvs, ids, lie_avail) ->
     returnM (ListPat pats' elem_ty, tvs, ids, lie_avail)
 
 tcPat tc_bndr pat_in@(PArrPat pats _) pat_ty
   = addErrCtxt (patCtxt pat_in)                $
-    unifyPArrTy pat_ty                         `thenM` \ elem_ty ->
+    zapToPArrTy pat_ty                         `thenM` \ elem_ty ->
     tcPats tc_bndr pats (repeat elem_ty)       `thenM` \ (pats', tvs, ids, lie_avail) ->
     returnM (PArrPat pats' elem_ty, tvs, ids, lie_avail)
 
 tcPat tc_bndr pat_in@(TuplePat pats boxity) pat_ty
   = addErrCtxt (patCtxt pat_in)        $
 
-    unifyTupleTy boxity arity pat_ty           `thenM` \ arg_tys ->
+    zapToTupleTy boxity arity pat_ty           `thenM` \ arg_tys ->
     tcPats tc_bndr pats arg_tys                `thenM` \ (pats', tvs, ids, lie_avail) ->
 
        -- possibly do the "make all tuple-pats irrefutable" test:
@@ -238,46 +243,51 @@ tcPat tc_bndr pat_in@(ConPatIn con_name arg_pats) pat_ty
 \begin{code}
 tcPat tc_bndr (LitPat lit@(HsLitLit s _)) pat_ty 
        -- cf tcExpr on LitLits
-  = tcLookupClass cCallableClassName           `thenM` \ cCallableClass ->
+  = zapExpectedType pat_ty                             `thenM` \ pat_ty' ->
+    tcLookupClass cCallableClassName                   `thenM` \ cCallableClass ->
     newDicts (LitLitOrigin (unpackFS s))
-            [mkClassPred cCallableClass [pat_ty]]      `thenM` \ dicts ->
+            [mkClassPred cCallableClass [pat_ty']]     `thenM` \ dicts ->
     extendLIEs dicts                                   `thenM_`
-    returnM (LitPat (HsLitLit s pat_ty), emptyBag, emptyBag, [])
+    returnM (LitPat (HsLitLit s pat_ty'), emptyBag, emptyBag, [])
 
 tcPat tc_bndr pat@(LitPat lit@(HsString _)) pat_ty
-  = unifyTauTy pat_ty stringTy         `thenM_` 
+  = zapExpectedType pat_ty             `thenM` \ pat_ty' ->
+    unifyTauTy pat_ty' stringTy                `thenM_` 
     tcLookupId eqStringName            `thenM` \ eq_id ->
     returnM (NPatOut lit stringTy (HsVar eq_id `HsApp` HsLit lit), 
-             emptyBag, emptyBag, [])
+           emptyBag, emptyBag, [])
 
 tcPat tc_bndr (LitPat simple_lit) pat_ty
-  = unifyTauTy pat_ty (hsLitType simple_lit)           `thenM_` 
+  = zapExpectedType pat_ty                     `thenM` \ pat_ty' ->
+    unifyTauTy pat_ty' (hsLitType simple_lit)  `thenM_` 
     returnM (LitPat simple_lit, emptyBag, emptyBag, [])
 
 tcPat tc_bndr pat@(NPatIn over_lit mb_neg) pat_ty
-  = newOverloadedLit origin over_lit pat_ty            `thenM` \ pos_lit_expr ->
-    newMethodFromName origin pat_ty eqName             `thenM` \ eq ->
+  = zapExpectedType pat_ty                     `thenM` \ pat_ty' ->
+    newOverloadedLit origin over_lit pat_ty'   `thenM` \ pos_lit_expr ->
+    newMethodFromName origin pat_ty' eqName    `thenM` \ eq ->
     (case mb_neg of
        Nothing  -> returnM pos_lit_expr        -- Positive literal
        Just neg ->     -- Negative literal
                        -- The 'negate' is re-mappable syntax
-                   tcSyntaxName origin pat_ty negateName neg   `thenM` \ (neg_expr, _) ->
+                   tcSyntaxName origin pat_ty' negateName neg  `thenM` \ (neg_expr, _) ->
                    returnM (HsApp neg_expr pos_lit_expr)
     )                                                          `thenM` \ lit_expr ->
 
-    returnM (NPatOut lit' pat_ty (HsApp (HsVar eq) lit_expr),
-            emptyBag, emptyBag, [])
-  where
-    origin = PatOrigin pat
-
+    let
        -- The literal in an NPatIn is always positive...
        -- But in NPat, the literal is used to find identical patterns
        --      so we must negate the literal when necessary!
-    lit' = case (over_lit, mb_neg) of
-            (HsIntegral i _, Nothing)   -> HsInteger i
-            (HsIntegral i _, Just _)    -> HsInteger (-i)
-            (HsFractional f _, Nothing) -> HsRat f pat_ty
-            (HsFractional f _, Just _)  -> HsRat (-f) pat_ty
+       lit' = case (over_lit, mb_neg) of
+                (HsIntegral i _,   Nothing) -> HsInteger i
+                (HsIntegral i _,   Just _)  -> HsInteger (-i)
+                (HsFractional f _, Nothing) -> HsRat f pat_ty'
+                (HsFractional f _, Just _)  -> HsRat (-f) pat_ty'
+    in
+    returnM (NPatOut lit' pat_ty' (HsApp (HsVar eq) lit_expr),
+            emptyBag, emptyBag, [])
+  where
+    origin = PatOrigin pat
 \end{code}
 
 %************************************************************************
@@ -288,12 +298,15 @@ tcPat tc_bndr pat@(NPatIn over_lit mb_neg) pat_ty
 
 \begin{code}
 tcPat tc_bndr pat@(NPlusKPatIn name lit@(HsIntegral i _) minus_name) pat_ty
-  = tc_bndr name pat_ty                                `thenM` \ (co_fn, bndr_id) ->
-    newOverloadedLit origin lit pat_ty         `thenM` \ over_lit_expr ->
-    newMethodFromName origin pat_ty geName     `thenM` \ ge ->
+  = tc_bndr name pat_ty                                 `thenM` \ (co_fn, bndr_id) ->
+    let 
+       pat_ty' = idType bndr_id
+    in
+    newOverloadedLit origin lit pat_ty'                 `thenM` \ over_lit_expr ->
+    newMethodFromName origin pat_ty' geName     `thenM` \ ge ->
 
        -- The '-' part is re-mappable syntax
-    tcSyntaxName origin pat_ty minusName minus_name    `thenM` \ (minus_expr, _) ->
+    tcSyntaxName origin pat_ty' minusName minus_name   `thenM` \ (minus_expr, _) ->
 
     returnM (NPlusKPatOut bndr_id i 
                           (SectionR (HsVar ge) over_lit_expr)
@@ -303,6 +316,7 @@ tcPat tc_bndr pat@(NPlusKPatIn name lit@(HsIntegral i _) minus_name) pat_ty
     origin = PatOrigin pat
 \end{code}
 
+
 %************************************************************************
 %*                                                                     *
 \subsection{Lists of patterns}
@@ -321,9 +335,9 @@ tcPats :: BinderChecker                     -- How to deal with variables
 
 tcPats tc_bndr [] tys = returnM ([], emptyBag, emptyBag, [])
 
-tcPats tc_bndr (ty:tys) (pat:pats)
-  = tcPat tc_bndr ty pat       `thenM` \ (pat',  tvs1, ids1, lie_avail1) ->
-    tcPats tc_bndr tys pats    `thenM` \ (pats', tvs2, ids2, lie_avail2) ->
+tcPats tc_bndr (pat:pats) (ty:tys)
+  = tcPat tc_bndr pat (Check ty)       `thenM` \ (pat',  tvs1, ids1, lie_avail1) ->
+    tcPats tc_bndr pats tys            `thenM` \ (pats', tvs2, ids2, lie_avail2) ->
 
     returnM (pat':pats', 
              tvs1 `unionBags` tvs2, ids1 `unionBags` ids2, 
@@ -357,8 +371,8 @@ tcConStuff tc_bndr data_con (InfixCon p1 p2) arg_tys
            (arityErr "Constructor" data_con con_arity 2)       `thenM_`
 
        -- Check arguments
-    tcPat tc_bndr p1 ty1       `thenM` \ (p1', tvs1, ids1, lie_avail1) ->
-    tcPat tc_bndr p2 ty2       `thenM` \ (p2', tvs2, ids2, lie_avail2) ->
+    tcPat tc_bndr p1 (Check ty1)       `thenM` \ (p1', tvs1, ids1, lie_avail1) ->
+    tcPat tc_bndr p2 (Check ty2)       `thenM` \ (p2', tvs2, ids2, lie_avail2) ->
 
     returnM (InfixCon p1' p2', 
              tvs1 `unionBags` tvs2, ids1 `unionBags` ids2, 
@@ -405,7 +419,7 @@ tcConStuff tc_bndr data_con (RecCon rpats) arg_tys
                returnM (sel_id, pat_ty)
        )                                               `thenM` \ (sel_id, pat_ty) ->
 
-       tcPat tc_bndr rhs_pat pat_ty    `thenM` \ (rhs_pat', tvs2, ids2, lie_avail2) ->
+       tcPat tc_bndr rhs_pat (Check pat_ty)    `thenM` \ (rhs_pat', tvs2, ids2, lie_avail2) ->
 
        returnM ((sel_id, rhs_pat') : rpats',
                  tvs1 `unionBags` tvs2,
@@ -436,7 +450,7 @@ tcSubPat does the work
                (forall a. a->a in the example)
 
 \begin{code}
-tcSubPat :: TcSigmaType -> TcHoleType -> TcM PatCoFn
+tcSubPat :: TcSigmaType -> Expected TcSigmaType -> TcM PatCoFn
 
 tcSubPat sig_ty exp_ty
  = tcSubOff sig_ty exp_ty              `thenM` \ co_fn ->
@@ -446,10 +460,11 @@ tcSubPat sig_ty exp_ty
        returnM idCoercion
    else
    newUnique                           `thenM` \ uniq ->
+   readExpectedType exp_ty             `thenM` \ exp_ty' ->
    let
-       arg_id  = mkSysLocal FSLIT("sub") uniq exp_ty
+       arg_id  = mkSysLocal FSLIT("sub") uniq exp_ty'
        the_fn  = DictLam [arg_id] (co_fn <$> HsVar arg_id)
-       pat_co_fn p = SigPatOut p exp_ty the_fn
+       pat_co_fn p = SigPatOut p exp_ty' the_fn
    in
    returnM (mkCoercion pat_co_fn)
 \end{code}
index 5bb8c6c..a6f3331 100644 (file)
@@ -45,7 +45,7 @@ import TcHsSyn                ( TypecheckedHsExpr, TypecheckedRuleDecl,
                          zonkTopExpr, zonkTopBndrs
                        )
 
-import TcExpr          ( tcExpr_id )
+import TcExpr          ( tcInferRho )
 import TcRnMonad
 import TcMType         ( newTyVarTy, zonkTcType )
 import TcType          ( Type, liftedTypeKind, 
@@ -444,8 +444,7 @@ tcRnExpr hsc_env pcs ictxt rdr_expr
     
        -- Now typecheck the expression; 
        -- it might have a rank-2 type (e.g. :t runST)
-       -- Hence the hole type (c.f. TcExpr.tcExpr_id)
-    ((tc_expr, res_ty), lie)      <- getLIE (tcExpr_id rn_expr) ;
+    ((tc_expr, res_ty), lie)      <- getLIE (tcInferRho rn_expr) ;
     ((qtvs, _, dict_ids), lie_top) <- getLIE (tcSimplifyInfer smpl_doc (tyVarsOfType res_ty) lie)  ;
     tcSimplifyTop lie_top ;
 
@@ -1116,7 +1115,7 @@ check_main ghci_mode tcg_env
        
        -- $main :: IO () = runIO main
        let { rhs = HsApp (HsVar runIOName) (HsVar main_name) } ;
-       (main_expr, ty) <- tcExpr_id rhs ;
+       (main_expr, ty) <- tcInferRho rhs ;
 
        let { dollar_main_id = setIdLocalExported (mkLocalId dollarMainName ty) ;
              main_bind      = VarMonoBind dollar_main_id main_expr ;
index 492e9ab..a26faa8 100644 (file)
@@ -15,10 +15,11 @@ import TcHsSyn              ( TypecheckedRuleDecl, mkHsLet )
 import TcRnMonad
 import TcSimplify      ( tcSimplifyToDicts, tcSimplifyInferCheck )
 import TcMType         ( newTyVarTy )
+import TcUnify         ( Expected(..) )
 import TcType          ( tyVarsOfTypes, openTypeKind )
 import TcIfaceSig      ( tcCoreExpr, tcCoreLamBndrs )
 import TcMonoType      ( tcHsSigType, UserTypeCtxt(..), tcAddScopedTyVars )
-import TcExpr          ( tcMonoExpr )
+import TcExpr          ( tcCheckRho )
 import TcEnv           ( tcExtendLocalValEnv, tcLookupGlobalId, tcLookupId )
 import Inst            ( instToId )
 import Id              ( idType, mkLocalId )
@@ -63,8 +64,8 @@ tcRule (HsRule name act vars lhs rhs src_loc)
        tcExtendLocalValEnv ids                 $
        
                -- Now LHS and RHS
-       getLIE (tcMonoExpr lhs rule_ty)         `thenM` \ (lhs', lhs_lie) ->
-       getLIE (tcMonoExpr rhs rule_ty)         `thenM` \ (rhs', rhs_lie) ->
+       getLIE (tcCheckRho lhs rule_ty) `thenM` \ (lhs', lhs_lie) ->
+       getLIE (tcCheckRho rhs rule_ty) `thenM` \ (rhs', rhs_lie) ->
        
        returnM (ids, lhs', rhs', lhs_lie, rhs_lie)
     )                          `thenM` \ (ids, lhs', rhs', lhs_lie, rhs_lie) ->
index 5f05962..6a2c4d7 100644 (file)
@@ -21,7 +21,7 @@ import Convert                ( convertToHsExpr, convertToHsDecls )
 import RnExpr          ( rnExpr )
 import RdrHsSyn                ( RdrNameHsExpr, RdrNameHsDecl )
 import RnHsSyn         ( RenamedHsExpr )
-import TcExpr          ( tcMonoExpr )
+import TcExpr          ( tcCheckRho )
 import TcHsSyn         ( TcExpr, TypecheckedHsExpr, mkHsLet, zonkTopExpr )
 import TcSimplify      ( tcSimplifyTop, tcSimplifyBracket )
 import TcUnify         ( unifyTauTy )
@@ -97,8 +97,8 @@ tcBracket brack res_ty
 
 tc_bracket :: HsBracket Name -> TcM TcType
 tc_bracket (ExpBr expr) 
-  = newTyVarTy openTypeKind            `thenM` \ any_ty ->
-    tcMonoExpr expr any_ty             `thenM_`
+  = newTyVarTy openTypeKind    `thenM` \ any_ty ->
+    tcCheckRho expr any_ty     `thenM_`
     tcMetaTy exprTyConName
        -- Result type is Expr (= Q Exp)
 
@@ -148,7 +148,7 @@ tcSpliceExpr name expr res_ty
     tcMetaTy exprTyConName                     `thenM` \ meta_exp_ty ->
     setStage (Splice next_level) (
        setLIEVar lie_var          $
-       tcMonoExpr expr meta_exp_ty
+       tcCheckRho expr meta_exp_ty
     )                                          `thenM` \ expr' ->
 
        -- Write the pending splice into the bucket
@@ -162,7 +162,7 @@ tcSpliceExpr name expr res_ty
 -- Note that we do not decrement the level (to -1) before 
 -- typechecking the expression.  For example:
 --     f x = $( ...$(g 3) ... )
--- The recursive call to tcMonoExpr will simply expand the 
+-- The recursive call to tcCheckRho will simply expand the 
 -- inner escape before dealing with the outer one
 
 tcTopSplice expr res_ty
@@ -188,7 +188,7 @@ tcTopSplice expr res_ty
     initRn SourceMode (rnExpr expr2)           `thenM` \ (exp3, fvs) ->
     importSupportingDecls fvs                  `thenM` \ env ->
 
-    setGblEnv env (tcMonoExpr exp3 res_ty)
+    setGblEnv env (tcCheckRho exp3 res_ty)
 
 
 tcTopSpliceExpr :: RenamedHsExpr -> TcType -> TcM TypecheckedHsExpr
@@ -201,7 +201,7 @@ tcTopSpliceExpr expr meta_ty
     setStage topSpliceStage $
 
        -- Typecheck the expression
-    getLIE (tcMonoExpr expr meta_ty)   `thenM` \ (expr', lie) ->
+    getLIE (tcCheckRho expr meta_ty)   `thenM` \ (expr', lie) ->
 
        -- Solve the constraints
     tcSimplifyTop lie                  `thenM` \ const_binds ->
index 3282d33..e2ec116 100644 (file)
@@ -26,7 +26,7 @@ module TcType (
 
   --------------------------------
   -- TyVarDetails
-  TyVarDetails(..), isUserTyVar, isSkolemTyVar, isHoleTyVar, 
+  TyVarDetails(..), isUserTyVar, isSkolemTyVar, 
   tyVarBindingInfo,
 
   --------------------------------
@@ -253,12 +253,7 @@ why Var.lhs shouldn't actually have the definition, but it "belongs" here.
 
 \begin{code}
 data TyVarDetails
-  = HoleTv     -- Used *only* by the type checker when passing in a type
-               -- variable that should be side-effected to the result type.
-               -- Always has kind openTypeKind.
-               -- Never appears in types
-
-  | SigTv      -- Introduced when instantiating a type signature,
+  = SigTv      -- Introduced when instantiating a type signature,
                -- prior to checking that the defn of a fn does 
                -- have the expected type.  Should not be instantiated.
                --
@@ -290,14 +285,6 @@ isSkolemTyVar tv = case mutTyVarDetails tv of
                      InstTv -> True
                      oteher -> False
 
-isHoleTyVar :: TcTyVar -> Bool
--- NB:  the hole might be filled in by now, and this
---     function does not check for that
-isHoleTyVar tv = ASSERT( isMutTyVar tv )
-                case mutTyVarDetails tv of
-                       HoleTv -> True
-                       other  -> False
-
 tyVarBindingInfo :: TyVar -> SDoc      -- Used in checkSigTyVars
 tyVarBindingInfo tv
   | isMutTyVar tv
@@ -310,7 +297,6 @@ tyVarBindingInfo tv
     details ClsTv     = ptext SLIT("class declaration")
     details InstTv    = ptext SLIT("instance declaration")
     details PatSigTv  = ptext SLIT("pattern type signature")
-    details HoleTv    = ptext SLIT("//hole//")         -- Should not happen
     details VanillaTv = ptext SLIT("//vanilla//")      -- Ditto
 \end{code}
 
index cea0796..dcf4863 100644 (file)
@@ -6,13 +6,21 @@
 \begin{code}
 module TcUnify (
        -- Full-blown subsumption
-  tcSubOff, tcSubExp, tcGen, subFunTy, TcHoleType,
+  tcSubOff, tcSubExp, tcGen, 
   checkSigTyVars, checkSigTyVarsWrt, sigCtxt, findGlobals,
 
        -- Various unifications
   unifyTauTy, unifyTauTyList, unifyTauTyLists, 
-  unifyFunTy, unifyListTy, unifyPArrTy, unifyTupleTy,
-  unifyKind, unifyKinds, unifyOpenTypeKind, unifyFunKind
+  unifyKind, unifyKinds, unifyOpenTypeKind, unifyFunKind,
+
+  --------------------------------
+  -- Holes
+  Expected(..), newHole, readExpectedType, 
+  zapExpectedType, zapExpectedTo, zapExpectedBranches,
+  subFunTy,            unifyFunTy, 
+  zapToListTy,         unifyListTy, 
+  zapToPArrTy,         unifyPArrTy, 
+  zapToTupleTy, unifyTupleTy
 
   ) where
 
@@ -32,14 +40,14 @@ import TcType               ( TcKind, TcType, TcSigmaType, TcRhoType, TcTyVar, TcTauType,
                          tcGetTyVar_maybe, tcGetTyVar, 
                          mkFunTy, tyVarsOfType, mkPhiTy,
                          typeKind, tcSplitFunTy_maybe, mkForAllTys,
-                         isHoleTyVar, isSkolemTyVar, isUserTyVar, 
+                         isSkolemTyVar, isUserTyVar, 
                          tidyOpenType, tidyOpenTypes, tidyOpenTyVar, tidyOpenTyVars,
                          eqKind, openTypeKind, liftedTypeKind, isTypeKind, mkArrowKind,
                          hasMoreBoxityInfo, allDistinctTyVars
                        )
 import Inst            ( newDicts, instToId, tcInstCall )
-import TcMType         ( getTcTyVar, putTcTyVar, tcInstType, readHoleResult, newKindVar,
-                         newTyVarTy, newTyVarTys, newOpenTypeKind, newHoleTyVarTy, 
+import TcMType         ( getTcTyVar, putTcTyVar, tcInstType, newKindVar,
+                         newTyVarTy, newTyVarTys, newOpenTypeKind, 
                          zonkTcType, zonkTcTyVars, zonkTcTyVarsAndFV )
 import TcSimplify      ( tcSimplifyCheck )
 import TysWiredIn      ( listTyCon, parrTyCon, mkListTy, mkPArrTy, mkTupleTy )
@@ -53,7 +61,7 @@ import VarEnv
 import Name            ( isSystemName )
 import ErrUtils                ( Message )
 import BasicTypes      ( Boxity, Arity, isBoxed )
-import Util            ( equalLength, notNull )
+import Util            ( equalLength, lengthExceeds, notNull )
 import Outputable
 \end{code}
 
@@ -63,6 +71,204 @@ Notes on holes
 
 %************************************************************************
 %*                                                                     *
+\subsection{'hole' type variables}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+data Expected ty = Infer (TcRef ty)    -- The hole to fill in for type inference
+                | Check ty             -- The type to check during type checking
+
+newHole :: TcM (TcRef ty)
+newHole = newMutVar (error "Empty hole in typechecker")
+
+readExpectedType :: Expected ty -> TcM ty
+readExpectedType (Infer hole) = readMutVar hole
+readExpectedType (Check ty)   = returnM ty
+
+zapExpectedType :: Expected TcType -> TcM TcTauType
+-- In the inference case, ensure we have a monotype
+zapExpectedType (Infer hole)
+  = do { ty <- newTyVarTy openTypeKind ;
+        writeMutVar hole ty ;
+        return ty }
+
+zapExpectedType (Check ty) = return ty
+
+zapExpectedTo :: Expected TcType -> TcTauType -> TcM ()
+zapExpectedTo (Infer hole) ty2 = writeMutVar hole ty2
+zapExpectedTo (Check ty1)  ty2 = unifyTauTy ty1 ty2
+
+zapExpectedBranches :: [a] -> Expected TcType -> TcM (Expected TcType)
+-- Zap the expected type to a monotype if there is more than one branch
+zapExpectedBranches branches exp_ty
+  | lengthExceeds branches 1 = zapExpectedType exp_ty  `thenM` \ exp_ty' -> 
+                              return (Check exp_ty')
+  | otherwise               = returnM exp_ty           
+
+instance Outputable ty => Outputable (Expected ty) where
+  ppr (Check ty)   = ptext SLIT("Expected type") <+> ppr ty
+  ppr (Infer hole) = ptext SLIT("Inferring type")
+\end{code}                
+
+
+%************************************************************************
+%*                                                                     *
+\subsection[Unify-fun]{@unifyFunTy@}
+%*                                                                     *
+%************************************************************************
+
+@subFunTy@ and @unifyFunTy@ is used to avoid the fruitless 
+creation of type variables.
+
+* subFunTy is used when we might be faced with a "hole" type variable,
+  in which case we should create two new holes. 
+
+* unifyFunTy is used when we expect to encounter only "ordinary" 
+  type variables, so we should create new ordinary type variables
+
+\begin{code}
+subFunTy :: Expected TcRhoType -- Fail if ty isn't a function type
+                               -- If it's a hole, make two holes, feed them to...
+        -> (Expected TcRhoType -> Expected TcRhoType -> TcM a) -- the thing inside
+        -> TcM a       -- and bind the function type to the hole
+
+subFunTy (Infer hole) thing_inside
+  =    -- This is the interesting case
+    newHole                    `thenM` \ arg_hole ->
+    newHole                    `thenM` \ res_hole ->
+
+       -- Do the business
+    thing_inside (Infer arg_hole) (Infer res_hole)     `thenM` \ answer ->
+
+       -- Extract the answers
+    readMutVar arg_hole                `thenM` \ arg_ty ->
+    readMutVar res_hole                `thenM` \ res_ty ->
+
+       -- Write the answer into the incoming hole
+    writeMutVar hole (mkFunTy arg_ty res_ty)   `thenM_` 
+
+       -- And return the answer
+    returnM answer
+
+subFunTy (Check ty) thing_inside
+  = unifyFunTy ty      `thenM` \ (arg,res) ->
+    thing_inside (Check arg) (Check res)
+
+                
+unifyFunTy :: TcRhoType                        -- Fail if ty isn't a function type
+          -> TcM (TcType, TcType)      -- otherwise return arg and result types
+
+unifyFunTy ty@(TyVarTy tyvar)
+  = getTcTyVar tyvar   `thenM` \ maybe_ty ->
+    case maybe_ty of
+       Just ty' -> unifyFunTy ty'
+       Nothing  -> unify_fun_ty_help ty
+
+unifyFunTy ty
+  = case tcSplitFunTy_maybe ty of
+       Just arg_and_res -> returnM arg_and_res
+       Nothing          -> unify_fun_ty_help ty
+
+unify_fun_ty_help ty   -- Special cases failed, so revert to ordinary unification
+  = newTyVarTy openTypeKind    `thenM` \ arg ->
+    newTyVarTy openTypeKind    `thenM` \ res ->
+    unifyTauTy ty (mkFunTy arg res)    `thenM_`
+    returnM (arg,res)
+\end{code}
+
+\begin{code}
+zapToListTy :: Expected TcType -- expected list type
+           -> TcM TcType      -- list element type
+
+zapToListTy (Check ty)   = unifyListTy ty
+zapToListTy (Infer hole) = do { elt_ty <- newTyVarTy liftedTypeKind ;
+                               writeMutVar hole (mkListTy elt_ty) ;
+                               return elt_ty }
+
+unifyListTy :: TcType -> TcM TcType
+unifyListTy ty@(TyVarTy tyvar)
+  = getTcTyVar tyvar   `thenM` \ maybe_ty ->
+    case maybe_ty of
+       Just ty' -> unifyListTy ty'
+       other    -> unify_list_ty_help ty
+
+unifyListTy ty
+  = case tcSplitTyConApp_maybe ty of
+       Just (tycon, [arg_ty]) | tycon == listTyCon -> returnM arg_ty
+       other                                       -> unify_list_ty_help ty
+
+unify_list_ty_help ty  -- Revert to ordinary unification
+  = newTyVarTy liftedTypeKind          `thenM` \ elt_ty ->
+    unifyTauTy ty (mkListTy elt_ty)    `thenM_`
+    returnM elt_ty
+
+-- variant for parallel arrays
+--
+zapToPArrTy :: Expected TcType     -- Expected list type
+           -> TcM TcType          -- List element type
+
+zapToPArrTy (Check ty)   = unifyPArrTy ty
+zapToPArrTy (Infer hole) = do { elt_ty <- newTyVarTy liftedTypeKind ;
+                               writeMutVar hole (mkPArrTy elt_ty) ;
+                               return elt_ty }
+
+unifyPArrTy :: TcType -> TcM TcType
+
+unifyPArrTy ty@(TyVarTy tyvar)
+  = getTcTyVar tyvar   `thenM` \ maybe_ty ->
+    case maybe_ty of
+      Just ty' -> unifyPArrTy ty'
+      _        -> unify_parr_ty_help ty
+unifyPArrTy ty
+  = case tcSplitTyConApp_maybe ty of
+      Just (tycon, [arg_ty]) | tycon == parrTyCon -> returnM arg_ty
+      _                                          -> unify_parr_ty_help ty
+
+unify_parr_ty_help ty  -- Revert to ordinary unification
+  = newTyVarTy liftedTypeKind          `thenM` \ elt_ty ->
+    unifyTauTy ty (mkPArrTy elt_ty)    `thenM_`
+    returnM elt_ty
+\end{code}
+
+\begin{code}
+zapToTupleTy :: Boxity -> Arity -> Expected TcType -> TcM [TcType]
+zapToTupleTy boxity arity (Check ty)   = unifyTupleTy boxity arity ty
+zapToTupleTy boxity arity (Infer hole) = do { (tup_ty, arg_tys) <- new_tuple_ty boxity arity ;
+                                             writeMutVar hole tup_ty ;
+                                             return arg_tys }
+
+unifyTupleTy boxity arity ty@(TyVarTy tyvar)
+  = getTcTyVar tyvar   `thenM` \ maybe_ty ->
+    case maybe_ty of
+       Just ty' -> unifyTupleTy boxity arity ty'
+       other    -> unify_tuple_ty_help boxity arity ty
+
+unifyTupleTy boxity arity ty
+  = case tcSplitTyConApp_maybe ty of
+       Just (tycon, arg_tys)
+               |  isTupleTyCon tycon 
+               && tyConArity tycon == arity
+               && tupleTyConBoxity tycon == boxity
+               -> returnM arg_tys
+       other -> unify_tuple_ty_help boxity arity ty
+
+unify_tuple_ty_help boxity arity ty
+  = new_tuple_ty boxity arity  `thenM` \ (tup_ty, arg_tys) ->
+    unifyTauTy ty tup_ty       `thenM_`
+    returnM arg_tys
+
+new_tuple_ty boxity arity
+  = newTyVarTys arity kind     `thenM` \ arg_tys ->
+    return (mkTupleTy boxity arity arg_tys, arg_tys)
+  where
+    kind | isBoxed boxity = liftedTypeKind
+        | otherwise      = openTypeKind
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
 \subsection{Subsumption}
 %*                                                                     *
 %************************************************************************
@@ -82,12 +288,8 @@ which takes an HsExpr of type offered_ty into one of type
 expected_ty.
 
 \begin{code}
-type TcHoleType = TcSigmaType  -- Either a TcSigmaType, 
-                               -- or else a hole
-
-tcSubExp :: TcHoleType  -> TcSigmaType -> TcM ExprCoFn
-tcSubOff :: TcSigmaType -> TcHoleType  -> TcM ExprCoFn
-tcSub    :: TcSigmaType -> TcSigmaType -> TcM ExprCoFn
+tcSubExp :: Expected TcRhoType -> TcRhoType  -> TcM ExprCoFn
+tcSubOff :: TcSigmaType  -> Expected TcSigmaType -> TcM ExprCoFn
 \end{code}
 
 These two check for holes
@@ -106,22 +308,17 @@ tcSubOff expected_ty offered_ty
 -- Otherwise it calls thing_inside, passing the two args, looking
 -- through any instantiated hole
 
-checkHole (TyVarTy tv) other_ty thing_inside
-  | isHoleTyVar tv
-  = getTcTyVar tv      `thenM` \ maybe_ty ->
-    case maybe_ty of
-       Just ty -> thing_inside ty other_ty
-       Nothing -> traceTc (text "checkHole" <+> ppr tv)        `thenM_`
-                  putTcTyVar tv other_ty       `thenM_`
-                  returnM idCoercion
+checkHole (Infer hole) other_ty thing_inside
+  = do { writeMutVar hole other_ty; return idCoercion }
 
-checkHole ty other_ty thing_inside 
+checkHole (Check ty) other_ty thing_inside 
   = thing_inside ty other_ty
 \end{code}
 
 No holes expected now.  Add some error-check context info.
 
 \begin{code}
+tcSub :: TcSigmaType -> TcSigmaType -> TcM ExprCoFn    -- Locally used only
 tcSub expected_ty actual_ty
   = traceTc (text "tcSub" <+> details)         `thenM_`
     addErrCtxtM (unifyCtxt "type" expected_ty actual_ty)
@@ -210,16 +407,14 @@ tc_sub _ (FunTy exp_arg exp_res) _ (FunTy act_arg act_res)
 -- I'm not quite sure what to do about this!
 
 tc_sub exp_sty exp_ty@(FunTy exp_arg exp_res) _ (TyVarTy tv)
-  = ASSERT( not (isHoleTyVar tv) )
-    getTcTyVar tv      `thenM` \ maybe_ty ->
+  = getTcTyVar tv      `thenM` \ maybe_ty ->
     case maybe_ty of
        Just ty -> tc_sub exp_sty exp_ty ty ty
        Nothing -> imitateFun tv exp_sty        `thenM` \ (act_arg, act_res) ->
                   tcSub_fun exp_arg exp_res act_arg act_res
 
 tc_sub _ (TyVarTy tv) act_sty act_ty@(FunTy act_arg act_res)
-  = ASSERT( not (isHoleTyVar tv) )
-    getTcTyVar tv      `thenM` \ maybe_ty ->
+  = getTcTyVar tv      `thenM` \ maybe_ty ->
     case maybe_ty of
        Just ty -> tc_sub ty ty act_sty act_ty
        Nothing -> imitateFun tv act_sty        `thenM` \ (exp_arg, exp_res) ->
@@ -265,8 +460,7 @@ tcSub_fun exp_arg exp_res act_arg act_res
 
 imitateFun :: TcTyVar -> TcType -> TcM (TcType, TcType)
 imitateFun tv ty
-  = ASSERT( not (isHoleTyVar tv) )
-       -- NB: tv is an *ordinary* tyvar and so are the new ones
+  =    -- NB: tv is an *ordinary* tyvar and so are the new ones
 
        -- Check that tv isn't a type-signature type variable
        -- (This would be found later in checkSigTyVars, but
@@ -705,146 +899,6 @@ okToUnifyWith tv ty
 
 %************************************************************************
 %*                                                                     *
-\subsection[Unify-fun]{@unifyFunTy@}
-%*                                                                     *
-%************************************************************************
-
-@subFunTy@ and @unifyFunTy@ is used to avoid the fruitless 
-creation of type variables.
-
-* subFunTy is used when we might be faced with a "hole" type variable,
-  in which case we should create two new holes. 
-
-* unifyFunTy is used when we expect to encounter only "ordinary" 
-  type variables, so we should create new ordinary type variables
-
-\begin{code}
-subFunTy :: TcHoleType -- Fail if ty isn't a function type
-                       -- If it's a hole, make two holes, feed them to...
-        -> (TcHoleType -> TcHoleType -> TcM a) -- the thing inside
-        -> TcM a       -- and bind the function type to the hole
-
-subFunTy ty@(TyVarTy tyvar) thing_inside
-  | isHoleTyVar tyvar
-  =    -- This is the interesting case
-    getTcTyVar tyvar   `thenM` \ maybe_ty ->
-    case maybe_ty of {
-       Just ty' -> subFunTy ty' thing_inside ;
-       Nothing  -> 
-
-    newHoleTyVarTy             `thenM` \ arg_ty ->
-    newHoleTyVarTy             `thenM` \ res_ty ->
-
-       -- Do the business
-    thing_inside arg_ty res_ty `thenM` \ answer ->
-
-       -- Extract the answers
-    readHoleResult arg_ty      `thenM` \ arg_ty' ->
-    readHoleResult res_ty      `thenM` \ res_ty' ->
-
-       -- Write the answer into the incoming hole
-    putTcTyVar tyvar (mkFunTy arg_ty' res_ty') `thenM_` 
-
-       -- And return the answer
-    returnM answer }
-
-subFunTy ty thing_inside
-  = unifyFunTy ty      `thenM` \ (arg,res) ->
-    thing_inside arg res
-
-                
-unifyFunTy :: TcRhoType                        -- Fail if ty isn't a function type
-          -> TcM (TcType, TcType)      -- otherwise return arg and result types
-
-unifyFunTy ty@(TyVarTy tyvar)
-  = ASSERT( not (isHoleTyVar tyvar) )
-    getTcTyVar tyvar   `thenM` \ maybe_ty ->
-    case maybe_ty of
-       Just ty' -> unifyFunTy ty'
-       Nothing  -> unify_fun_ty_help ty
-
-unifyFunTy ty
-  = case tcSplitFunTy_maybe ty of
-       Just arg_and_res -> returnM arg_and_res
-       Nothing          -> unify_fun_ty_help ty
-
-unify_fun_ty_help ty   -- Special cases failed, so revert to ordinary unification
-  = newTyVarTy openTypeKind    `thenM` \ arg ->
-    newTyVarTy openTypeKind    `thenM` \ res ->
-    unifyTauTy ty (mkFunTy arg res)    `thenM_`
-    returnM (arg,res)
-\end{code}
-
-\begin{code}
-unifyListTy :: TcType              -- expected list type
-           -> TcM TcType      -- list element type
-
-unifyListTy ty@(TyVarTy tyvar)
-  = getTcTyVar tyvar   `thenM` \ maybe_ty ->
-    case maybe_ty of
-       Just ty' -> unifyListTy ty'
-       other    -> unify_list_ty_help ty
-
-unifyListTy ty
-  = case tcSplitTyConApp_maybe ty of
-       Just (tycon, [arg_ty]) | tycon == listTyCon -> returnM arg_ty
-       other                                       -> unify_list_ty_help ty
-
-unify_list_ty_help ty  -- Revert to ordinary unification
-  = newTyVarTy liftedTypeKind          `thenM` \ elt_ty ->
-    unifyTauTy ty (mkListTy elt_ty)    `thenM_`
-    returnM elt_ty
-
--- variant for parallel arrays
---
-unifyPArrTy :: TcType              -- expected list type
-           -> TcM TcType          -- list element type
-
-unifyPArrTy ty@(TyVarTy tyvar)
-  = getTcTyVar tyvar   `thenM` \ maybe_ty ->
-    case maybe_ty of
-      Just ty' -> unifyPArrTy ty'
-      _        -> unify_parr_ty_help ty
-unifyPArrTy ty
-  = case tcSplitTyConApp_maybe ty of
-      Just (tycon, [arg_ty]) | tycon == parrTyCon -> returnM arg_ty
-      _                                          -> unify_parr_ty_help ty
-
-unify_parr_ty_help ty  -- Revert to ordinary unification
-  = newTyVarTy liftedTypeKind          `thenM` \ elt_ty ->
-    unifyTauTy ty (mkPArrTy elt_ty)    `thenM_`
-    returnM elt_ty
-\end{code}
-
-\begin{code}
-unifyTupleTy :: Boxity -> Arity -> TcType -> TcM [TcType]
-unifyTupleTy boxity arity ty@(TyVarTy tyvar)
-  = getTcTyVar tyvar   `thenM` \ maybe_ty ->
-    case maybe_ty of
-       Just ty' -> unifyTupleTy boxity arity ty'
-       other    -> unify_tuple_ty_help boxity arity ty
-
-unifyTupleTy boxity arity ty
-  = case tcSplitTyConApp_maybe ty of
-       Just (tycon, arg_tys)
-               |  isTupleTyCon tycon 
-               && tyConArity tycon == arity
-               && tupleTyConBoxity tycon == boxity
-               -> returnM arg_tys
-       other -> unify_tuple_ty_help boxity arity ty
-
-unify_tuple_ty_help boxity arity ty
-  = newTyVarTys arity kind                             `thenM` \ arg_tys ->
-    unifyTauTy ty (mkTupleTy boxity arity arg_tys)     `thenM_`
-    returnM arg_tys
-  where
-    kind | isBoxed boxity = liftedTypeKind
-        | otherwise      = openTypeKind
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
 \subsection{Kind unification}
 %*                                                                     *
 %************************************************************************