[project @ 1996-03-21 12:46:33 by partain]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcInstDcls.lhs
index 2f75b9d..6e3db5b 100644 (file)
@@ -36,7 +36,7 @@ import Inst           ( Inst, InstOrigin(..), InstanceMapper(..),
                          newDicts, newMethod, LIE(..), emptyLIE, plusLIE )
 import TcBinds         ( tcPragmaSigs )
 import TcDeriv         ( tcDeriving )
                          newDicts, newMethod, LIE(..), emptyLIE, plusLIE )
 import TcBinds         ( tcPragmaSigs )
 import TcDeriv         ( tcDeriving )
-import TcEnv           ( tcLookupClass, tcTyVarScope, newLocalIds )
+import TcEnv           ( tcLookupClass, tcTyVarScope, newLocalId )
 import TcGRHSs         ( tcGRHSsAndBinds )
 import TcInstUtil      ( InstInfo(..), mkInstanceRelatedIds, buildInstanceEnvs )
 import TcKind          ( TcKind, unifyKind )
 import TcGRHSs         ( tcGRHSsAndBinds )
 import TcInstUtil      ( InstInfo(..), mkInstanceRelatedIds, buildInstanceEnvs )
 import TcKind          ( TcKind, unifyKind )
@@ -57,7 +57,7 @@ import Class          ( GenClass, GenClassOp,
                          isCcallishClass, getClassBigSig,
                          getClassOps, getClassOpLocalType )
 import CoreUtils       ( escErrorMsg )
                          isCcallishClass, getClassBigSig,
                          getClassOps, getClassOpLocalType )
 import CoreUtils       ( escErrorMsg )
-import Id              ( idType, isDefaultMethodId_maybe )
+import Id              ( GenId, idType, isDefaultMethodId_maybe )
 import ListSetOps      ( minusList )
 import Maybes          ( maybeToBool, expectJust )
 import Name            ( Name, getTagFromClassOpName )
 import ListSetOps      ( minusList )
 import Maybes          ( maybeToBool, expectJust )
 import Name            ( Name, getTagFromClassOpName )
@@ -69,10 +69,10 @@ import PprStyle
 import Pretty
 import RnUtils         ( GlobalNameMappers(..), GlobalNameMapper(..) )
 import TyCon           ( derivedFor )
 import Pretty
 import RnUtils         ( GlobalNameMappers(..), GlobalNameMapper(..) )
 import TyCon           ( derivedFor )
-import Type            ( GenType(..),  ThetaType(..), mkTyVarTy,
-                         splitSigmaTy, splitAppTy, isTyVarTy, matchTy,
+import Type            ( GenType(..),  ThetaType(..), mkTyVarTys,
+                         splitSigmaTy, splitAppTy, isTyVarTy, matchTy, mkSigmaTy,
                          getTyCon_maybe, maybeBoxedPrimType )
                          getTyCon_maybe, maybeBoxedPrimType )
-import TyVar           ( GenTyVar, tyVarListToSet )
+import TyVar           ( GenTyVar, mkTyVarSet )
 import TysWiredIn      ( stringTy )
 import Unique          ( Unique )
 import Util            ( panic )
 import TysWiredIn      ( stringTy )
 import Unique          ( Unique )
 import Util            ( panic )
@@ -348,7 +348,7 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
        -- Get the class signature
     mapNF_Tc tcInstTyVar inst_tyvars   `thenNF_Tc` \ inst_tyvars' ->
     let 
        -- Get the class signature
     mapNF_Tc tcInstTyVar inst_tyvars   `thenNF_Tc` \ inst_tyvars' ->
     let 
