[project @ 1998-03-19 23:54:49 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcExpr.lhs
index 0ac4f08..4675575 100644 (file)
@@ -10,7 +10,7 @@ module TcExpr ( tcExpr, tcStmt, tcId ) where
 
 import HsSyn           ( HsExpr(..), HsLit(..), ArithSeqInfo(..), 
                          HsBinds(..), Stmt(..), DoOrListComp(..),
-                         pprParendExpr, failureFreePat, collectPatBinders
+                         failureFreePat, collectPatBinders
                        )
 import RnHsSyn         ( RenamedHsExpr, 
                          RenamedStmt, RenamedRecordBinds
@@ -26,10 +26,10 @@ import BasicTypes   ( RecFlag(..) )
 import Inst            ( Inst, InstOrigin(..), OverloadedLit(..),
                          LIE, emptyLIE, plusLIE, plusLIEs, newOverloadedLit,
                          newMethod, newMethodWithGivenTy, newDicts )
-import TcBinds         ( tcBindsAndThen, checkSigTyVars, sigThetaCtxt )
+import TcBinds         ( tcBindsAndThen, checkSigTyVars )
 import TcEnv           ( TcIdOcc(..), tcInstId,
                          tcLookupLocalValue, tcLookupGlobalValue, tcLookupClassByKey,
-                         tcLookupGlobalValueByKey, newMonoIds, tcGetGlobalTyVars,
+                         tcLookupGlobalValueByKey, newMonoIds,
                          tcExtendGlobalTyVars, tcLookupGlobalValueMaybe,
                          tcLookupTyCon
                        )
@@ -40,45 +40,40 @@ import TcSimplify   ( tcSimplifyAndCheck )
 import TcType          ( TcType, TcMaybe(..),
                          tcInstType, tcInstSigTcType, tcInstTyVars,
                          tcInstSigType, tcInstTcType, tcInstTheta, tcSplitRhoTy,
-                         newTyVarTy, newTyVarTys, zonkTcTyVars, zonkTcType )
+                         newTyVarTy, newTyVarTys, zonkTcType )
 import TcKind          ( TcKind )
 
 import Class           ( Class )
 import FieldLabel      ( FieldLabel, fieldLabelName, fieldLabelType )
 import Id              ( idType, dataConFieldLabels, dataConSig, recordSelectorFieldLabel,
                          isRecordSelector,
-                         Id, GenId
+                         Id
                        )
 import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind, mkArrowKind )
 import Name            ( Name{-instance Eq-} )
