[project @ 1996-06-11 13:18:54 by partain]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcInstDcls.lhs
index 238e3fd..aa8590a 100644 (file)
@@ -9,17 +9,18 @@
 module TcInstDcls (
        tcInstDecls1,
        tcInstDecls2,
-       processInstBinds
+       processInstBinds,
+       newMethodId
     ) where
 
 
-import Ubiq
+IMP_Ubiq()
 
 import HsSyn           ( InstDecl(..), FixityDecl, Sig(..),
                          SpecInstSig(..), HsBinds(..), Bind(..),
                          MonoBinds(..), GRHSsAndBinds, Match, 
                          InPat(..), OutPat(..), HsExpr(..), HsLit(..),
-                         Stmt, Qual, ArithSeqInfo, Fake,
+                         Stmt, Qualifier, ArithSeqInfo, Fake,
                          PolyType(..), MonoType )
 import RnHsSyn         ( RenamedHsBinds(..), RenamedMonoBinds(..),
                          RenamedInstDecl(..), RenamedFixityDecl(..),
@@ -33,7 +34,7 @@ import TcHsSyn                ( TcIdOcc(..), TcHsBinds(..),
 
 
 import TcMonad         hiding ( rnMtoTcM )
-import GenSpecEtc      ( checkSigTyVars )
+import GenSpecEtc      ( checkSigTyVarsGivenGlobals )
 import Inst            ( Inst, InstOrigin(..), InstanceMapper(..),
                          newDicts, newMethod, LIE(..), emptyLIE, plusLIE )
 import TcBinds         ( tcPragmaSigs )
@@ -44,18 +45,19 @@ import TcInstUtil   ( InstInfo(..), mkInstanceRelatedIds, buildInstanceEnvs )
 import TcKind          ( TcKind, unifyKind )
 import TcMatches       ( tcMatchesFun )
 import TcMonoType      ( tcContext, tcMonoTypeKind )
-import TcSimplify      ( tcSimplifyAndCheck, tcSimplifyThetas )
+import TcSimplify      ( tcSimplifyAndCheck )
 import TcType          ( TcType(..), TcTyVar(..),
-                         tcInstSigTyVars, tcInstType, tcInstTheta
+                         tcInstSigTyVars, tcInstType, tcInstTheta, tcInstTcType
                        )
-import Unify           ( unifyTauTy )
+import Unify           ( unifyTauTy, unifyTauTyLists )
 
 
 import Bag             ( emptyBag, unitBag, unionBags, unionManyBags,
                          concatBag, foldBag, bagToList )
-import CmdLineOpts     ( opt_GlasgowExts, opt_CompilingPrelude,
+import CmdLineOpts     ( opt_GlasgowExts,
                          opt_OmitDefaultInstanceMethods,
-                         opt_SpecialiseOverloaded )
+                         opt_SpecialiseOverloaded
+                       )
 import Class           ( GenClass, GenClassOp, 
                          isCcallishClass, classBigSig,
                          classOps, classOpLocalType,
@@ -76,12 +78,12 @@ import RnUtils              ( RnEnv(..) )
 import TyCon           ( isSynTyCon, derivedFor )
 import Type            ( GenType(..),  ThetaType(..), mkTyVarTys,
                          splitSigmaTy, splitAppTy, isTyVarTy, matchTy, mkSigmaTy,
-                         getTyCon_maybe, maybeBoxedPrimType
+                         getTyCon_maybe, maybeBoxedPrimType, splitRhoTy
                        )
-import TyVar           ( GenTyVar, mkTyVarSet )
+import TyVar           ( GenTyVar, mkTyVarSet, unionTyVarSets )
 import TysWiredIn      ( stringTy )
 import Unique          ( Unique )
-import Util            ( panic )
+import Util            ( zipEqual, panic )
 \end{code}
 
 Typechecking instance declarations is done in two passes. The first
@@ -231,8 +233,7 @@ tcInstDecl1 mod_name
     if (not from_here && (clas `derivedFor` inst_tycon)
                      && all isTyVarTy arg_tys)
     then
-       if not opt_CompilingPrelude && maybeToBool inst_mod &&
-          mod_name == expectJust "inst_mod" inst_mod
+       if mod_name == inst_mod
        then
                -- Imported instance came from this module;
                -- discard and derive fresh instance
@@ -244,7 +245,7 @@ tcInstDecl1 mod_name
     else
 
        -- Make the dfun id and constant-method ids
-    mkInstanceRelatedIds from_here inst_mod pragmas
+    mkInstanceRelatedIds from_here src_loc inst_mod pragmas
                         clas inst_tyvars inst_tau inst_theta uprags
                                        `thenTc` \ (dfun_id, dfun_theta, const_meth_ids) ->
 
@@ -366,9 +367,9 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
     tcInstTheta tenv dfun_theta                `thenNF_Tc` \ dfun_theta' ->
     tcInstTheta tenv inst_decl_theta   `thenNF_Tc` \ inst_decl_theta' ->
     let
-       sc_theta'        = super_classes `zip` (repeat inst_ty')
+       sc_theta'        = super_classes `zip` repeat inst_ty'
        origin           = InstanceDeclOrigin
-       mk_method sel_id = newMethodId sel_id inst_ty' origin locn
+       mk_method sel_id = newMethodId sel_id inst_ty' origin
     in
         -- Create dictionary Ids from the specified instance contexts.
     newDicts origin sc_theta'          `thenNF_Tc` \ (sc_dicts,        sc_dict_ids) ->
@@ -435,8 +436,8 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
                 inst_tyvars'
                 dfun_arg_dicts_ids
                 ((this_dict_id, RealId dfun_id) 
-                 : (meth_ids `zip` (map RealId const_meth_ids)))
-                       -- const_meth_ids will often be empty
+                 : (meth_ids `zip` map RealId const_meth_ids))
+                       -- NB: const_meth_ids will often be empty
                 super_binds
                 (RecBind dict_and_method_binds)
 
@@ -447,6 +448,8 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
     returnTc (const_lie `plusLIE` spec_lie, inst_binds)
 \end{code}
 
+============= OLD ================
+
 @mkMethodId@ manufactures an id for a local method.
 It's rather turgid stuff, because there are two cases:
 
@@ -473,10 +476,15 @@ It's rather turgid stuff, because there are two cases:
       So for these we just make a local (non-Inst) id with a suitable type.
 
 How disgusting.
+=============== END OF OLD ===================
 
 \begin{code}
-newMethodId sel_id inst_ty origin loc
-  = let (sel_tyvars,sel_theta,sel_tau) = splitSigmaTy (idType sel_id)
+newMethodId sel_id inst_ty origin
+  = newMethod origin (RealId sel_id) [inst_ty]
+
+
+{- REMOVE SOON:                (this was pre-split-poly selector types)
+let (sel_tyvars,sel_theta,sel_tau) = splitSigmaTy (idType sel_id)
        (_:meth_theta) = sel_theta      -- The local theta is all except the
                                        -- first element of the context
     in 
@@ -493,6 +501,7 @@ newMethodId sel_id inst_ty origin loc
                                                                `thenNF_Tc` \ method_ty ->
                newLocalId (getLocalName sel_id) method_ty      `thenNF_Tc` \ meth_id ->
                returnNF_Tc (emptyLIE, meth_id)
+-}
 \end{code}
 
 The next function makes a default method which calls the global default method, at
@@ -511,22 +520,13 @@ makeInstanceDeclDefaultMethodExpr
        -> NF_TcM s (TcExpr s)
 
 makeInstanceDeclDefaultMethodExpr origin meth_ids defm_ids inst_ty this_dict tag
-  = newDicts origin op_theta           `thenNF_Tc` \ (op_lie,op_dicts) ->
-
-       -- def_op_id = /\ op_tyvars -> \ op_dicts ->
-       --                defm_id inst_ty op_tyvars this_dict op_dicts
-    returnNF_Tc (
-      mkHsTyLam op_tyvars (
-      mkHsDictLam op_dicts (
-      mkHsDictApp (mkHsTyApp (HsVar (RealId defm_id))
-                            (inst_ty :  mkTyVarTys op_tyvars))
-                 (this_dict : op_dicts)
-      )))
+  =
+       -- def_op_id = defm_id inst_ty this_dict
+    returnNF_Tc (mkHsDictApp (mkHsTyApp (HsVar (RealId defm_id)) [inst_ty]) [this_dict])
  where
     idx            = tag - 1
     meth_id = meth_ids !! idx
     defm_id = defm_ids  !! idx
-    (op_tyvars, op_theta, op_tau) = splitSigmaTy (tcIdType meth_id)
 
 makeInstanceDeclNoDefaultExpr
        :: InstOrigin s
@@ -534,38 +534,32 @@ makeInstanceDeclNoDefaultExpr
        -> [Id]
        -> TcType s
        -> Class
-       -> Maybe Module
+       -> Module
        -> Int
        -> NF_TcM s (TcExpr s)
 
 makeInstanceDeclNoDefaultExpr origin meth_ids defm_ids inst_ty clas inst_mod tag
-  = newDicts origin op_theta           `thenNF_Tc` \ (op_lie, op_dicts) ->
-
+  = 
        -- Produce a warning if the default instance method
        -- has been omitted when one exists in the class
     warnTc (not err_defm_ok)
           (omitDefaultMethodWarn clas_op clas_name inst_ty)
                                        `thenNF_Tc_`
-    returnNF_Tc (mkHsTyLam op_tyvars (
-                mkHsDictLam op_dicts (
-                HsApp (mkHsTyApp (HsVar (RealId nO_EXPLICIT_METHOD_ERROR_ID)) [op_tau])
-                    (HsLitOut (HsString (_PK_ error_msg)) stringTy))))
+    returnNF_Tc (HsApp (mkHsTyApp (HsVar (RealId nO_EXPLICIT_METHOD_ERROR_ID)) [tcIdType meth_id])
+                      (HsLitOut (HsString (_PK_ error_msg)) stringTy))
   where
     idx            = tag - 1
     meth_id = meth_ids  !! idx
     clas_op = (classOps clas) !! idx
     defm_id = defm_ids  !! idx
-    (op_tyvars,op_theta,op_tau) = splitSigmaTy (tcIdType meth_id)
 
     Just (_, _, err_defm_ok) = isDefaultMethodId_maybe defm_id
 
-    mod_str = case inst_mod of { Nothing -> pRELUDE; Just m -> m }
-
-    error_msg = _UNPK_ mod_str ++ "." ++ _UNPK_ clas_name ++ "."
+    error_msg = _UNPK_ inst_mod ++ "." ++ _UNPK_ clas_name ++ "."
                ++ (ppShow 80 (ppr PprForUser inst_ty)) ++ "."
                ++ (ppShow 80 (ppr PprForUser clas_op)) ++ "\""
 
-    clas_name = nameOf (origName clas)
+    clas_name = nameOf (origName "makeInstanceDeclNoDefaultExpr" clas)
 \end{code}
 
 
@@ -666,11 +660,14 @@ processInstBinds1 clas inst_tyvars avail_insts method_ids mbind
     let
        tag       = classOpTagByString clas occ
        method_id = method_ids !! (tag-1)
-
        method_ty = tcIdType method_id
-       (method_tyvars, method_theta, method_tau) = splitSigmaTy method_ty
     in
-    newDicts origin method_theta               `thenNF_Tc` \ (method_dicts,method_dict_ids) ->
+
+    tcInstTcType method_ty             `thenNF_Tc` \ (method_tyvars, method_rho) ->
+    let
+       (method_theta, method_tau) = splitRhoTy method_rho
+    in
+    newDicts origin method_theta       `thenNF_Tc` \ (method_dicts,method_dict_ids) ->
 
     case (method_tyvars, method_dict_ids) of
 
@@ -687,10 +684,17 @@ processInstBinds1 clas inst_tyvars avail_insts method_ids mbind
                -- The latter is needed just so we can return an AbsBinds wrapped
                -- up inside a MonoBinds.
 
+
+               -- Make the method_tyvars into signature tyvars so they
+               -- won't get unified with anything.
+       tcInstSigTyVars method_tyvars           `thenNF_Tc` \ (sig_tyvars, sig_tyvar_tys, _) ->
+       unifyTauTyLists (mkTyVarTys method_tyvars) sig_tyvar_tys        `thenTc_`
+
        newLocalId occ method_tau               `thenNF_Tc` \ local_id ->
        newLocalId occ method_ty                `thenNF_Tc` \ copy_id ->
        let
-           inst_method_tyvars = inst_tyvars ++ method_tyvars
+           inst_tyvar_set = mkTyVarSet inst_tyvars
+           inst_method_tyvar_set = inst_tyvar_set `unionTyVarSets` (mkTyVarSet sig_tyvars)
        in
                -- Typecheck the method
        tcMethodBind local_id method_tau mbind `thenTc` \ (mbind', lieIop) ->
@@ -705,12 +709,17 @@ processInstBinds1 clas inst_tyvars avail_insts method_ids mbind
                -- Here we must simplify constraints on "a" to catch all
                -- the Bar-ish things.
        tcAddErrCtxt (methodSigCtxt op method_ty) (
+           checkSigTyVarsGivenGlobals
+               inst_tyvar_set
+               sig_tyvars method_tau                           `thenTc_`
+
          tcSimplifyAndCheck
-               (mkTyVarSet inst_method_tyvars)
+               inst_method_tyvar_set
                (method_dicts `plusLIE` avail_insts)
                lieIop
        )                                        `thenTc` \ (f_dicts, dict_binds) ->
 
+
        returnTc ([tag],
                  f_dicts,
                  VarMonoBind method_id
@@ -813,16 +822,19 @@ tcSpecInstSig e ce tce inst_infos inst_mapper (SpecInstSig class_name ty src_loc
 
        mk_spec_origin clas ty
          = InstanceSpecOrigin inst_mapper clas ty src_loc
+       -- I'm VERY SUSPICIOUS ABOUT THIS
+       -- the inst-mapper is in a knot at this point so it's no good
+       -- looking at it in tcSimplify...
     in
     tcSimplifyThetas mk_spec_origin subst_tv_theta
                                `thenTc` \ simpl_tv_theta ->
     let
        simpl_theta = [ (clas, tv_to_tmpl tv) | (clas, tv) <- simpl_tv_theta ]
 
-       tv_tmpl_map = inst_tv_tys `zipEqual` inst_tmpl_tys
+       tv_tmpl_map   = zipEqual "tcSpecInstSig" inst_tv_tys inst_tmpl_tys
        tv_to_tmpl tv = assoc "tcSpecInstSig" tv_tmpl_map tv
     in
-    mkInstanceRelatedIds e True{-from here-} mod NoInstancePragmas src_loc
+    mkInstanceRelatedIds e True{-from here-} src_loc mod NoInstancePragmas 
                         clas inst_tmpls inst_ty simpl_theta uprag
                                `thenTc` \ (dfun_id, dfun_theta, const_meth_ids) ->
 
@@ -916,8 +928,7 @@ scrutiniseInstanceType from_here clas inst_tau
        -- A user declaration of a CCallable/CReturnable instance
        -- must be for a "boxed primitive" type.
     isCcallishClass clas
-    && not opt_CompilingPrelude                -- which allows anything
-    && maybeToBool (maybeBoxedPrimType inst_tau)
+    && not (maybeToBool (maybeBoxedPrimType inst_tau))
   = failTc (nonBoxedPrimCCallErr clas inst_tau)
 
   | otherwise
@@ -947,9 +958,7 @@ derivingWhenInstanceImportedErr inst_mod clas tycon sty
   = ppHang (ppBesides [ppStr "Deriving class `", ppr sty clas, ppStr "' type `", ppr sty tycon, ppStr "'"])
          4 (ppBesides [ppStr "when an instance declared in module `", pp_mod, ppStr "' has been imported"])
   where
-    pp_mod = case inst_mod of
-              Nothing -> ppPStr SLIT("the standard Prelude")
-              Just  m -> ppBesides [ppStr "module `", ppPStr m, ppStr "'"]
+    pp_mod = ppBesides [ppStr "module `", ppPStr inst_mod, ppStr "'"]
 
 nonBoxedPrimCCallErr clas inst_ty sty
   = ppHang (ppStr "Instance isn't for a `boxed-primitive' type")