2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[RnNames]{Extracting imported and top-level names in scope}
7 #include "HsVersions.h"
15 import CmdLineOpts ( opt_SourceUnchanged, opt_NoImplicitPrelude )
16 import HsSyn ( HsModule(..), HsDecl(..), FixityDecl(..), Fixity, Fake, InPat, IE(..), HsTyVar,
17 TyDecl, ClassDecl, InstDecl, DefaultDecl, ImportDecl(..), HsBinds, IfaceSig
19 import HsBinds ( collectTopBinders )
20 import HsImpExp ( ieName )
21 import RdrHsSyn ( RdrNameHsDecl(..), RdrName(..), RdrNameIE(..), SYN_IE(RdrNameImportDecl),
22 SYN_IE(RdrNameHsModule), SYN_IE(RdrNameFixityDecl),
25 import RnHsSyn ( RenamedHsModule(..), RenamedFixityDecl(..) )
26 import RnIfaces ( getInterfaceExports, getDeclBinders, checkUpToDate, recordSlurp )
31 import UniqFM ( UniqFM, emptyUFM, addListToUFM_C, lookupUFM )
32 import Bag ( Bag, bagToList )
33 import Maybes ( maybeToBool, expectJust )
36 import PprStyle ( PprStyle(..) )
37 import Util ( panic, pprTrace, assertPanic )
42 %************************************************************************
44 \subsection{Get global names}
46 %************************************************************************
49 getGlobalNames :: RdrNameHsModule
50 -> RnMG (Maybe (ExportEnv, RnEnv, [AvailInfo]))
51 -- Nothing <=> no need to recompile
53 getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
54 = fixRn (\ ~(rec_exp_fn, _) ->
56 -- PROCESS LOCAL DECLS
57 -- Do these *first* so that the correct provenance gets
58 -- into the global name cache.
59 importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails) ->
61 -- PROCESS IMPORT DECLS
62 mapAndUnzipRn importsFromImportDecl all_imports
63 `thenRn` \ (imp_rn_envs, imp_avails_s) ->
65 -- CHECK FOR EARLY EXIT
66 checkEarlyExit this_mod `thenRn` \ early_exit ->
68 returnRn (junk_exp_fn, Nothing)
72 -- We put the local env first, so that a local provenance
73 -- "wins", even if a module imports itself.
74 foldlRn plusRnEnv emptyRnEnv imp_rn_envs `thenRn` \ imp_rn_env ->
75 plusRnEnv local_rn_env imp_rn_env `thenRn` \ rn_env ->
77 all_avails :: ModuleAvails
78 all_avails = foldr plusModuleAvails local_mod_avails imp_avails_s
79 local_avails = expectJust "getGlobalNames" (lookupModuleAvails local_mod_avails this_mod)
82 -- PROCESS EXPORT LISTS
83 exportsFromAvail this_mod exports all_avails rn_env
84 `thenRn` \ (export_fn, export_env) ->
86 -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
87 mapRn (recordSlurp Nothing) local_avails `thenRn_`
89 returnRn (export_fn, Just (export_env, rn_env, local_avails))
90 ) `thenRn` \ (_, result) ->
93 junk_exp_fn = error "RnNames:export_fn"
95 all_imports = prel_imports ++ imports
97 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
98 -- because the former doesn't even look at Prelude.hi for instance declarations,
99 -- whereas the latter does.
100 prel_imports | this_mod == pRELUDE ||
101 explicit_prelude_import ||
102 opt_NoImplicitPrelude
105 | otherwise = [ImportDecl pRELUDE
106 False {- Not qualified -}
107 Nothing {- No "as" -}
108 Nothing {- No import list -}
111 explicit_prelude_import
112 = not (null [ () | (ImportDecl mod qual _ _ _) <- imports, mod == pRELUDE ])
117 = checkErrsRn `thenRn` \ no_errs_so_far ->
118 if not no_errs_so_far then
119 -- Found errors already, so exit now
122 if not opt_SourceUnchanged then
123 -- Source code changed and no errors yet... carry on
126 -- Unchanged source, and no errors yet; see if usage info
127 -- up to date, and exit if so
128 checkUpToDate mod `thenRn` \ up_to_date ->
134 importsFromImportDecl :: RdrNameImportDecl
135 -> RnMG (RnEnv, ModuleAvails)
137 importsFromImportDecl (ImportDecl mod qual_only as_mod import_spec loc)
139 getInterfaceExports mod `thenRn` \ (avails, fixities) ->
140 filterImports mod import_spec avails `thenRn` \ filtered_avails ->
142 filtered_avails' = map set_avail_prov filtered_avails
143 fixities' = [ (occ,(fixity,provenance)) | (occ,fixity) <- fixities ]
146 True -- Want qualified names
147 (not qual_only) -- Maybe want unqualified names
149 (ExportEnv filtered_avails' fixities')
151 set_avail_prov NotAvailable = NotAvailable
152 set_avail_prov (Avail n) = Avail (set_name_prov n)
153 set_avail_prov (AvailTC n ns) = AvailTC (set_name_prov n) (map set_name_prov ns)
154 set_name_prov name = setNameProvenance name provenance
155 provenance = Imported mod loc
160 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
161 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
162 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
164 False -- Don't want qualified names
165 True -- Want unqualified names
166 Nothing -- No "as M" part
167 (ExportEnv avails fixities)
169 newLocalName rdr_name loc
170 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
172 getLocalDeclBinders avails (ValD binds)
173 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
174 returnRn (val_avails ++ avails)
176 getLocalDeclBinders avails decl
177 = getDeclBinders newLocalName decl `thenRn` \ avail ->
179 NotAvailable -> returnRn avails -- Instance decls and suchlike
180 other -> returnRn (avail : avails)
182 do_one (rdr_name, loc)
183 = newLocalName rdr_name loc `thenRn` \ name ->
184 returnRn (Avail name)
187 %************************************************************************
189 \subsection{Filtering imports}
191 %************************************************************************
193 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
194 available, and filters it through the import spec (if any).
197 filterImports :: Module
198 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
199 -> [AvailInfo] -- What's available
200 -> RnMG [AvailInfo] -- What's actually imported
201 -- Complains if import spec mentions things the
202 -- module doesn't export
204 filterImports mod Nothing imports
207 filterImports mod (Just (want_hiding, import_items)) avails
208 = foldlRn (filter_item want_hiding) initial_avails import_items
210 initial_avails | want_hiding = avails
213 import_fm :: FiniteMap OccName AvailInfo
214 import_fm = listToFM [ (nameOccName name, avail)
216 name <- availEntityNames avail]
218 filter_item want_hiding avails_so_far item@(IEModuleContents _)
219 = addErrRn (badImportItemErr mod item) `thenRn_`
220 returnRn avails_so_far
222 filter_item want_hiding avails_so_far item
223 | not (maybeToBool maybe_in_import_avails) ||
224 (case filtered_avail of { NotAvailable -> True; other -> False })
225 = addErrRn (badImportItemErr mod item) `thenRn_`
226 returnRn avails_so_far
228 | want_hiding = returnRn (foldr hide_it [] avails_so_far)
229 | otherwise = returnRn (filtered_avail : avails_so_far) -- Explicit import list
232 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
233 Just avail = maybe_in_import_avails
234 filtered_avail = filterAvail item avail
235 hide_it avail avails = case hideAvail item avail of
236 NotAvailable -> avails
237 avail' -> avail' : avails
242 %************************************************************************
244 \subsection{Qualifiying imports}
246 %************************************************************************
248 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
249 of an import decl, and deals with producing an @RnEnv@ with the
250 right qaulified names. It also turns the @Names@ in the @ExportEnv@ into
251 fully fledged @Names@.
254 qualifyImports :: Module -- Imported module
255 -> Bool -- True <=> want qualified import
256 -> Bool -- True <=> want unqualified import
257 -> Maybe Module -- Optional "as M" part
258 -> ExportEnv -- What's imported
259 -> RnMG (RnEnv, ModuleAvails)
261 qualifyImports this_mod qual_imp unqual_imp as_mod (ExportEnv avails fixities)
262 = -- Make the qualified-name environments, checking of course for clashes
263 foldlRn add_name emptyNameEnv avails `thenRn` \ name_env ->
264 foldlRn (add_fixity name_env) emptyFixityEnv fixities `thenRn` \ fixity_env ->
265 returnRn (RnEnv name_env fixity_env, mod_avail_env)
267 show_it (rdr, (fix,prov)) = ppSep [ppLbrack, ppr PprDebug rdr, ppr PprDebug fix, pprProvenance PprDebug prov, ppRbrack]
269 qual_mod = case as_mod of
271 Just another_name -> another_name
273 mod_avail_env = unitFM qual_mod avails
275 add_name name_env avail = foldlRn add_one name_env (availNames avail)
277 add_one :: NameEnv -> Name -> RnMG NameEnv
278 add_one env name = add_to_env addOneToNameEnvRn env occ_name name
280 occ_name = nameOccName name
282 add_to_env add_fn env occ thing | qual_imp && unqual_imp = both
283 | qual_imp = qual_only
284 | unqual_imp = unqual_only
286 unqual_only = add_fn env (Unqual occ) thing
287 qual_only = add_fn env (Qual qual_mod occ) thing
288 both = unqual_only `thenRn` \ env' ->
289 add_fn env' (Qual qual_mod occ) thing
291 add_fixity name_env fixity_env (occ_name, (fixity, provenance))
292 | maybeToBool (lookupFM name_env rdr_name) -- It's imported
293 = add_to_env addOneToFixityEnvRn fixity_env occ_name (fixity,provenance)
294 | otherwise -- It ain't imported
295 = returnRn fixity_env
297 -- rdr_name is a name by which the thing is guaranteed to be known,
298 -- *if it is imported at all*
299 rdr_name | qual_imp = Qual qual_mod occ_name
300 | otherwise = Unqual occ_name
303 unQualify adds an Unqual binding for every existing Qual binding.
306 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
307 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ, elt) <- fmToList fm]
310 %************************************************************************
312 \subsection{Local declarations}
314 %************************************************************************
318 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, Provenance))
320 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
321 = returnRn (rdrNameOcc rdr_name, (fixity, LocalDef (panic "export-flag") loc))
325 %************************************************************************
327 \subsection{Export list processing
329 %************************************************************************
331 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
332 When exporting we need to combine the availabilities for a particular
333 exported thing, and we also need to check for name clashes -- that
334 is: two exported things must have different @OccNames@.
337 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo)
338 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
339 -- for error reporting, as well as to its AvailInfo
341 emptyAvailEnv = emptyFM
343 unitAvailEnv :: RdrNameIE -> AvailInfo -> AvailEnv
344 unitAvailEnv ie NotAvailable = emptyFM
345 unitAvailEnv ie (AvailTC _ []) = emptyFM
346 unitAvailEnv ie avail = unitFM (nameOccName (availName avail)) (ie,avail)
349 = mapRn (addErrRn.availClashErr) (conflictsFM bad_avail a1 a2) `thenRn_`
350 returnRn (plusFM_C plus_avail a1 a2)
352 listToAvailEnv :: RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
353 listToAvailEnv ie items
354 = foldlRn plusAvailEnv emptyAvailEnv (map (unitAvailEnv ie) items)
356 bad_avail (ie1,avail1) (ie2,avail2) = availName avail1 /= availName avail2 -- Same OccName, different Name
357 plus_avail (ie1,a1) (ie2,a2) = (ie1, a1 `plusAvail` a2)
360 Processing the export list.
362 You might think that we should record things that appear in the export list as
363 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
364 that they are in scope, but there is no need to slurp in their actual declaration
365 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
366 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
367 includes ConcBase.StateAndSynchVar#, and so on...
370 exportsFromAvail :: Module
371 -> Maybe [RdrNameIE] -- Export spec
374 -> RnMG (Name -> ExportFlag, ExportEnv)
375 -- Complains if two distinct exports have same OccName
376 -- Complains about exports items not in scope
377 exportsFromAvail this_mod Nothing all_avails rn_env
378 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) all_avails rn_env
380 exportsFromAvail this_mod (Just export_items) all_avails (RnEnv name_env fixity_env)
381 = mapRn exports_from_item export_items `thenRn` \ avail_envs ->
382 foldlRn plusAvailEnv emptyAvailEnv avail_envs `thenRn` \ export_avail_env ->
384 export_avails = map snd (eltsFM export_avail_env)
385 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
386 export_fn = mk_export_fn export_avails
388 returnRn (export_fn, ExportEnv export_avails export_fixities)
391 full_avail_env :: UniqFM AvailInfo
392 full_avail_env = addListToUFM_C plusAvail emptyUFM
393 [(name, avail) | avail <- concat (eltsFM all_avails),
394 name <- availEntityNames avail
397 -- NB: full_avail_env will contain bindings for class ops but not constructors
398 -- (see defn of availEntityNames)
400 exports_from_item :: RdrNameIE -> RnMG AvailEnv
401 exports_from_item ie@(IEModuleContents mod)
402 = case lookupFM all_avails mod of
403 Nothing -> failWithRn emptyAvailEnv (modExportErr mod)
404 Just avails -> listToAvailEnv ie avails
407 | not (maybeToBool maybe_in_scope)
408 = failWithRn emptyAvailEnv (unknownNameErr (ieName ie))
411 -- I can't see why this should ever happen; if the thing is in scope
412 -- at all it ought to have some availability
413 | not (maybeToBool maybe_avail)
414 = pprTrace "exportsFromAvail: curious Nothing:" (ppr PprDebug name)
415 returnRn emptyAvailEnv
419 = failWithRn emptyAvailEnv (exportItemErr ie export_avail)
421 | otherwise -- Phew! It's OK!
422 = returnRn (unitAvailEnv ie export_avail)
424 maybe_in_scope = lookupNameEnv name_env (ieName ie)
425 Just name = maybe_in_scope
426 maybe_avail = lookupUFM full_avail_env name
427 Just avail = maybe_avail
428 export_avail = filterAvail ie avail
429 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
431 -- We export a fixity iff we export a thing with the same (qualified) RdrName
432 mk_exported_fixities :: NameSet -> [(OccName, (Fixity, Provenance))]
433 mk_exported_fixities exports
434 = fmToList (foldr (perhaps_add_fixity exports)
436 (fmToList fixity_env))
438 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, Provenance))
439 -> FiniteMap OccName (Fixity,Provenance)
440 -> FiniteMap OccName (Fixity,Provenance)
441 perhaps_add_fixity exports (rdr_name, (fixity, prov)) fix_env
443 do_nothing = fix_env -- The default is to pass on the env unchanged
445 -- Step 1: check whether the rdr_name is in scope; if so find its Name
446 case lookupFM name_env rdr_name of {
447 Nothing -> do_nothing;
450 -- Step 2: check whether the fixity thing is exported
451 if not (fixity_name `elemNameSet` exports) then
455 -- Step 3: check whether we already have a fixity for the
456 -- Name's OccName in the fix_env we are building up. This can easily
457 -- happen. the original fixity_env might contain bindings for
458 -- M.a and N.a, if a was imported via M and N.
459 -- If this does happen, we expect the fixity to be the same either way.
461 occ_name = rdrNameOcc rdr_name
463 case lookupFM fix_env occ_name of {
464 Just (fixity1, prov1) -> -- Got it already
465 ASSERT( fixity == fixity1 )
469 -- Step 3: add it to the outgoing fix_env
470 addToFM fix_env occ_name (fixity,prov)
473 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
475 = \name -> if name `elemNameSet` exported_names
479 exported_names :: NameSet
480 exported_names = availsToNameSet avails
484 %************************************************************************
488 %************************************************************************
491 badImportItemErr mod ie sty
492 = ppSep [ppPStr SLIT("Module"), pprModule sty mod, ppPStr SLIT("does not export"), ppr sty ie]
495 = ppCat [ ppPStr SLIT("Unknown module in export list: module"), ppPStr mod]
497 exportItemErr export_item NotAvailable sty
498 = ppSep [ ppPStr SLIT("Export item not in scope:"), ppr sty export_item ]
500 exportItemErr export_item avail sty
501 = ppHang (ppPStr SLIT("Export item not fully in scope:"))
502 4 (ppAboves [ppCat [ppPStr SLIT("Wanted: "), ppr sty export_item],
503 ppCat [ppPStr SLIT("Available: "), ppr sty (ieOcc export_item), pprAvail sty avail]])
505 availClashErr (occ_name, ((ie1,avail1), (ie2,avail2))) sty
506 = ppHang (ppCat [ppPStr SLIT("Conflicting exports for local name: "), ppr sty occ_name])
507 4 (ppAboves [ppr sty ie1, ppr sty ie2])