-import Type            ( mkFunTy, mkAppTy, mkTyVarTy, mkTyVarTys, mkRhoTy,
+import Type            ( mkFunTy, mkAppTy, mkTyVarTy, mkTyVarTys,
                          splitFunTy_maybe, splitFunTys,
                          mkTyConApp,
                          splitForAllTys, splitRhoTy, splitSigmaTy, 
-                         isTauTy, mkFunTys, tyVarsOfType, tyVarsOfTypes, 
+                         isTauTy, tyVarsOfType, tyVarsOfTypes, 
                          splitForAllTy_maybe, splitAlgTyConApp, splitAlgTyConApp_maybe
                        )
-import TyVar           ( TyVarSet, emptyTyVarEnv, zipTyVarEnv,
-                         unionTyVarSets, elementOfTyVarSet, mkTyVarSet, tyVarSetToList
+import TyVar           ( emptyTyVarEnv, zipTyVarEnv,
+                         elementOfTyVarSet, mkTyVarSet, tyVarSetToList
                        )
 import TyCon           ( tyConDataCons )
 import TysPrim         ( intPrimTy, charPrimTy, doublePrimTy,
-                         floatPrimTy, addrPrimTy, realWorldTy
-                       )
-import TysWiredIn      ( addrTy, mkTupleTy,
-                         boolTy, charTy, stringTy, mkListTy
+                         floatPrimTy, addrPrimTy
                        )
+import TysWiredIn      ( boolTy, charTy, stringTy )
 import PrelInfo                ( ioTyCon_NAME )
-import Unify           ( unifyTauTy, unifyTauTyList, unifyTauTyLists, 
-                         unifyFunTy, unifyListTy, unifyTupleTy
-                       )
+import Unify           ( unifyTauTy, unifyFunTy, unifyListTy, unifyTupleTy )
 import Unique          ( Unique, cCallableClassKey, cReturnableClassKey, 
                          enumFromClassOpKey, enumFromThenClassOpKey,
                          enumFromToClassOpKey, enumFromThenToClassOpKey,
                          thenMClassOpKey, zeroClassOpKey, returnMClassOpKey
                        )
 import Outputable
-import PprType         ( GenType, GenTyVar )   -- Instances
 import Maybes          ( maybeToBool )
 import ListSetOps      ( minusList )
 import Util
@@ -99,7 +94,7 @@ tcExpr :: RenamedHsExpr                       -- Expession to type check
 \begin{code}
 tcExpr (HsVar name) res_ty
   = tcId name                  `thenNF_Tc` \ (expr', lie, id_ty) ->
-    unifyTauTy id_ty res_ty    `thenTc_`
+    unifyTauTy res_ty id_ty    `thenTc_`
 
     -- Check that the result type doesn't have any nested for-alls.
     -- For example, a "build" on its own is no good; it must be
@@ -143,23 +138,23 @@ Primitive literals:
 
 \begin{code}
 tcExpr (HsLit lit@(HsCharPrim c)) res_ty
-  = unifyTauTy charPrimTy res_ty               `thenTc_`
+  = unifyTauTy res_ty charPrimTy               `thenTc_`
     returnTc (HsLitOut lit charPrimTy, emptyLIE)
 
 tcExpr (HsLit lit@(HsStringPrim s)) res_ty
-  = unifyTauTy addrPrimTy res_ty               `thenTc_`
+  = unifyTauTy res_ty addrPrimTy               `thenTc_`
     returnTc (HsLitOut lit addrPrimTy, emptyLIE)
 
 tcExpr (HsLit lit@(HsIntPrim i)) res_ty
-  = unifyTauTy intPrimTy res_ty                `thenTc_`
+  = unifyTauTy res_ty intPrimTy                `thenTc_`
     returnTc (HsLitOut lit intPrimTy, emptyLIE)
 
 tcExpr (HsLit lit@(HsFloatPrim f)) res_ty
-  = unifyTauTy floatPrimTy res_ty              `thenTc_`
+  = unifyTauTy res_ty floatPrimTy              `thenTc_`
     returnTc (HsLitOut lit floatPrimTy, emptyLIE)
 
 tcExpr (HsLit lit@(HsDoublePrim d)) res_ty
-  = unifyTauTy doublePrimTy res_ty             `thenTc_`
+  = unifyTauTy res_ty doublePrimTy             `thenTc_`
     returnTc (HsLitOut lit doublePrimTy, emptyLIE)
 \end{code}
 
@@ -167,11 +162,11 @@ Unoverloaded literals:
 
 \begin{code}
 tcExpr (HsLit lit@(HsChar c)) res_ty
-  = unifyTauTy charTy res_ty           `thenTc_`
+  = unifyTauTy res_ty charTy           `thenTc_`
     returnTc (HsLitOut lit charTy, emptyLIE)
 
 tcExpr (HsLit lit@(HsString str)) res_ty
-  = unifyTauTy stringTy res_ty         `thenTc_`
+  = unifyTauTy res_ty stringTy                 `thenTc_`
     returnTc (HsLitOut lit stringTy, emptyLIE)
 \end{code}
 
@@ -185,7 +180,15 @@ tcExpr (HsLit lit@(HsString str)) res_ty
 tcExpr (HsPar expr) res_ty -- preserve parens so printing needn't guess where they go
   = tcExpr expr res_ty
 
-tcExpr (NegApp expr neg) res_ty = tcExpr (HsApp neg expr) res_ty
+-- perform the negate *before* overloading the integer, since the case
+-- of minBound on Ints fails otherwise.  Could be done elsewhere, but
+-- convenient to do it here.
+
+tcExpr (NegApp (HsLit (HsInt i)) neg) res_ty
+  = tcExpr (HsLit (HsInt (-i))) res_ty
+
+tcExpr (NegApp expr neg) res_ty 
+  = tcExpr (HsApp neg expr) res_ty
 
 tcExpr (HsLam match) res_ty
   = tcMatchExpected [] res_ty match    `thenTc` \ (match',lie) ->
@@ -237,7 +240,7 @@ tcExpr in_expr@(SectionR op expr) res_ty
     tcAddErrCtxt (sectionRAppCtxt in_expr) $
     split_fun_ty op_ty 2 {- two args -}                        `thenTc` \ ([arg1_ty, arg2_ty], op_res_ty) ->
     tcExpr expr        arg2_ty                                 `thenTc` \ (expr',lie2) ->
-    unifyTauTy (mkFunTy arg1_ty op_res_ty) res_ty      `thenTc_`
+    unifyTauTy res_ty (mkFunTy arg1_ty op_res_ty)      `thenTc_`
     returnTc (SectionR op' expr', lie1 `plusLIE` lie2)
 \end{code}
 
@@ -276,7 +279,7 @@ tcExpr (CCall lbl args may_gc is_asm ignored_fake_result_ty) res_ty
        io_result_ty = mkTyConApp ioTyCon [result_ty]
     in
     case tyConDataCons ioTyCon of { [ioDataCon] ->
-    unifyTauTy io_result_ty res_ty   `thenTc_`
+    unifyTauTy res_ty io_result_ty             `thenTc_`
 
        -- Construct the extra insts, which encode the
        -- constraints on the argument and result types.
@@ -306,16 +309,24 @@ tcExpr (HsLet binds expr) res_ty
              returnTc (expr', lie)
     combiner is_rec bind expr = HsLet (MonoBind bind [] is_rec) expr
 
-tcExpr in_expr@(HsCase expr matches src_loc) res_ty
-  = tcAddSrcLoc src_loc        $
-    newTyVarTy mkTypeKind      `thenNF_Tc` \ expr_ty ->
-    tcExpr expr expr_ty                `thenTc`    \ (expr',lie1) ->
+tcExpr in_expr@(HsCase scrut matches src_loc) res_ty
+  = tcAddSrcLoc src_loc                        $
+    tcAddErrCtxt (caseCtxt in_expr)    $
 
-    tcAddErrCtxt (caseCtxt in_expr) $
-    tcMatchesCase (mkFunTy expr_ty res_ty) matches     
-                               `thenTc`    \ (matches',lie2) ->
+       -- Typecheck the case alternatives first.
+       -- The case patterns tend to give good type info to use
+       -- when typechecking the scrutinee.  For example
+       --      case (map f) of
+       --        (x:xs) -> ...
+       -- will report that map is applied to too few arguments
 
-    returnTc (HsCase expr' matches' src_loc, plusLIE lie1 lie2)
+    tcMatchesCase res_ty matches       `thenTc`    \ (scrut_ty, matches', lie2) ->
+
+    tcAddErrCtxt (caseScrutCtxt scrut) (
+      tcExpr scrut scrut_ty
+    )                                  `thenTc`    \ (scrut',lie1) ->
+
+    returnTc (HsCase scrut' matches' src_loc, plusLIE lie1 lie2)
 
 tcExpr (HsIf pred b1 b2 src_loc) res_ty
   = tcAddSrcLoc src_loc        $
@@ -357,7 +368,7 @@ tcExpr (RecordCon con_name _ rbinds) res_ty
     in
        -- Con is syntactically constrained to be a data constructor
     ASSERT( maybeToBool (splitAlgTyConApp_maybe record_ty ) )
-    unifyTauTy record_ty res_ty         `thenTc_`
+    unifyTauTy res_ty record_ty          `thenTc_`
 
        -- Check that the record bindings match the constructor
     let
@@ -432,7 +443,7 @@ tcExpr (RecordUpd record_expr rbinds) res_ty
     let
        result_record_ty = mkTyConApp tycon result_inst_tys
     in
-    unifyTauTy result_record_ty res_ty          `thenTc_`
+    unifyTauTy res_ty result_record_ty          `thenTc_`
     tcRecordBinds result_record_ty rbinds      `thenTc` \ (rbinds', rbinds_lie) ->
 
        -- STEP 4
@@ -566,19 +577,18 @@ tcExpr in_expr@(ExprWithTySig expr poly_ty) res_ty
 
        -- Check overloading constraints
    newDicts SignatureOrigin sig_theta'         `thenNF_Tc` \ (sig_dicts, _) ->
-   tcAddErrCtxtM (sigThetaCtxt sig_dicts)      (
-     tcSimplifyAndCheck
-        (text "expr ty sig")
+   tcSimplifyAndCheck
+        (ptext SLIT("the type signature") <+> quotes (ppr sigma_sig))
        (mkTyVarSet zonked_sig_tyvars)
        sig_dicts lie                           
-   )                                           `thenTc_`
+                                               `thenTc_`
 
        -- Now match the signature type with res_ty.
        -- We must not do this earlier, because res_ty might well
        -- mention variables free in the environment, and we'd get
        -- bogus complaints about not being able to for-all the
        -- sig_tyvars
-   unifyTauTy sig_tau' res_ty          `thenTc_`
+   unifyTauTy res_ty sig_tau'                  `thenTc_`
 
        -- If everything is ok, return the stuff unchanged, except for
        -- the effect of any substutions etc.  We simply discard the
@@ -682,12 +692,18 @@ tcArg :: RenamedHsExpr                    -- The function (for error messages)
 
 tcArg the_fun (arg, expected_arg_ty, arg_no)
   = tcAddErrCtxt (funAppCtxt the_fun arg arg_no) $
-    tcPolyExpr arg expected_arg_ty
+    tcPolyExpr (ptext SLIT("argument type of") <+> quotes (ppr the_fun))
+              arg expected_arg_ty
 
 
 -- tcPolyExpr is like tcExpr, except that the expected type
 -- can be a polymorphic one.
-tcPolyExpr arg expected_arg_ty
+tcPolyExpr :: SDoc                     -- Just for error messages
+          -> RenamedHsExpr
+          -> TcType s                  -- Expected type
+          -> TcM s (TcExpr s, LIE s)   -- Resulting type and LIE
+
+tcPolyExpr str arg expected_arg_ty
   | not (maybeToBool (splitForAllTy_maybe expected_arg_ty))
   =    -- The ordinary, non-rank-2 polymorphic case
     tcExpr arg expected_arg_ty
@@ -722,15 +738,14 @@ tcPolyExpr arg expected_arg_ty
        -- Conclusion: include the free vars of the expected arg type in the
        -- list of "free vars" for the signature check.
 
-    tcAddErrCtxt (rank2ArgCtxt arg expected_arg_ty) $
     tcExtendGlobalTyVars (tyVarSetToList (tyVarsOfType expected_arg_ty)) $
 
     checkSigTyVars sig_tyvars sig_tau          `thenTc` \ zonked_sig_tyvars ->
-    newDicts Rank2Origin sig_theta             `thenNF_Tc` \ (sig_dicts, dict_ids) ->
+    newDicts SignatureOrigin sig_theta         `thenNF_Tc` \ (sig_dicts, dict_ids) ->
        -- ToDo: better origin
 
-    tcAddErrCtxtM (sigThetaCtxt sig_dicts) $
-    tcSimplifyAndCheck (text "rank2")
+    tcSimplifyAndCheck 
+               str
                (mkTyVarSet zonked_sig_tyvars)
                sig_dicts lie_arg               `thenTc` \ (free_insts, inst_binds) ->
 
@@ -742,7 +757,7 @@ tcPolyExpr arg expected_arg_ty
                   HsLet (MonoBind inst_binds [] Recursive) 
                   arg' 
                 , free_insts
-                )
+    )
 \end{code}
 
 %************************************************************************
@@ -819,7 +834,7 @@ tcDoStmts do_or_lc stmts src_loc res_ty
       combine_stmts stmt               _     (stmts, ty) = (stmt:stmts, ty)
     in
     tc_stmts stmts                     `thenTc`   \ ((stmts', result_ty), final_lie) ->
-    unifyTauTy result_ty res_ty                `thenTc_`
+    unifyTauTy res_ty result_ty                `thenTc_`
 
        -- Build the then and zero methods in case we need them
        -- It's important that "then" and "return" appear just once in the final LIE,
@@ -987,7 +1002,8 @@ tcRecordBinds expected_record_ty rbinds
          Just (record_ty, field_ty) = splitFunTy_maybe tau
        in
        unifyTauTy expected_record_ty record_ty         `thenTc_`
-       tcPolyExpr rhs field_ty                         `thenTc` \ (rhs', lie) ->
+       tcPolyExpr (ptext SLIT("type of field") <+> quotes (ppr field_label))
+                  rhs field_ty                         `thenTc` \ (rhs', lie) ->
        returnTc ((RealId sel_id, rhs', pun_flag), lie)
 
 badFields rbinds data_con
@@ -1034,6 +1050,9 @@ arithSeqCtxt expr
 caseCtxt expr
   = hang (ptext SLIT("In the case expression:")) 4 (ppr expr)
 
+caseScrutCtxt expr
+  = hang (ptext SLIT("In the scrutinee of a case expression:")) 4 (ppr expr)
+
 exprSigCtxt expr
   = hang (ptext SLIT("In an expression with a type signature:"))
         4 (ppr expr)
@@ -1068,7 +1087,7 @@ wrongArgsCtxt too_many_or_few fun args
   = hang (ptext SLIT("Probable cause:") <+> ppr fun
                    <+> ptext SLIT("is applied to") <+> text too_many_or_few 
                    <+> ptext SLIT("arguments in the call"))
-        4 (ppr the_app)
+        4 (parens (ppr the_app))
   where
     the_app = foldl HsApp fun args     -- Used in error messages