[project @ 2000-11-24 09:51:38 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcInstDcls.lhs
index b2298bf..2a95703 100644 (file)
@@ -30,37 +30,37 @@ import TcDeriv              ( tcDeriving )
 import TcEnv           ( TcEnv, tcExtendGlobalValEnv, 
                          tcExtendTyVarEnvForMeths, 
                          tcAddImportedIdInfo, tcInstId, tcLookupClass,
+                         InstInfo(..), pprInstInfo, simpleInstInfoTyCon, simpleInstInfoTy, 
                          newDFunName, tcExtendTyVarEnv
                        )
-import InstEnv         ( InstInfo(..), InstEnv, pprInstInfo, classDataCon, 
-                         simpleInstInfoTyCon, simpleInstInfoTy, isLocalInst,
-                         extendInstEnv )
+import InstEnv         ( InstEnv, extendInstEnv )
 import TcMonoType      ( tcTyVars, tcHsSigType, kcHsSigType )
 import TcSimplify      ( tcSimplifyAndCheck )
 import TcType          ( zonkTcSigTyVars )
-import HscTypes                ( PersistentCompilerState(..), HomeSymbolTable, DFunId,
+import HscTypes                ( HomeSymbolTable, DFunId,
                          ModDetails(..), PackageInstEnv, PersistentRenamerState
                        )
 
 import Bag             ( unionManyBags )
+import DataCon         ( classDataCon )
 import Class           ( Class, DefMeth(..), classBigSig )
 import Var             ( idName, idType )
 import Maybes          ( maybeToBool )
 import MkId            ( mkDictFunId )
 import Generics                ( validGenericInstanceType )
 import Module          ( Module, foldModuleEnv )
-import Name            ( isLocallyDefined )
+import Name            ( getSrcLoc )
 import NameSet         ( emptyNameSet, nameSetToList )
 import PrelInfo                ( eRROR_ID )
 import PprType         ( pprConstraint, pprPred )
-import TyCon           ( TyCon, isSynTyCon, tyConDerivings )
-import Type            ( mkTyVarTys, splitDFunTy, isTyVarTy,
+import TyCon           ( TyCon, isSynTyCon )
+import Type            ( splitDFunTy, isTyVarTy,
                          splitTyConApp_maybe, splitDictTy,
-                         splitAlgTyConApp_maybe, 
-                         unUsgTy, tyVarsOfTypes, mkClassPred, mkTyVarTy,
+                         splitForAllTys,
+                         tyVarsOfTypes, mkClassPred, mkTyVarTy,
                          getClassTys_maybe
                        )
-import Subst           ( mkTopTyVarSubst, substClasses, substTheta )
+import Subst           ( mkTopTyVarSubst, substClasses )
 import VarSet          ( mkVarSet, varSetElems )
 import TysWiredIn      ( genericTyCons, isFFIArgumentTy, isFFIResultTy )
 import PrelNames       ( cCallableClassKey, cReturnableClassKey, hasKey )
@@ -167,14 +167,14 @@ tcInstDecls1 :: PackageInstEnv
             -> TcEnv                   -- Contains IdInfo for dfun ids
             -> (Name -> Maybe Fixity)  -- for deriving Show and Read
             -> Module                  -- Module for deriving
-            -> [TyCon]
             -> [RenamedHsDecl]
             -> TcM (PackageInstEnv, InstEnv, [InstInfo], RenamedHsBinds)
 
-tcInstDecls1 inst_env0 prs hst unf_env get_fixity mod local_tycons decls
+tcInstDecls1 inst_env0 prs hst unf_env get_fixity mod decls
   = let
-       inst_decls = [inst_decl | InstD inst_decl <- decls]
-       clas_decls = [clas_decl | TyClD clas_decl <- decls, isClassDecl clas_decl]
+       inst_decls = [inst_decl | InstD inst_decl <- decls]     
+       tycl_decls = [decl      | TyClD decl <- decls]
+       clas_decls = filter isClassDecl tycl_decls
     in
        -- (1) Do the ordinary instance declarations
     mapNF_Tc (tcInstDecl1 mod unf_env) inst_decls      `thenNF_Tc` \ inst_infos ->
@@ -190,8 +190,7 @@ tcInstDecls1 inst_env0 prs hst unf_env get_fixity mod local_tycons decls
        --      e) generic instances                                    inst_env4
        -- The result of (b) replaces the cached InstEnv in the PCS
     let
-       (local_inst_info, imported_inst_info)
-          = partition isLocalInst (concat inst_infos)
+       (local_inst_info, imported_inst_info) = partition iLocal (concat inst_infos)
 
        imported_dfuns   = map (tcAddImportedIdInfo unf_env . iDFunId) 
                               imported_inst_info
@@ -207,8 +206,8 @@ tcInstDecls1 inst_env0 prs hst unf_env get_fixity mod local_tycons decls
        --     we ignore deriving decls from interfaces!
        -- This stuff computes a context for the derived instance decl, so it
        -- needs to know about all the instances possible; hecne inst_env4
-    tcDeriving prs mod inst_env4 get_fixity local_tycons       `thenTc` \ (deriv_inst_info, deriv_binds) ->
-    addInstInfos inst_env4 deriv_inst_info                     `thenNF_Tc` \ final_inst_env ->
+    tcDeriving prs mod inst_env4 get_fixity tycl_decls `thenTc` \ (deriv_inst_info, deriv_binds) ->
+    addInstInfos inst_env4 deriv_inst_info             `thenNF_Tc` \ final_inst_env ->
 
     returnTc (inst_env1, 
              final_inst_env, 
@@ -221,12 +220,11 @@ addInstInfos inst_env infos = addInstDFuns inst_env (map iDFunId infos)
 addInstDFuns :: InstEnv -> [DFunId] -> NF_TcM InstEnv
 addInstDFuns dfuns infos
   = getDOptsTc                         `thenTc` \ dflags ->
-    extendInstEnv dflags dfuns infos   `bind`   \ (inst_env', errs) ->
+    let
+       (inst_env', errs) = extendInstEnv dflags dfuns infos
+    in
     addErrsTc errs                     `thenNF_Tc_` 
     returnTc inst_env'
-  where
-    bind x f = f x
-
 \end{code} 
 
 \begin{code}
@@ -256,17 +254,18 @@ tcInstDecl1 mod unf_env (InstDecl poly_ty binds uprags maybe_dfun_name src_loc)
 
                -- Make the dfun id and return it
            newDFunName mod clas inst_tys src_loc               `thenNF_Tc` \ dfun_name ->
-           returnNF_Tc (True, mkDictFunId dfun_name clas tyvars inst_tys theta)
+           returnNF_Tc (True, dfun_name)
 
        Just dfun_name ->       -- An interface-file instance declaration
                -- Make the dfun id
-           returnNF_Tc (False, mkDictFunId dfun_name clas tyvars inst_tys theta)
-    )                                          `thenNF_Tc` \ (is_local, dfun_id) ->
+           returnNF_Tc (False, dfun_name)
+    )                                          `thenNF_Tc` \ (is_local, dfun_name) ->
 
-    returnTc [InstInfo { iLocal = is_local,
-                        iClass = clas, iTyVars = tyvars, iTys = inst_tys,
-                        iTheta = theta, iDFunId = dfun_id, 
-                        iBinds = binds, iLoc = src_loc, iPrags = uprags }]
+    let
+       dfun_id = mkDictFunId dfun_name clas tyvars inst_tys theta
+    in
+    returnTc [InstInfo { iLocal = is_local, iDFunId = dfun_id, 
+                        iBinds = binds,    iPrags = uprags }]
 \end{code}
 
 
@@ -335,15 +334,18 @@ get_generics mod decl@(ClassDecl context class_name tyvar_names
        --      f {| x+y |} ... = ...
        -- Then at this point we'll have an InstInfo for each
     let
-       bad_groups = [group | group <- equivClassesByUniq get_uniq inst_infos,
+       tc_inst_infos :: [(TyCon, InstInfo)]
+       tc_inst_infos = [(simpleInstInfoTyCon i, i) | i <- inst_infos]
+
+       bad_groups = [group | group <- equivClassesByUniq get_uniq tc_inst_infos,
                              length group > 1]
-       get_uniq inst = getUnique (simpleInstInfoTyCon inst)
+       get_uniq (tc,_) = getUnique tc
     in
     mapTc (addErrTc . dupGenericInsts) bad_groups      `thenTc_`
 
        -- Check that there is an InstInfo for each generic type constructor
     let
-       missing = genericTyCons `minusList` map simpleInstInfoTyCon inst_infos
+       missing = genericTyCons `minusList` [tc | (tc,_) <- tc_inst_infos]
     in
     checkTc (null missing) (missingGenericInstances missing)   `thenTc_`
 
@@ -365,9 +367,11 @@ getGenericBinds (AndMonoBinds m1 m2)
   = plusAssoc_C AndMonoBinds (getGenericBinds m1) (getGenericBinds m2)
 
 getGenericBinds (FunMonoBind id infixop matches loc)
-  = mapAssoc wrap (foldr add emptyAssoc matches)
+  = mapAssoc wrap (foldl add emptyAssoc matches)
+       -- Using foldl not foldr is vital, else
+       -- we reverse the order of the bindings!
   where
-    add match env = case maybeGenericMatch match of
+    add env match = case maybeGenericMatch match of
                      Nothing           -> env
                      Just (ty, match') -> extendAssoc_C (++) env (ty, [match'])
 
@@ -400,10 +404,8 @@ mkGenericInstance mod clas loc (hs_ty, binds)
        dfun_id    = mkDictFunId dfun_name clas tyvars inst_tys inst_theta
     in
 
-    returnTc (InstInfo { iLocal = True,
-                        iClass = clas, iTyVars = tyvars, iTys = inst_tys, 
-                        iTheta = inst_theta, iDFunId = dfun_id, iBinds = binds,
-                        iLoc = loc, iPrags = [] })
+    returnTc (InstInfo { iLocal = True, iDFunId = dfun_id, 
+                        iBinds = binds, iPrags = [] })
 \end{code}
 
 
@@ -497,16 +499,15 @@ First comes the easy case of a non-local instance decl.
 \begin{code}
 tcInstDecl2 :: InstInfo -> NF_TcM (LIE, TcMonoBinds)
 
-tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
-                       iTheta = inst_decl_theta, iDFunId = dfun_id,
-                       iBinds = monobinds, iLoc = locn, iPrags = uprags })
-  | not (isLocallyDefined dfun_id)
+tcInstDecl2 (InstInfo { iLocal = is_local, iDFunId = dfun_id, 
+                       iBinds = monobinds, iPrags = uprags })
+  | not is_local
   = returnNF_Tc (emptyLIE, EmptyMonoBinds)
 
   | otherwise
   =     -- Prime error recovery
     recoverNF_Tc (returnNF_Tc (emptyLIE, EmptyMonoBinds))  $
-    tcAddSrcLoc locn                                      $
+    tcAddSrcLoc (getSrcLoc dfun_id)                       $
 
        -- Instantiate the instance decl with tc-style type variables
     tcInstId dfun_id           `thenNF_Tc` \ (inst_tyvars', dfun_theta', dict_ty') ->
@@ -519,15 +520,16 @@ tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
        dm_ids    = [dm_id | (_, DefMeth dm_id) <- op_items]
        sel_names = [idName sel_id | (sel_id, _) <- op_items]
 
-       -- Instantiate the theta found in the original instance decl
-       inst_decl_theta' = substTheta (mkTopTyVarSubst inst_tyvars (mkTyVarTys inst_tyvars'))
-                                     inst_decl_theta
-
         -- Instantiate the super-class context with inst_tys
        sc_theta' = substClasses (mkTopTyVarSubst class_tyvars inst_tys') sc_theta
 
        -- Find any definitions in monobinds that aren't from the class
        bad_bndrs = collectMonoBinders monobinds `minusList` sel_names
