Commit 483817dd authored by simonmar's avatar simonmar
Browse files

[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.
parent c1980f1d
......@@ -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}
%************************************************************************
......
......@@ -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
......
......@@ -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]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment