- -> RnMG (Maybe (ExportEnv, RnEnv, [AvailInfo]))
- -- Nothing <=> no need to recompile
-
-getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
- = fixRn (\ ~(rec_exp_fn, _) ->
-
- -- PROCESS LOCAL DECLS
- -- Do these *first* so that the correct provenance gets
- -- into the global name cache.
- importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails) ->
-
- -- PROCESS IMPORT DECLS
- mapAndUnzipRn importsFromImportDecl all_imports
- `thenRn` \ (imp_rn_envs, imp_avails_s) ->
-
- -- CHECK FOR EARLY EXIT
- checkEarlyExit this_mod `thenRn` \ early_exit ->
- if early_exit then
- returnRn (junk_exp_fn, Nothing)
+ -> RnMG (Maybe (ExportEnv,
+ RnEnv,
+ NameEnv AvailInfo -- Maps a name to its parent AvailInfo
+ -- Just for in-scope things only
+ ))
+ -- Nothing => no need to recompile
+
+getGlobalNames (HsModule this_mod _ exports imports decls mod_loc)
+ = -- These two fix-loops are to get the right
+ -- provenance information into a Name
+ fixRn (\ ~(rec_exported_avails, _) ->
+
+ fixRn (\ ~(rec_rn_env, _) ->
+ let
+ rec_unqual_fn :: Name -> Bool -- Is this chap in scope unqualified?
+ rec_unqual_fn = unQualInScope rec_rn_env
+
+ rec_exp_fn :: Name -> ExportFlag
+ rec_exp_fn = mk_export_fn (availsToNameSet rec_exported_avails)
+ in
+ setOmitQualFn rec_unqual_fn $
+ setModuleRn this_mod $
+
+ -- PROCESS LOCAL DECLS
+ -- Do these *first* so that the correct provenance gets
+ -- into the global name cache.
+ importsFromLocalDecls this_mod rec_exp_fn decls `thenRn` \ (local_gbl_env, local_mod_avails) ->
+
+ -- PROCESS IMPORT DECLS
+ mapAndUnzipRn importsFromImportDecl all_imports `thenRn` \ (imp_gbl_envs, imp_avails_s) ->
+
+ -- COMBINE RESULTS
+ -- We put the local env second, so that a local provenance
+ -- "wins", even if a module imports itself.
+ let
+ gbl_env :: GlobalRdrEnv
+ imp_gbl_env = foldr plusGlobalRdrEnv emptyRdrEnv imp_gbl_envs
+ gbl_env = imp_gbl_env `plusGlobalRdrEnv` local_gbl_env
+
+ all_avails :: ExportAvails
+ all_avails = foldr plusExportAvails local_mod_avails imp_avails_s
+ in
+ returnRn (gbl_env, all_avails)
+ ) `thenRn` \ (gbl_env, all_avails) ->
+
+ -- TRY FOR EARLY EXIT
+ -- We can't go for an early exit before this because we have to check
+ -- for name clashes. Consider:
+ --
+ -- module A where module B where
+ -- import B h = True
+ -- f = h
+ --
+ -- Suppose I've compiled everything up, and then I add a
+ -- new definition to module B, that defines "f".
+ --
+ -- Then I must detect the name clash in A before going for an early
+ -- exit. The early-exit code checks what's actually needed from B
+ -- to compile A, and of course that doesn't include B.f. That's
+ -- why we wait till after the plusRnEnv stuff to do the early-exit.
+ checkEarlyExit this_mod `thenRn` \ up_to_date ->
+ if up_to_date then
+ returnRn (junk_exp_fn, Nothing)