+
+       -- The type variable from the dict fun actually scope 
+       -- over the bindings.  They were gotten from
+       -- the original instance declaration
+       (inst_tyvars, _) = splitForAllTys (idType dfun_id)
     in
         -- Check that all the method bindings come from this class
     mapTc (addErrTc . badMethodErr clas) bad_bndrs             `thenNF_Tc_`
@@ -535,7 +537,6 @@ tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
         -- Create dictionary Ids from the specified instance contexts.
     newClassDicts origin sc_theta'             `thenNF_Tc` \ (sc_dicts,        sc_dict_ids) ->
     newDicts origin dfun_theta'                        `thenNF_Tc` \ (dfun_arg_dicts,  dfun_arg_dicts_ids)  ->
-    newDicts origin inst_decl_theta'           `thenNF_Tc` \ (inst_decl_dicts, _) ->
     newClassDicts origin [(clas,inst_tys')]    `thenNF_Tc` \ (this_dict,       [this_dict_id]) ->
 
     tcExtendTyVarEnvForMeths inst_tyvars inst_tyvars' (
@@ -543,7 +544,7 @@ tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
                -- Default-method Ids may be mentioned in synthesised RHSs 
 
        mapAndUnzip3Tc (tcMethodBind clas origin inst_tyvars' inst_tys'
-                                    inst_decl_theta'
+                                    dfun_theta'
                                     monobinds uprags True)
                       op_items
     ))                 `thenTc` \ (method_binds_s, insts_needed_s, meth_lies_w_ids) ->
