[project @ 2002-05-23 15:37:32 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / Inst.lhs
index 3e93da1..d43651c 100644 (file)
@@ -12,8 +12,8 @@ module Inst (
        pprInst, pprInsts, pprInstsInFull, tidyInsts, tidyMoreInsts,
 
        newDictsFromOld, newDicts, cloneDict,
-       newMethod, newMethodWithGivenTy, newMethodAtLoc,
-       newOverloadedLit, newIPDict, tcInstCall,
+       newMethod, newMethodFromName, newMethodWithGivenTy, newMethodAtLoc,
+       newOverloadedLit, newIPDict, tcInstCall, tcInstDataCon,
 
        tyVarsOfInst, tyVarsOfInsts, tyVarsOfLIE, 
        ipNamesOfInst, ipNamesOfInsts, predsOfInst, predsOfInsts,
@@ -39,15 +39,15 @@ import TcHsSyn      ( TcExpr, TcId, TypecheckedHsExpr,
                  mkHsTyApp, mkHsDictApp, mkHsConApp, zonkId
                )
 import TcMonad
-import TcEnv   ( TcIdSet, tcGetInstEnv, tcLookupId )
+import TcEnv   ( TcIdSet, tcGetInstEnv, tcLookupId, tcLookupGlobalId )
 import InstEnv ( InstLookupResult(..), lookupInstEnv )
-import TcMType ( zonkTcType, zonkTcTypes, zonkTcPredType,
-                 zonkTcThetaType, tcInstTyVar, tcInstType,
+import TcMType ( zonkTcType, zonkTcTypes, zonkTcPredType, zapToType,
+                 zonkTcThetaType, tcInstTyVar, tcInstType, tcInstTyVars
                )
 import TcType  ( Type, TcType, TcThetaType, TcPredType, TcTauType, TcTyVarSet,
-                 SourceType(..), PredType, ThetaType,
-                 tcSplitForAllTys, tcSplitForAllTys, 
-                 tcSplitMethodTy, tcSplitRhoTy, tcFunArgTy,
+                 SourceType(..), PredType, ThetaType, TyVarDetails(VanillaTv),
+                 tcSplitForAllTys, tcSplitForAllTys, mkTyConApp,
+                 tcSplitMethodTy, tcSplitPhiTy, tcFunArgTy,
                  isIntTy,isFloatTy, isIntegerTy, isDoubleTy,
                  tcIsTyVarTy, mkPredTy, mkTyVarTy, mkTyVarTys,
                  tyVarsOfType, tyVarsOfTypes, tyVarsOfPred, tidyPred,
@@ -58,6 +58,7 @@ import TcType ( Type, TcType, TcThetaType, TcPredType, TcTauType, TcTyVarSet,
                )
 import CoreFVs ( idFreeTyVars )
 import Class   ( Class )
+import DataCon ( dataConSig )
 import Id      ( Id, idName, idType, mkUserLocal, mkSysLocal, mkLocalId, setIdUnique )
 import PrelInfo        ( isStandardClass, isCcallishClass, isNoDictClass )
 import Name    ( Name, mkMethodOcc, getOccName )
@@ -358,13 +359,43 @@ newIPDict orig ip_name ty
 \begin{code}
 tcInstCall :: InstOrigin  -> TcType -> NF_TcM (TypecheckedHsExpr -> TypecheckedHsExpr, LIE, TcType)
 tcInstCall orig fun_ty -- fun_ty is usually a sigma-type
-  = tcInstType fun_ty          `thenNF_Tc` \ (tyvars, theta, tau) ->
+  = tcInstType VanillaTv fun_ty        `thenNF_Tc` \ (tyvars, theta, tau) ->
     newDicts orig theta                `thenNF_Tc` \ dicts ->
     let
        inst_fn e = mkHsDictApp (mkHsTyApp e (mkTyVarTys tyvars)) (map instToId dicts)
     in
     returnNF_Tc (inst_fn, mkLIE dicts, tau)
 
+tcInstDataCon orig data_con
+  = let 
+       (tvs, stupid_theta, ex_tvs, ex_theta, arg_tys, tycon) = dataConSig data_con
+            -- We generate constraints for the stupid theta even when 
+            -- pattern matching (as the Report requires)
+    in
+    tcInstTyVars VanillaTv (tvs ++ ex_tvs)     `thenNF_Tc` \ (all_tvs', ty_args', tenv) ->
+    let
+       stupid_theta' = substTheta tenv stupid_theta
+       ex_theta'     = substTheta tenv ex_theta
+       arg_tys'      = map (substTy tenv) arg_tys
+
+       n_normal_tvs  = length tvs
+       ex_tvs'       = drop n_normal_tvs all_tvs'
+       result_ty     = mkTyConApp tycon (take n_normal_tvs ty_args')
+    in
+    newDicts orig stupid_theta'        `thenNF_Tc` \ stupid_dicts ->
+    newDicts orig ex_theta'    `thenNF_Tc` \ ex_dicts ->
+
+       -- Note that we return the stupid theta *only* in the LIE;
+       -- we don't otherwise use it at all
+    returnNF_Tc (ty_args', map instToId ex_dicts, arg_tys', result_ty,
+                mkLIE stupid_dicts, mkLIE ex_dicts, ex_tvs')
+
+
+newMethodFromName :: InstOrigin -> TcType -> Name -> NF_TcM Inst
+newMethodFromName origin ty name
+  = tcLookupGlobalId name              `thenNF_Tc` \ id ->
+    newMethod origin id [ty]
+
 newMethod :: InstOrigin
          -> TcId
          -> [TcType]
@@ -399,7 +430,7 @@ newMethodAtLoc inst_loc real_id tys
        (tyvars,rho)  = tcSplitForAllTys (idType real_id)
        rho_ty        = ASSERT( equalLength tyvars tys )
                        substTy (mkTopTyVarSubst tyvars tys) rho
-       (theta, tau)  = tcSplitRhoTy rho_ty
+       (theta, tau)  = tcSplitPhiTy rho_ty
     in
     newMethodWith inst_loc real_id tys theta tau       `thenNF_Tc` \ meth_inst ->
     returnNF_Tc (meth_inst, instToId meth_inst)
@@ -415,16 +446,19 @@ newOverloadedLit :: InstOrigin
                 -> HsOverLit
                 -> TcType
                 -> NF_TcM (TcExpr, LIE)
-newOverloadedLit orig lit ty
-  | Just expr <- shortCutLit lit ty
+newOverloadedLit orig lit expected_ty
+  | Just expr <- shortCutLit lit expected_ty
   = returnNF_Tc (expr, emptyLIE)
 
   | otherwise
   = tcGetInstLoc orig          `thenNF_Tc` \ loc ->
     tcGetUnique                        `thenNF_Tc` \ new_uniq ->
+    zapToType expected_ty      `thenNF_Tc_` 
+       -- The expected type might be a 'hole' type variable, 
+       -- in which case we must zap it to an ordinary type variable
     let
-       lit_inst = LitInst lit_id lit ty loc
-       lit_id   = mkSysLocal FSLIT("lit") new_uniq ty
+       lit_inst = LitInst lit_id lit expected_ty loc
+       lit_id   = mkSysLocal FSLIT("lit") new_uniq expected_ty
     in
     returnNF_Tc (HsVar (instToId lit_inst), unitLIE lit_inst)
 
@@ -550,22 +584,22 @@ lookupInst dict@(Dict _ (ClassP clas tys) loc)
     case lookupInstEnv dflags inst_env clas tys of
 
       FoundInst tenv dfun_id
-       -> let
+       ->      -- It's possible that not all the tyvars are in
+               -- the substitution, tenv. For example:
+               --      instance C X a => D X where ...
+               -- (presumably there's a functional dependency in class C)
+               -- Hence the mk_ty_arg to instantiate any un-substituted tyvars.        
+          let
                (tyvars, rho) = tcSplitForAllTys (idType dfun_id)
                mk_ty_arg tv  = case lookupSubstEnv tenv tv of
                                   Just (DoneTy ty) -> returnNF_Tc ty
-                                  Nothing          -> tcInstTyVar tv   `thenNF_Tc` \ tc_tv ->
+                                  Nothing          -> tcInstTyVar VanillaTv tv `thenNF_Tc` \ tc_tv ->
                                                       returnTc (mkTyVarTy tc_tv)
           in
-               -- It's possible that not all the tyvars are in
-               -- the substitution, tenv. For example:
-               --      instance C X a => D X where ...
-               -- (presumably there's a functional dependency in class C)
-               -- Hence the mk_ty_arg to instantiate any un-substituted tyvars.        
           mapNF_Tc mk_ty_arg tyvars    `thenNF_Tc` \ ty_args ->
           let
                dfun_rho   = substTy (mkTyVarSubst tyvars ty_args) rho
-               (theta, _) = tcSplitRhoTy dfun_rho
+               (theta, _) = tcSplitPhiTy dfun_rho
                ty_app     = mkHsTyApp (HsVar dfun_id) ty_args
           in
           if null theta then
@@ -635,7 +669,7 @@ lookupSimpleInst clas tys
        -> returnNF_Tc (Just (substTheta (mkSubst emptyInScopeSet tenv) theta))
         where
           (_, rho)  = tcSplitForAllTys (idType dfun)
-          (theta,_) = tcSplitRhoTy rho
+          (theta,_) = tcSplitPhiTy rho
 
       other  -> returnNF_Tc Nothing
 \end{code}