From 483817dd051f011218c3c7041809ef019a7ebd0d Mon Sep 17 00:00:00 2001 From: simonmar Date: Tue, 22 Jan 2002 13:35:37 +0000 Subject: [PATCH] [project @ 2002-01-22 13:35:36 by simonmar] Attempt to fix the problems with missing instances once more. The current problem is that in the case where a ModDetails is being constructed from its interface (in compilation manager modes) we weren't getting any instances because the instances are gotten from the [InstInfo] returned from tcInstDecls1, which only contains *source* instance declarations. Fix: return a list of DFuns defined in the current module from tcInstDecls1, to be plugged into the ModDetails later. Also: revert the previous change to the isLocalThing predicate, because now we really want to know which dfuns come from the current module. The comment about the iface_dfuns containing only package and local instances is incorrect in batch-compile mode, because we also demand-load stuff from home package interfaces, so I deleted this comment and fixed up some of the other commentary. --- ghc/compiler/typecheck/TcEnv.lhs | 8 +--- ghc/compiler/typecheck/TcInstDcls.lhs | 73 ++++++++++++++++++--------------- ghc/compiler/typecheck/TcModule.lhs | 48 +++++++++++----------- 3 files changed, 66 insertions(+), 63 deletions(-) diff --git a/ghc/compiler/typecheck/TcEnv.lhs b/ghc/compiler/typecheck/TcEnv.lhs index d2b7ce4..744fb42 100644 --- a/ghc/compiler/typecheck/TcEnv.lhs +++ b/ghc/compiler/typecheck/TcEnv.lhs @@ -33,7 +33,7 @@ module TcEnv( newLocalName, newDFunName, -- Misc - isLocalThing, isHomePackageThing, tcSetEnv + isLocalThing, tcSetEnv ) where #include "HsVersions.h" @@ -53,8 +53,7 @@ import DataCon ( DataCon ) import TyCon ( TyCon ) import Class ( Class, ClassOpItem ) import Name ( Name, NamedThing(..), - getSrcLoc, mkLocalName, isLocalName, nameIsLocalOrFrom, - isHomePackageName + getSrcLoc, mkLocalName, isLocalName, nameIsLocalOrFrom ) import NameEnv ( NameEnv, lookupNameEnv, nameEnvElts, elemNameEnv, extendNameEnvList, emptyNameEnv, plusNameEnv ) @@ -254,9 +253,6 @@ newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc) \begin{code} isLocalThing :: NamedThing a => Module -> a -> Bool isLocalThing mod thing = nameIsLocalOrFrom mod (getName thing) - -isHomePackageThing :: NamedThing a => a -> Bool -isHomePackageThing thing = isHomePackageName (getName thing) \end{code} %************************************************************************ diff --git a/ghc/compiler/typecheck/TcInstDcls.lhs b/ghc/compiler/typecheck/TcInstDcls.lhs index 98a7075..3787abd 100644 --- a/ghc/compiler/typecheck/TcInstDcls.lhs +++ b/ghc/compiler/typecheck/TcInstDcls.lhs @@ -33,7 +33,7 @@ import TcType ( mkClassPred, mkTyVarTy, mkTyVarTys, tcSplitForAllTys, import Inst ( InstOrigin(..), newDicts, instToId, LIE, mkLIE, emptyLIE, plusLIE, plusLIEs ) import TcDeriv ( tcDeriving ) -import TcEnv ( TcEnv, tcExtendGlobalValEnv, isHomePackageThing, +import TcEnv ( TcEnv, tcExtendGlobalValEnv, isLocalThing, tcExtendTyVarEnvForMeths, tcLookupId, tcLookupClass, InstInfo(..), pprInstInfo, simpleInstInfoTyCon, simpleInstInfoTy, newDFunName @@ -158,14 +158,19 @@ and $dbinds_super$ bind the superclass dictionaries sd1 \ldots sdm. Gather up the instance declarations from their various sources \begin{code} -tcInstDecls1 :: PackageInstEnv - -> PersistentRenamerState - -> HomeSymbolTable -- Contains instances - -> TcEnv -- Contains IdInfo for dfun ids - -> (Name -> Maybe Fixity) -- for deriving Show and Read - -> Module -- Module for deriving - -> [RenamedHsDecl] - -> TcM (PackageInstEnv, InstEnv, [InstInfo], RenamedHsBinds) +tcInstDecls1 + :: PackageInstEnv + -> PersistentRenamerState + -> HomeSymbolTable -- Contains instances + -> TcEnv -- Contains IdInfo for dfun ids + -> (Name -> Maybe Fixity) -- for deriving Show and Read + -> Module -- Module for deriving + -> [RenamedHsDecl] + -> TcM (PackageInstEnv, -- cached package inst env + InstEnv, -- the full inst env + [InstInfo], -- instance decls to process + [DFunId], -- instances from this module, for its iface + RenamedHsBinds) -- derived instances tcInstDecls1 inst_env0 prs hst unf_env get_fixity this_mod decls = let @@ -175,37 +180,37 @@ tcInstDecls1 inst_env0 prs hst unf_env get_fixity this_mod decls (iface_inst_ds, local_inst_ds) = partition isIfaceInstDecl inst_decls in -- (1) Do the ordinary instance declarations - mapNF_Tc tcLocalInstDecl1 local_inst_ds `thenNF_Tc` \ local_inst_infos -> - mapNF_Tc tcImportedInstDecl1 iface_inst_ds `thenNF_Tc` \ iface_dfuns -> + mapNF_Tc tcLocalInstDecl1 local_inst_ds `thenNF_Tc` \ local_inst_infos -> + mapNF_Tc tcImportedInstDecl1 iface_inst_ds `thenNF_Tc` \ iface_dfuns -> -- (2) Instances from generic class declarations - getGenericInstances clas_decls `thenTc` \ generic_inst_info -> + getGenericInstances clas_decls `thenTc` \ generic_inst_info -> -- Next, construct the instance environment so far, consisting of - -- a) cached non-home-package InstEnv (gotten from pcs) inst_env0 - -- b) imported instance decls (not in the home package) inst_env1 - -- c) imported instance decls (from this module) inst_env2 - -- c) other modules in this package (gotten from hst) inst_env3 - -- d) local instance decls inst_env4 - -- e) generic instances inst_env5 + -- a) cached non-home-package InstEnv (gotten from pcs) inst_env0 + -- b) imported instance decls (not in the home package) inst_env1 + -- c) other modules in this package (gotten from hst) inst_env2 + -- d) imported instance decls (from this module) inst_env3 + -- e) local instance decls inst_env4 + -- f) generic instances inst_env5 -- The result of (b) replaces the cached InstEnv in the PCS -- - -- Note that iface_dfuns may contain not only insts that we demand-loaded - -- from package interface files, but also instances from the current module - -- in the case where we are loading this module's interface file in GHCi, - -- so we partition the iface_dfuns into package instances and local instances - -- below so that we don't end up with home package instances in the PCS. + -- Note that iface_dfuns may contain not only insts that we + -- demand-loaded from interface files, but also instances from + -- the current module in the case where we are loading this + -- module's interface file in GHCi, so we partition the + -- iface_dfuns into non-local and local instances so that we + -- don't end up with home package instances in the PCS. -- -- There can't be any instance declarations from the home -- package other than from the current module (with the -- compilation manager) because they are loaded explicitly by - -- the compilation manager. The partition is really only - -- necessary when we're under control of the compilation - -- manager. + -- the compilation manager. let local_inst_info = catMaybes local_inst_infos - (local_iface_dfuns, pkg_iface_dfuns) = partition isHomePackageThing iface_dfuns - hst_dfuns = foldModuleEnv ((++) . md_insts) [] hst + (local_iface_dfuns, pkg_iface_dfuns) + = partition (isLocalThing this_mod) iface_dfuns + hst_dfuns = foldModuleEnv ((++) . md_insts) [] hst in -- pprTrace "tcInstDecls" (vcat [ppr imported_dfuns, ppr hst_dfuns]) $ @@ -220,14 +225,16 @@ tcInstDecls1 inst_env0 prs hst unf_env get_fixity this_mod decls -- note that we only do derivings for things in this module; -- 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; hence inst_env4 - tcDeriving prs this_mod inst_env4 get_fixity tycl_decls - `thenTc` \ (deriv_inst_info, deriv_binds) -> - addInstInfos inst_env4 deriv_inst_info `thenNF_Tc` \ final_inst_env -> + -- needs to know about all the instances possible; hence inst_env5 + tcDeriving prs this_mod inst_env5 get_fixity tycl_decls + `thenTc` \ (deriv_inst_info, deriv_binds) -> + addInstInfos inst_env5 deriv_inst_info `thenNF_Tc` \ final_inst_env -> + let inst_info = generic_inst_info ++ deriv_inst_info ++ local_inst_info in returnTc (inst_env1, final_inst_env, - generic_inst_info ++ deriv_inst_info ++ local_inst_info, + inst_info, + local_iface_dfuns ++ map iDFunId inst_info, deriv_binds) addInstInfos :: InstEnv -> [InstInfo] -> NF_TcM InstEnv diff --git a/ghc/compiler/typecheck/TcModule.lhs b/ghc/compiler/typecheck/TcModule.lhs index eea3a21..716b933 100644 --- a/ghc/compiler/typecheck/TcModule.lhs +++ b/ghc/compiler/typecheck/TcModule.lhs @@ -108,10 +108,7 @@ typecheckStmt dflags pcs hst ic_type_env unqual this_mod names (stmt, iface_decl tcSetDefaultTys defaultDefaultTys $ -- Typecheck the extra declarations - fixTc (\ ~(unf_env, _, _, _, _) -> - tcImports unf_env pcs hst get_fixity this_mod iface_decls - ) `thenTc` \ (env, new_pcs, local_inst_info, deriv_binds, local_rules) -> - ASSERT( null local_inst_info && nullBinds deriv_binds && null local_rules ) + tcExtraDecls pcs hst get_fixity this_mod iface_decls `thenTc` \ (new_pcs, env) -> tcSetEnv env $ tcExtendGlobalTypeEnv ic_type_env $ @@ -249,10 +246,7 @@ typecheckExpr dflags pcs hst ic_type_env unqual this_mod (expr, decls) tcSetDefaultTys defaultDefaultTys $ -- Typecheck the extra declarations - fixTc (\ ~(unf_env, _, _, _, _) -> - tcImports unf_env pcs hst get_fixity this_mod decls - ) `thenTc` \ (env, new_pcs, local_inst_info, deriv_binds, local_rules) -> - ASSERT( null local_inst_info && nullBinds deriv_binds && null local_rules ) + tcExtraDecls pcs hst get_fixity this_mod decls `thenTc` \ (new_pcs, env) -> -- Now typecheck the expression tcSetEnv env $ @@ -306,13 +300,20 @@ typecheckExtraDecls typecheckExtraDecls dflags pcs hst unqual this_mod decls = typecheck dflags pcs hst unqual $ - fixTc (\ ~(unf_env, _, _, _, _) -> - tcImports unf_env pcs hst get_fixity this_mod decls - ) `thenTc` \ (env, new_pcs, local_inst_info, deriv_binds, local_rules) -> - ASSERT( null local_inst_info && nullBinds deriv_binds && null local_rules ) + tcExtraDecls pcs hst get_fixity this_mod decls + `thenTc` \ (new_pcs, env) -> returnTc new_pcs where get_fixity n = pprPanic "typecheckExpr" (ppr n) + +tcExtraDecls pcs hst get_fixity this_mod decls = + fixTc (\ ~(unf_env, _, _, _, _, _) -> + tcImports unf_env pcs hst get_fixity this_mod decls + ) `thenTc` \ (env, new_pcs, local_inst_info, local_inst_dfuns, + deriv_binds, local_rules) -> + ASSERT( null local_inst_info && nullBinds deriv_binds && null local_rules + && null local_inst_dfuns ) + returnTc (new_pcs, env) \end{code} %************************************************************************ @@ -373,7 +374,7 @@ tcModule pcs hst get_fixity this_mod decls -- Type-check the type and class decls, and all imported decls tcImports unf_env pcs hst get_fixity this_mod decls - `thenTc` \ (env, new_pcs, local_insts, deriv_binds, local_rules) -> + `thenTc` \ (env, new_pcs, local_inst_info, local_inst_dfuns, deriv_binds, local_rules) -> tcSetEnv env $ @@ -397,7 +398,7 @@ tcModule pcs hst get_fixity this_mod decls tcSetEnv env $ tcClassDecls2 this_mod tycl_decls `thenNF_Tc` \ (lie_clasdecls, cls_dm_binds, dm_ids) -> tcExtendGlobalValEnv dm_ids $ - tcInstDecls2 local_insts `thenNF_Tc` \ (lie_instdecls, inst_binds) -> + tcInstDecls2 local_inst_info `thenNF_Tc` \ (lie_instdecls, inst_binds) -> tcForeignExports decls `thenTc` \ (lie_fodecls, foe_binds, foe_decls) -> tcSourceRules source_rules `thenNF_Tc` \ (lie_rules, more_local_rules) -> @@ -459,7 +460,7 @@ tcModule pcs hst get_fixity this_mod decls returnTc (final_env, new_pcs, TcResults { tc_env = local_type_env, - tc_insts = map iDFunId local_insts, + tc_insts = local_inst_dfuns, tc_binds = all_binds', tc_fords = foi_decls ++ foe_decls', tc_rules = all_local_rules @@ -504,16 +505,16 @@ typecheckIface dflags pcs hst mod_iface decls get_fixity nm = lookupNameEnv fixity_env nm tcIfaceImports pcs hst get_fixity this_mod decls - = fixTc (\ ~(unf_env, _, _, _, _) -> + = fixTc (\ ~(unf_env, _, _, _, _, _) -> tcImports unf_env pcs hst get_fixity this_mod decls - ) `thenTc` \ (env, new_pcs, local_inst_info, + ) `thenTc` \ (env, new_pcs, local_inst_info, local_inst_dfuns, deriv_binds, local_rules) -> - ASSERT(nullBinds deriv_binds) + ASSERT(nullBinds deriv_binds && null local_inst_info) let local_things = filter (isLocalThing this_mod) (typeEnvElts (getTcGEnv env)) mod_details = ModDetails { md_types = mkTypeEnv local_things, - md_insts = map iDFunId local_inst_info, + md_insts = local_inst_dfuns, md_rules = [(id,rule) | IfaceRuleOut id rule <- local_rules], md_binds = [] } -- All the rules from an interface are of the IfaceRuleOut form @@ -526,7 +527,7 @@ tcImports :: RecTcEnv -> (Name -> Maybe Fixity) -> Module -> [RenamedHsDecl] - -> TcM (TcEnv, PersistentCompilerState, [InstInfo], + -> TcM (TcEnv, PersistentCompilerState, [InstInfo], [DFunId], RenamedHsBinds, [TypecheckedRuleDecl]) -- tcImports is a slight mis-nomer. @@ -567,9 +568,8 @@ tcImports unf_env pcs hst get_fixity this_mod decls -- Note that imported dictionary functions are already -- in scope from the preceding tcInterfaceSigs traceTc (text "Tc3") `thenNF_Tc_` - tcInstDecls1 (pcs_insts pcs) (pcs_PRS pcs) - hst unf_env get_fixity this_mod - decls `thenTc` \ (new_pcs_insts, inst_env, local_insts, deriv_binds) -> + tcInstDecls1 (pcs_insts pcs) (pcs_PRS pcs) hst unf_env get_fixity this_mod decls + `thenTc` \ (new_pcs_insts, inst_env, local_inst_info, local_inst_dfuns, deriv_binds) -> tcSetInstEnv inst_env $ tcIfaceRules unf_env (pcs_rules pcs) this_mod iface_rules `thenNF_Tc` \ (new_pcs_rules, local_rules) -> @@ -596,7 +596,7 @@ tcImports unf_env pcs hst get_fixity this_mod decls pcs_rules = new_pcs_rules } in - returnTc (unf_env, new_pcs, local_insts, deriv_binds, local_rules) + returnTc (unf_env, new_pcs, local_inst_info, local_inst_dfuns, deriv_binds, local_rules) where tycl_decls = [d | TyClD d <- decls] iface_rules = [d | RuleD d <- decls, isIfaceRuleDecl d] -- 1.7.10.4