@@ -577,7 +578,7 @@ tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
         methods_lie = plusLIEs insts_needed_s
     in
 
-       -- Ditto method bindings
+       -- Simplify the constraints from methods
     tcAddErrCtxt methodCtxt (
       tcSimplifyAndCheck
                 (ptext SLIT("instance declaration context"))
@@ -586,26 +587,10 @@ tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
                 methods_lie
     )                                           `thenTc` \ (const_lie1, lie_binds1) ->
     
-       -- Check that we *could* construct the superclass dictionaries,
-       -- even though we are *actually* going to pass the superclass dicts in;
-       -- the check ensures that the caller will never have 
-       --a problem building them.
+       -- Figure out bindings for the superclass context
     tcAddErrCtxt superClassCtxt (
       tcSimplifyAndCheck
                 (ptext SLIT("instance declaration context"))
-                inst_tyvars_set                -- Local tyvars
-                inst_decl_dicts                -- The instance dictionaries available
-                sc_dicts                       -- The superclass dicationaries reqd
-    )                                  `thenTc` \ _ -> 
-                                               -- Ignore the result; we're only doing
-                                               -- this to make sure it can be done.
-
-       -- Now do the simplification again, this time to get the
-       -- bindings; this time we use an enhanced "avails"
-       -- Ignore errors because they come from the *previous* tcSimplify
-    discardErrsTc (
-       tcSimplifyAndCheck
-                (ptext SLIT("instance declaration context"))
                 inst_tyvars_set
                 dfun_arg_dicts         -- NB! Don't include this_dict here, else the sc_dicts
                                        -- get bound by just selecting from this_dict!!
@@ -626,7 +611,7 @@ tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys,
                -- emit an error message.  This in turn means that we don't
                -- mention the constructor, which doesn't exist for CCallable, CReturnable
                -- Hardly beautiful, but only three extra lines.
-           HsApp (TyApp (HsVar eRROR_ID) [(unUsgTy . idType) this_dict_id])
+           HsApp (TyApp (HsVar eRROR_ID) [idType this_dict_id])
                  (HsLit (HsString msg))
 
          | otherwise   -- The common case
@@ -702,13 +687,6 @@ scrutiniseInstanceHead clas inst_taus
             && not (creturnable_type first_inst_tau))
      -> addErrTc (nonBoxedPrimCCallErr clas first_inst_tau)
 
