- decls_and_insts todo def_env occ_env to_return us
- = 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
- where
- (us1,us2) = splitUniqSupply us
-
- 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 -> -- OK, see what the cache has for us...
-
- cachedDeclByType iface_cache n >>= \ maybe_ans ->
- case maybe_ans of
- Failed err -> -- add the error, but keep going:
- -- pprTrace "do_decls:cache error:" (ppr PprDebug n) $
- do_decls ns down (add_err err to_return)
-
- Succeeded 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
- | isRnTyConOrClass n
- = lookupTcRnEnv def_env (origName n)
- | otherwise
- = lookupRnEnv def_env (origName n)
-
-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) ->
- ASSERT(isEmptyBag def_dups)
+ doc_str = ppSep [ppPStr SLIT("Need decl for"), ppr PprDebug name]
+ (mod,_) = modAndOcc name
+\end{code}
+
+@getWiredInDecl@ maps a wired-in @Name@ to what it makes available.
+It behaves exactly as if the wired in decl were actually in an interface file.
+Specifically,
+
+ * if the wired-in name is a data type constructor or a data constructor,
+ it brings in the type constructor and all the data constructors; and
+ marks as "occurrences" any free vars of the data con.
+
+ * similarly for synonum type constructor
+
+ * if the wired-in name is another wired-in Id, it marks as "occurrences"
+ the free vars of the Id's type.
+
+ * it loads the interface file for the wired-in thing for the
+ sole purpose of making sure that its instance declarations are available
+
+All this is necessary so that we know all types that are "in play", so
+that we know just what instances to bring into scope.
+
+\begin{code}
+getWiredInDecl name
+ = get_wired `thenRn` \ avail ->
+ recordSlurp Nothing avail `thenRn_`
+
+ -- Force in the home module in case it has instance decls for
+ -- the thing we are interested in.
+ --
+ -- Mini hack 1: no point for non-tycons/class; and if we
+ -- do this we find PrelNum trying to import PackedString,
+ -- because PrelBase's .hi file mentions PackedString.unpackString
+ -- But PackedString.hi isn't built by that point!
+ --
+ -- Mini hack 2; GHC is guaranteed not to have
+ -- instance decls, so it's a waste of time to read it
+ --
+ -- NB: We *must* look at the availName of the slurped avail,
+ -- not the name passed to getWiredInDecl! Why? Because if a data constructor
+ -- or class op is passed to getWiredInDecl we'll pull in the whole data/class
+ -- decl, and recordSlurp will record that fact. But since the data constructor
+ -- isn't a tycon/class we won't force in the home module. And even if the
+ -- type constructor/class comes along later, loadDecl will say that it's already
+ -- been slurped, so getWiredInDecl won't even be called. Pretty obscure bug, this was.