-rnIfaces :: IfaceCache -- iface cache (mutvar)
- -> [Module] -- directly imported modules
- -> UniqSupply
- -> RnEnv -- defined (in the source) name env
- -> RnEnv -- mentioned (in the source) name env
- -> RenamedHsModule -- module to extend with iface decls
- -> [RnName] -- imported names required (really the
- -- same info as in mentioned name env)
- -- Also, all the things we may look up
- -- later by key (Unique).
- -> IO (RenamedHsModule, -- extended module
- RnEnv, -- final env (for renaming derivings)
- ImplicitEnv, -- implicit names used (for usage info)
- (UsagesMap,VersionsMap,[Module]), -- usage info
- (Bag Error, Bag Warning))
-
-rnIfaces iface_cache imp_mods us
- def_env@((dqual, dunqual, dtc_qual, dtc_unqual), dstack)
- occ_env@((qual, unqual, tc_qual, tc_unqual), stack)
- rn_module@(HsModule modname iface_version exports imports fixities
- typedecls typesigs classdecls instdecls instsigs
- defdecls binds sigs src_loc)
- todo
- = {-
- pprTrace "rnIfaces:going after:" (ppCat (map (ppr PprDebug) todo)) $
- pprTrace "rnIfaces:qual:" (ppCat [ppBesides[ppPStr m,ppChar '.',ppPStr n] | (n,m) <- keysFM qual]) $
- pprTrace "rnIfaces:unqual:" (ppCat (map ppPStr (keysFM unqual))) $
- pprTrace "rnIfaces:tc_qual:" (ppCat [ppBesides[ppPStr m,ppChar '.',ppPStr n] | (n,m) <- keysFM tc_qual]) $
- pprTrace "rnIfaces:tc_unqual:" (ppCat (map ppPStr (keysFM tc_unqual))) $
-
- pprTrace "rnIfaces:dqual:" (ppCat [ppBesides[ppPStr m,ppChar '.',ppPStr n] | (n,m) <- keysFM dqual]) $
- pprTrace "rnIfaces:dunqual:" (ppCat (map ppPStr (keysFM dunqual))) $
- pprTrace "rnIfaces:dtc_qual:" (ppCat [ppBesides[ppPStr m,ppChar '.',ppPStr n] | (n,m) <- keysFM dtc_qual]) $
- pprTrace "rnIfaces:dtc_unqual:"(ppCat (map ppPStr (keysFM dtc_unqual))) $
- -}
-
- -- do transitive closure to bring in all needed names/defns and insts:
-
- decls_and_insts todo def_env occ_env empty_return us
- >>= \ (((if_typedecls, if_classdecls, if_instdecls, if_sigs),
- if_implicits,
- if_errs_warns),
- if_final_env) ->
-
- -- finalize what we want to say we learned about the
- -- things we used
- finalIfaceInfo iface_cache modname if_final_env if_instdecls {-all_imports_used imp_mods-} >>=
- \ usage_stuff@(usage_info, version_info, instance_mods) ->
-
- return (HsModule modname iface_version exports imports fixities
- (typedecls ++ if_typedecls)
- typesigs
- (classdecls ++ if_classdecls)
- (instdecls ++ if_instdecls)
- instsigs defdecls binds
- (sigs ++ if_sigs)
- src_loc,
- if_final_env,
- if_implicits,
- usage_stuff,
- if_errs_warns)
- where
- decls_and_insts todo def_env occ_env to_return us
- = let
- (us1,us2) = splitUniqSupply us
- in
- do_decls todo -- initial batch of names to process
- (def_env, occ_env, us1) -- init stuff down
- to_return -- acc results
- >>= \ (decls_return,
- decls_def_env,
- decls_occ_env) ->
-
- cacheInstModules iface_cache imp_mods >>= \ errs ->
-
- do_insts decls_def_env decls_occ_env emptyRnEnv emptyFM
- (add_errs errs decls_return) us2
-
- --------
- do_insts def_env occ_env prev_env done_insts to_return us
- | size_tc_env occ_env == size_tc_env prev_env
- = return (to_return, occ_env)
-
- | otherwise
- = rnIfaceInstStuff iface_cache modname us1 occ_env done_insts to_return
- >>= \ (insts_return,
- new_insts,
- insts_occ_env,
- new_unknowns) ->
-
- do_decls new_unknowns -- new batch of names to process
- (def_env, insts_occ_env, us2) -- init stuff down
- insts_return -- acc results
- >>= \ (decls_return,
- decls_def_env,
- decls_occ_env) ->
-
- do_insts decls_def_env decls_occ_env occ_env new_insts decls_return us3
- where
- (us1,us') = splitUniqSupply us
- (us2,us3) = splitUniqSupply us'
-
- size_tc_env ((_, _, qual, unqual), _)
- = sizeFM qual + sizeFM unqual
-
-
- do_decls :: [RnName] -- Names we're looking for; we keep adding/deleting
- -- from this list; we're done when empty (nothing
- -- more needs to be looked for)
- -> Go_Down -- see defn below
- -> To_Return -- accumulated result
- -> IO (To_Return,
- RnEnv, -- extended decl env
- RnEnv) -- extended occ env
-
- do_decls to_find@[] down to_return
- = return (to_return, defenv down, occenv down)
-
- do_decls to_find@(n:ns) down to_return
- = case (lookup_defd down n) of
- Just _ -> -- previous processing must've found the stuff for this name;
- -- continue with the rest:
- -- pprTrace "do_decls:done:" (ppr PprDebug n) $
- do_decls ns down to_return
-
- Nothing
- | moduleOf (origName "do_decls" n) == modname ->
- -- avoid looking in interface for the module being compiled
- --pprTrace "do_decls:this module error:" (ppr PprDebug n) $
- do_decls ns down (add_warn (thisModImplicitWarn modname n) to_return)
-
- | otherwise ->
- -- OK, see what the cache has for us...
-
- cachedDeclByType iface_cache n >>= \ maybe_ans ->
- case maybe_ans of
- CachingAvoided _ ->
- pprTrace "do_decls:caching avoided:" (ppr PprDebug n) $
- do_decls ns down to_return
-
- CachingFail err -> -- add the error, but keep going:
- --pprTrace "do_decls:cache error:" (ppr PprDebug n) $
- do_decls ns down (add_err err to_return)
-
- CachingHit iface_decl -> -- something needing renaming!
- let
- (us1, us2) = splitUniqSupply (uniqsupply down)
- in
- case (initRn False{-iface-} modname (occenv down) us1 (
- setExtraRn emptyUFM{-no fixities-} $
- rnIfaceDecl iface_decl)) of {
- ((if_decl, if_defd, if_implicits), if_errs, if_warns) ->
- let
- new_unknowns = eltsFM (fst if_implicits) ++ eltsFM (snd if_implicits)
- in
- {-
- pprTrace "do_decls:renamed:" (ppAboves [ppr PprDebug n
- , ppCat [ppStr "new unknowns:", interpp'SP PprDebug new_unknowns]
- , ppCat [ppStr "defd vals:", interpp'SP PprDebug [n | (_,n) <- fst if_defd] ]
- , ppCat [ppStr "defd tcs:", interpp'SP PprDebug [n | (_,n) <- snd if_defd] ]
- ]) $
- -}
- do_decls (new_unknowns ++ ns)
- (add_occs if_defd if_implicits $
- new_uniqsupply us2 down)
- (add_decl if_decl $
- add_implicits if_implicits $
- add_errs if_errs $
- add_warns if_warns to_return)
- }
-
------------
-type Go_Down = (RnEnv, -- stuff we already have defns for;
- -- to check quickly if we've already
- -- found something for the name under consideration,
- -- due to previous processing.
- -- It starts off just w/ the defns for
- -- the things in this module.
- RnEnv, -- occurrence env; this gets added to as
- -- we process new iface decls. It includes
- -- entries for *all* occurrences, including those
- -- for which we have definitions.
- UniqSupply -- the obvious
- )
-
-lookup_defd (def_env, _, _) n
- = (if isRnTyConOrClass n then lookupTcRnEnv else lookupRnEnv) def_env
- (case (origName "lookup_defd" n) of { OrigName m s -> Qual m s })
- -- this is hack because we are reusing the RnEnv technology
-
-defenv (def_env, _, _) = def_env
-occenv (_, occ_env, _) = occ_env
-uniqsupply (_, _, us) = us
-
-new_uniqsupply us (def_env, occ_env, _) = (def_env, occ_env, us)
-
-add_occs (val_defds, tc_defds) (val_imps, tc_imps) (def_env, occ_env, us)
- = case (extendGlobalRnEnv def_env val_defds tc_defds) of { (new_def_env, def_dups) ->
- (if isEmptyBag def_dups then \x->x else pprTrace "add_occs:" (ppCat [ppr PprDebug n | (n,_,_) <- bagToList def_dups])) $
--- ASSERT(isEmptyBag def_dups)
- let
- de_orig imps = [ (Qual m n, v) | (OrigName m n, v) <- fmToList imps ]
- -- again, this hackery because we are reusing the RnEnv technology