-       -- DERIVING CHECK
-       -- It is obviously illegal to have an explicit instance
-       -- for something that we are also planning to `derive'
-     |  maybeToBool alg_tycon_app_maybe && clas `elem` (tyConDerivings alg_tycon)
-     -> addErrTc (derivingWhenInstanceExistsErr clas first_inst_tau)
-          -- Kind check will have ensured inst_taus is of length 1
-
        -- Allow anything for AllowUndecidableInstances
      |  dopt Opt_AllowUndecidableInstances dflags
      -> returnNF_Tc ()
@@ -743,11 +721,6 @@ scrutiniseInstanceHead clas inst_taus
     maybe_tycon_app      = splitTyConApp_maybe first_inst_tau
     Just (tycon, arg_tys) = maybe_tycon_app
 
-       -- Stuff for an *algebraic* data type
-    alg_tycon_app_maybe           = splitAlgTyConApp_maybe first_inst_tau
-                               -- The "Alg" part looks through synonyms
-    Just (alg_tycon, _, _) = alg_tycon_app_maybe
     ccallable_type   dflags ty = isFFIArgumentTy dflags False {- Not safe call -} ty
     creturnable_type        ty = isFFIResultTy ty
 \end{code}
@@ -792,28 +765,24 @@ missingGenericInstances missing
          
 
 
-dupGenericInsts inst_infos
+dupGenericInsts tc_inst_infos
   = vcat [ptext SLIT("More than one type pattern for a single generic type constructor:"),
-         nest 4 (vcat (map (ppr . simpleInstInfoTy) inst_infos)),
+         nest 4 (vcat (map ppr_inst_ty tc_inst_infos)),
          ptext SLIT("All the type patterns for a generic type constructor must be identical")
     ]
+  where 
+    ppr_inst_ty (tc,inst) = ppr (simpleInstInfoTy inst)
 
 instTypeErr clas tys msg
   = sep [ptext SLIT("Illegal instance declaration for") <+> quotes (pprConstraint clas tys),
         nest 4 (parens msg)
     ]
 
-derivingWhenInstanceExistsErr clas tycon
-  = hang (hsep [ptext SLIT("Deriving class"), 
-                      quotes (ppr clas), 
-                      ptext SLIT("type"), quotes (ppr tycon)])
-         4 (ptext SLIT("when an explicit instance exists"))
-
 nonBoxedPrimCCallErr clas inst_ty
   = hang (ptext SLIT("Unacceptable instance type for ccall-ish class"))
         4 (hsep [ ptext SLIT("class"), ppr clas, ptext SLIT("type"),
                        ppr inst_ty])
 
 methodCtxt     = ptext SLIT("When checking the methods of an instance declaration")
-superClassCtxt = ptext SLIT("When checking the superclasses of an instance declaration")
+superClassCtxt = ptext SLIT("When checking the super-classes of an instance declaration")
 \end{code}