lookupIfaceTop, lookupIfaceExt,
lookupOrig, lookupIfaceTc,
newIfaceName, newIfaceNames,
- extendIfaceIdEnv, extendIfaceTyVarEnv,
+ extendIfaceIdEnv, extendIfaceTyVarEnv, refineIfaceIdEnv,
tcIfaceLclId, tcIfaceTyVar,
+ lookupAvail, ifaceExportNames,
+
-- Name-cache stuff
- allocateGlobalBinder, initNameCache
+ allocateGlobalBinder, initNameCache,
) where
#include "HsVersions.h"
import TcRnMonad
import IfaceType ( IfaceExtName(..), IfaceTyCon(..), ifaceTyConName )
import TysWiredIn ( tupleTyCon, tupleCon )
-import HscTypes ( NameCache(..), HscEnv(..), OrigNameCache )
+import HscTypes ( NameCache(..), HscEnv(..), GenAvailInfo(..),
+ IfaceExport, OrigNameCache )
+import Type ( mkOpenTvSubst, substTy )
import TyCon ( TyCon, tyConName )
+import Unify ( TypeRefinement )
import DataCon ( dataConWorkId, dataConName )
-import Var ( TyVar, Id, varName )
+import Var ( TyVar, Id, varName, setIdType, idType )
import Name ( Name, nameUnique, nameModule,
- nameOccName, nameSrcLoc,
+ nameOccName, nameSrcLoc,
getOccName, nameParent_maybe,
isWiredInName, mkIPName,
mkExternalName, mkInternalName )
-import OccName ( OccName, isTupleOcc_maybe, tcName, dataName,
+import NameSet ( NameSet, emptyNameSet, addListToNameSet )
+import OccName ( OccName, isTupleOcc_maybe, tcName, dataName, mapOccEnv,
lookupOccEnv, unitOccEnv, extendOccEnv, extendOccEnvList )
-import PrelNames ( gHC_PRIM_Name, pREL_TUP_Name )
-import Module ( Module, ModuleName, moduleName, mkPackageModule,
- emptyModuleEnv, lookupModuleEnvByName, extendModuleEnv_C )
+import PrelNames ( gHC_PRIM, pREL_TUP )
+import Module ( Module, emptyModuleEnv,
+ lookupModuleEnv, extendModuleEnv_C )
import UniqSupply ( UniqSupply, splitUniqSupply, uniqFromSupply, uniqsFromSupply )
import FiniteMap ( emptyFM, lookupFM, addToFM )
import BasicTypes ( IPName(..), mapIPName )
newGlobalBinder mod occ mb_parent loc
= do { mod `seq` occ `seq` return () -- See notes with lookupOrig_help
+ -- ; traceIf (text "newGlobalBinder" <+> ppr mod <+> ppr occ <+> ppr loc)
; name_supply <- getNameCache
; let (name_supply', name) = allocateGlobalBinder
name_supply mod occ
-> Module -> OccName -> Maybe Name -> SrcLoc
-> (NameCache, Name)
allocateGlobalBinder name_supply mod occ mb_parent loc
- = case lookupOrigNameCache (nsNames name_supply) (moduleName mod) occ of
+ = case lookupOrigNameCache (nsNames name_supply) mod occ of
-- A hit in the cache! We are at the binding site of the name.
- -- This is the moment when we know the defining Module and SrcLoc
+ -- This is the moment when we know the defining parent and SrcLoc
-- of the Name, so we set these fields in the Name we return.
--
- -- This is essential, to get the right Module in a Name.
- -- Also: then (bogus) multiple bindings of the same Name
- -- get different SrcLocs can can be reported as such.
+ -- Then (bogus) multiple bindings of the same Name
+ -- get different SrcLocs can can be reported as such.
--
-- Possible other reason: it might be in the cache because we
-- encountered an occurrence before the binding site for an
Just parent_name -> parent_name
Nothing -> base_name
-lookupOrig :: ModuleName -> OccName -> TcRnIf a b Name
--- This one starts with a ModuleName, not a Module, because
--- we may be simply looking at an occurrence M.x in an interface file.
--- We may enounter this well before finding the binding site for M.x
---
--- So, even if we get a miss in the original-name cache, we
+ifaceExportNames :: [IfaceExport] -> TcRnIf gbl lcl NameSet
+ifaceExportNames exports
+ = foldlM do_one emptyNameSet exports
+ where
+ do_one acc (mod, exports) = foldlM (do_avail mod) acc exports
+ do_avail mod acc avail = do { ns <- lookupAvail mod avail
+ ; return (addListToNameSet acc ns) }
+
+lookupAvail :: Module -> GenAvailInfo OccName -> TcRnIf a b [Name]
+-- Find all the names arising from an import
+-- Make sure the parent info is correct, even though we may not
+-- yet have read the interface for this module
+lookupAvail mod (Avail n) = do { n' <- lookupOrig mod n;
+ ; return [n'] }
+lookupAvail mod (AvailTC p_occ occs)
+ = do { p_name <- lookupOrig mod p_occ
+ ; let lookup_sub occ | occ == p_occ = return p_name
+ | otherwise = lookup_orig mod occ (Just p_name)
+ ; mappM lookup_sub occs }
+ -- Remember that 'occs' is all the exported things, including
+ -- the parent. It's possible to export just class ops without
+ -- the class, via C( op ). If the class was exported too we'd
+ -- have C( C, op )
+
+ -- The use of lookupOrigSub here (rather than lookupOrig)
+ -- ensures that the subordinate names record their parent;
+ -- and that in turn ensures that the GlobalRdrEnv
+ -- has the correct parent for all the names in its range.
+ -- For imported things, we may only suck in the interface later, if ever.
+ -- Reason for all this:
+ -- Suppose module M exports type A.T, and constructor A.MkT
+ -- Then, we know that A.MkT is a subordinate name of A.T,
+ -- even though we aren't at the binding site of A.T
+ -- And it's important, because we may simply re-export A.T
+ -- without ever sucking in the declaration itself.
+
+
+lookupOrig :: Module -> OccName -> TcRnIf a b Name
+-- Even if we get a miss in the original-name cache, we
-- make a new External Name.
-- We fake up
--- Module to AnotherPackage
-- SrcLoc to noSrcLoc
-- Parent no Nothing
-- They'll be overwritten, in due course, by LoadIface.loadDecl.
+lookupOrig mod occ = lookup_orig mod occ Nothing
-lookupOrig mod_name occ
- = do { -- First ensure that mod_name and occ are evaluated
+lookup_orig :: Module -> OccName -> Maybe Name -> TcRnIf a b Name
+-- Used when we know the parent of the thing we are looking up
+lookup_orig mod occ mb_parent
+ = do { -- First ensure that mod and occ are evaluated
-- If not, chaos can ensue:
-- we read the name-cache
-- then pull on mod (say)
mod `seq` occ `seq` return ()
; name_supply <- getNameCache
- ; case lookupOrigNameCache (nsNames name_supply) mod_name occ of {
+ ; case lookupOrigNameCache (nsNames name_supply) mod occ of {
Just name -> returnM name ;
Nothing -> do
{ let { (us', us1) = splitUniqSupply (nsUniqs name_supply)
; uniq = uniqFromSupply us1
- ; name = mkExternalName uniq tmp_mod occ Nothing noSrcLoc
- ; new_cache = extend_name_cache (nsNames name_supply) tmp_mod occ name
+ ; name = mkExternalName uniq mod occ mb_parent noSrcLoc
+ ; new_cache = extend_name_cache (nsNames name_supply) mod occ name
; new_name_supply = name_supply {nsUniqs = us', nsNames = new_cache}
- ; tmp_mod = mkPackageModule mod_name
- -- Guess at the package-ness for now, becuase we don't know whether
- -- this imported module is from the home package or not.
- -- If we ever need it, we'll open its interface, and update the cache
- -- with a better name (newGlobalBinder)
}
; setNameCache new_name_supply
; return name }
Local helper functions (not exported)
\begin{code}
-lookupOrigNameCache :: OrigNameCache -> ModuleName -> OccName -> Maybe Name
-lookupOrigNameCache nc mod_name occ
- | mod_name == pREL_TUP_Name || mod_name == gHC_PRIM_Name, -- Boxed tuples from one,
- Just tup_info <- isTupleOcc_maybe occ -- unboxed from the other
+lookupOrigNameCache :: OrigNameCache -> Module -> OccName -> Maybe Name
+lookupOrigNameCache nc mod occ
+ | mod == pREL_TUP || mod == gHC_PRIM, -- Boxed tuples from one,
+ Just tup_info <- isTupleOcc_maybe occ -- unboxed from the other
= -- Special case for tuples; there are too many
-- of them to pre-populate the original-name cache
Just (mk_tup_name tup_info)
| ns == dataName = dataConName (tupleCon boxity arity)
| otherwise = varName (dataConWorkId (tupleCon boxity arity))
-lookupOrigNameCache nc mod_name occ -- The normal case
- = case lookupModuleEnvByName nc mod_name of
+lookupOrigNameCache nc mod occ -- The normal case
+ = case lookupModuleEnv nc mod of
Nothing -> Nothing
Just occ_env -> lookupOccEnv occ_env occ
`orElse`
pprPanic "tcIfaceLclId" (ppr occ)) }
+refineIfaceIdEnv :: TypeRefinement -> IfL a -> IfL a
+refineIfaceIdEnv (tv_subst, _) thing_inside
+ = do { env <- getLclEnv
+ ; let { id_env' = mapOccEnv refine_id (if_id_env env)
+ ; refine_id id = setIdType id (substTy subst (idType id))
+ ; subst = mkOpenTvSubst tv_subst }
+ ; setLclEnv (env { if_id_env = id_env' }) thing_inside }
+
extendIfaceIdEnv :: [Id] -> IfL a -> IfL a
extendIfaceIdEnv ids thing_inside
= do { env <- getLclEnv