-       tenv = inst_tyvars `zip` (map mkTyVarTy inst_tyvars')
+       tenv = inst_tyvars `zip` (mkTyVarTys inst_tyvars')
 
         (class_tyvar,
         super_classes, sc_sel_ids,
 
         (class_tyvar,
         super_classes, sc_sel_ids,
@@ -360,7 +360,7 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
     let
        sc_theta'        = super_classes `zip` (repeat inst_ty')
        origin           = InstanceDeclOrigin
     let
        sc_theta'        = super_classes `zip` (repeat inst_ty')
        origin           = InstanceDeclOrigin
-       mk_method sel_id = newMethod origin (RealId sel_id) [inst_ty']
+       mk_method sel_id = newMethodId sel_id inst_ty' origin locn
     in
         -- Create dictionary Ids from the specified instance contexts.
     newDicts origin sc_theta'          `thenNF_Tc` \ (sc_dicts,        sc_dict_ids) ->
     in
         -- Create dictionary Ids from the specified instance contexts.
     newDicts origin sc_theta'          `thenNF_Tc` \ (sc_dicts,        sc_dict_ids) ->
@@ -392,7 +392,7 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
        dict_and_method_binds
            = dict_bind `AndMonoBinds` method_mbinds
 
        dict_and_method_binds
            = dict_bind `AndMonoBinds` method_mbinds
 
-       inst_tyvars_set' = tyVarListToSet inst_tyvars'
+       inst_tyvars_set' = mkTyVarSet inst_tyvars'
     in
        -- Check the overloading constraints of the methods and superclasses
     tcAddErrCtxt (bindSigCtxt meth_ids) (
     in
        -- Check the overloading constraints of the methods and superclasses
     tcAddErrCtxt (bindSigCtxt meth_ids) (
@@ -439,7 +439,55 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
     returnTc (const_lie `plusLIE` spec_lie, inst_binds)
 \end{code}
 
     returnTc (const_lie `plusLIE` spec_lie, inst_binds)
 \end{code}
 
-This function makes a default method which calls the global default method, at
+@mkMethodId@ manufactures an id for a local method.
+It's rather turgid stuff, because there are two cases:
+
+  (a) For methods with no local polymorphism, we can make an Inst of the 
+      class-op selector function and a corresp InstId; 
+      which is good because then other methods which call
+      this one will do so directly.
+
+  (b) For methods with local polymorphism, we can't do this.  For example,
+
+        class Foo a where
+               op :: (Num b) => a -> b -> a
+
+      Here the type of the class-op-selector is
+
+       forall a b. (Foo a, Num b) => a -> b -> a
+
+      The locally defined method at (say) type Float will have type
+
+       forall b. (Num b) => Float -> b -> Float
+
+      and the one is not an instance of the other.
+
+      So for these we just make a local (non-Inst) id with a suitable type.
+
+How disgusting.
+
+\begin{code}
+newMethodId sel_id inst_ty origin loc
+  = 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 
+       case sel_tyvars of
+       -- Ah! a selector for a class op with no local polymorphism
+       -- Build an Inst for this
+       [clas_tyvar] -> newMethod origin (RealId sel_id) [inst_ty]
+
+       -- Ho! a selector for a class op with local polymorphism.
+       -- Just make a suitably typed local id for this
+       (clas_tyvar:local_tyvars) -> 
+               tcInstType [(clas_tyvar,inst_ty)]
+                          (mkSigmaTy local_tyvars meth_theta sel_tau)
+                                                               `thenNF_Tc` \ method_ty ->
+               newLocalId (getOccurrenceName 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
 the appropriate instance type.
 
 See the notes under default decls in TcClassDcl.lhs.
 the appropriate instance type.
 
 See the notes under default decls in TcClassDcl.lhs.
@@ -465,7 +513,7 @@ makeInstanceDeclDefaultMethodExpr origin this_dict class_ops defm_ids inst_ty ta
       mkHsTyLam op_tyvars (
       mkHsDictLam op_dicts (
       mkHsDictApp (mkHsTyApp (HsVar (RealId defm_id))
       mkHsTyLam op_tyvars (
       mkHsDictLam op_dicts (
       mkHsDictApp (mkHsTyApp (HsVar (RealId defm_id))
-                            (inst_ty :  map mkTyVarTy op_tyvars))
+                            (inst_ty :  mkTyVarTys op_tyvars))
                  (this_dict : op_dicts)
       )))
  where
                  (this_dict : op_dicts)
       )))
  where
@@ -640,9 +688,9 @@ processInstBinds1 inst_tyvars avail_insts method_ids mbind
                -- The latter is needed just so we can return an AbsBinds wrapped
                -- up inside a MonoBinds.
 
                -- The latter is needed just so we can return an AbsBinds wrapped
                -- up inside a MonoBinds.
 
-       newLocalIds [occ,occ] [method_tau,method_ty] `thenNF_Tc` \ new_ids ->
+       newLocalId occ method_tau               `thenNF_Tc` \ local_id ->
+       newLocalId occ method_ty                `thenNF_Tc` \ copy_id ->
        let
        let
-           [local_id, copy_id] = map TcId new_ids
            inst_method_tyvars = inst_tyvars ++ method_tyvars
        in
                -- Typecheck the method
            inst_method_tyvars = inst_tyvars ++ method_tyvars
        in
                -- Typecheck the method
@@ -665,7 +713,7 @@ processInstBinds1 inst_tyvars avail_insts method_ids mbind
                -- the Bar-ish things.
        tcAddErrCtxt (methodSigCtxt op method_ty) (
          tcSimplifyAndCheck
                -- the Bar-ish things.
        tcAddErrCtxt (methodSigCtxt op method_ty) (
          tcSimplifyAndCheck
-               (tyVarListToSet inst_method_tyvars)
+               (mkTyVarSet inst_method_tyvars)
                (method_dicts `plusLIE` avail_insts)
                lieIop
        )                                        `thenTc` \ (f_dicts, dict_binds) ->
                (method_dicts `plusLIE` avail_insts)
                lieIop
        )                                        `thenTc` \ (f_dicts, dict_binds) ->
@@ -747,7 +795,7 @@ tcSpecInstSig e ce tce inst_infos inst_mapper (SpecInstSig class_name ty src_loc
     babyTcMtoTcM (tcInstanceType ce tce tmpl_e True src_loc ty)
                                `thenTc` \ inst_ty ->
     let
     babyTcMtoTcM (tcInstanceType ce tce tmpl_e True src_loc ty)
                                `thenTc` \ inst_ty ->
     let
-       maybe_tycon = case maybeDataTyCon inst_ty of
+       maybe_tycon = case maybeAppDataTyCon inst_ty of
                         Just (tc,_,_) -> Just tc
                         Nothing       -> Nothing
 
                         Just (tc,_,_) -> Just tc
                         Nothing       -> Nothing
 
@@ -818,7 +866,7 @@ lookup_unspec_inst clas maybe_tycon inst_infos
                      Just tycon -> match_tycon tycon
                      Nothing    -> match_fun
 
                      Just tycon -> match_tycon tycon
                      Nothing    -> match_fun
 
-    match_tycon tycon inst_ty = case (maybeDataTyCon inst_ty) of
+    match_tycon tycon inst_ty = case (maybeAppDataTyCon inst_ty) of
          Just (inst_tc,_,_) -> tycon == inst_tc
          Nothing            -> False
 
          Just (inst_tc,_,_) -> tycon == inst_tc
          Nothing            -> False
 
@@ -826,7 +874,7 @@ lookup_unspec_inst clas maybe_tycon inst_infos
 
 
 is_plain_instance inst_ty
 
 
 is_plain_instance inst_ty
-  = case (maybeDataTyCon inst_ty) of
+  = case (maybeAppDataTyCon inst_ty) of
       Just (_,tys,_) -> all isTyVarTemplateTy tys
       Nothing       -> case maybeUnpackFunTy inst_ty of
                          Just (arg, res) -> isTyVarTemplateTy arg && isTyVarTemplateTy res
       Just (_,tys,_) -> all isTyVarTemplateTy tys
       Nothing       -> case maybeUnpackFunTy inst_ty of
                          Just (arg, res) -> isTyVarTemplateTy arg && isTyVarTemplateTy res