2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[RnNames]{Extracting imported and top-level names in scope}
11 #include "HsVersions.h"
13 import CmdLineOpts ( opt_NoImplicitPrelude, opt_WarnDuplicateExports,
17 import HsSyn ( HsModule(..), ImportDecl(..), HsDecl(..),
22 import RdrHsSyn ( RdrNameHsDecl(..), RdrName(..), RdrNameIE(..), RdrNameImportDecl,
23 RdrNameHsModule, RdrNameFixityDecl,
26 import RnIfaces ( getInterfaceExports, getDeclBinders, recordSlurp, checkUpToDate )
27 import BasicTypes ( IfaceFlavour(..) )
33 import UniqFM ( UniqFM, addListToUFM_C, lookupUFM )
34 import Bag ( Bag, bagToList )
35 import Maybes ( maybeToBool )
38 import Util ( removeDups )
43 %************************************************************************
45 \subsection{Get global names}
47 %************************************************************************
50 getGlobalNames :: RdrNameHsModule
51 -> RnMG (Maybe (ExportEnv, RnEnv, NameSet, Name -> PrintUnqualified))
52 -- The NameSet is the set of names that are
53 -- either locally defined,
54 -- or explicitly imported
55 -- Nothing => no need to recompile
57 getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
58 = fixRn (\ ~(rec_exp_fn, _) ->
60 -- PROCESS LOCAL DECLS
61 -- Do these *first* so that the correct provenance gets
62 -- into the global name cache.
63 importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails, local_avails) ->
65 -- PROCESS IMPORT DECLS
66 mapAndUnzip3Rn importsFromImportDecl all_imports
67 `thenRn` \ (imp_rn_envs, imp_avails_s, explicit_imports_s) ->
70 -- We put the local env second, so that a local provenance
71 -- "wins", even if a module imports itself.
72 foldlRn plusRnEnv emptyRnEnv imp_rn_envs `thenRn` \ imp_rn_env ->
73 plusRnEnv imp_rn_env local_rn_env `thenRn` \ rn_env ->
76 -- We can't go for an early exit before this because we have to check
77 -- for name clashes. Consider:
79 -- module A where module B where
83 -- Suppose I've compiled everything up, and then I add a
84 -- new definition to module B, that defines "f".
86 -- Then I must detect the name clash in A before going for an early
87 -- exit. The early-exit code checks what's actually needed from B
88 -- to compile A, and of course that doesn't include B.f. That's
89 -- why we wait till after the plusRnEnv stuff to do the early-exit.
90 checkEarlyExit this_mod `thenRn` \ up_to_date ->
92 returnRn (error "early exit", Nothing)
96 -- PROCESS EXPORT LISTS
98 export_avails :: ExportAvails
99 export_avails = foldr plusExportAvails local_mod_avails imp_avails_s
101 explicit_names :: NameSet -- locally defined or explicitly imported
102 explicit_names = foldr add_on emptyNameSet (local_avails : explicit_imports_s)
103 add_on avails names = foldr (unionNameSets . mkNameSet . availNames) names avails
105 exportsFromAvail this_mod exports export_avails rn_env
106 `thenRn` \ (export_fn, export_env) ->
108 -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
109 mapRn (recordSlurp Nothing Compulsory) local_avails `thenRn_`
111 -- BUILD THE "IMPORT FN". It just tells whether a name is in
112 -- scope in an unqualified form.
114 print_unqual = mkImportFn imp_rn_env
117 returnRn (export_fn, Just (export_env, rn_env, explicit_names, print_unqual))
118 ) `thenRn` \ (_, result) ->
121 junk_exp_fn = error "RnNames:export_fn"
123 all_imports = prel_imports ++ imports
125 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
126 -- because the former doesn't even look at Prelude.hi for instance declarations,
127 -- whereas the latter does.
128 prel_imports | this_mod == pRELUDE ||
129 explicit_prelude_import ||
130 opt_NoImplicitPrelude
133 | otherwise = [ImportDecl pRELUDE
134 False {- Not qualified -}
135 HiFile {- Not source imported -}
136 Nothing {- No "as" -}
137 Nothing {- No import list -}
140 explicit_prelude_import
141 = not (null [ () | (ImportDecl mod qual _ _ _ _) <- imports, mod == pRELUDE ])
146 = checkErrsRn `thenRn` \ no_errs_so_far ->
147 if not no_errs_so_far then
148 -- Found errors already, so exit now
152 traceRn (text "Considering whether compilation is required...") `thenRn_`
153 if not opt_SourceUnchanged then
154 -- Source code changed and no errors yet... carry on
155 traceRn (nest 4 (text "source file changed or recompilation check turned off")) `thenRn_`
159 -- Unchanged source, and no errors yet; see if usage info
160 -- up to date, and exit if so
161 checkUpToDate mod `thenRn` \ up_to_date ->
162 putDocRn (text "Compilation" <+>
163 text (if up_to_date then "IS NOT" else "IS") <+>
164 text "required") `thenRn_`
169 importsFromImportDecl :: RdrNameImportDecl
170 -> RnMG (RnEnv, ExportAvails, [AvailInfo])
172 importsFromImportDecl (ImportDecl mod qual_only as_source as_mod import_spec loc)
174 getInterfaceExports mod as_source `thenRn` \ (avails, fixities) ->
175 filterImports mod import_spec avails `thenRn` \ (filtered_avails, hides, explicits) ->
177 how_in_scope = FromImportDecl mod loc
180 True -- Want qualified names
181 (not qual_only) -- Maybe want unqualified names
184 filtered_avails (\n -> how_in_scope)
185 [ (occ,(fixity,how_in_scope)) | (occ,fixity) <- fixities ]
186 `thenRn` \ (rn_env, mod_avails) ->
187 returnRn (rn_env, mod_avails, explicits)
192 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
193 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
194 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
196 False -- Don't want qualified names
197 True -- Want unqualified names
198 Nothing -- No "as M" part
200 avails (\n -> FromLocalDefn (getSrcLoc n))
202 `thenRn` \ (rn_env, mod_avails) ->
203 returnRn (rn_env, mod_avails, avails)
205 newLocalName rdr_name loc
206 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
208 getLocalDeclBinders avails (ValD binds)
209 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
210 returnRn (val_avails ++ avails)
212 getLocalDeclBinders avails decl
213 = getDeclBinders newLocalName decl `thenRn` \ avail ->
215 NotAvailable -> returnRn avails -- Instance decls and suchlike
216 other -> returnRn (avail : avails)
218 do_one (rdr_name, loc)
219 = newLocalName rdr_name loc `thenRn` \ name ->
220 returnRn (Avail name)
223 %************************************************************************
225 \subsection{Filtering imports}
227 %************************************************************************
229 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
230 available, and filters it through the import spec (if any).
233 filterImports :: Module
234 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
235 -> [AvailInfo] -- What's available
236 -> RnMG ([AvailInfo], -- What's actually imported
237 [AvailInfo], -- What's to be hidden (the unqualified version, that is)
238 [AvailInfo]) -- What was imported explicitly
240 -- Complains if import spec mentions things that the module doesn't export
241 -- Warns/informs if import spec contains duplicates.
242 filterImports mod Nothing imports
243 = returnRn (imports, [], [])
245 filterImports mod (Just (want_hiding, import_items)) avails
246 = mapRn check_item import_items `thenRn` \ item_avails ->
249 returnRn (avails, item_avails, []) -- All imported; item_avails to be hidden
251 returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
254 import_fm :: FiniteMap OccName AvailInfo
255 import_fm = listToFM [ (nameOccName name, avail)
257 name <- availEntityNames avail]
259 check_item item@(IEModuleContents _)
260 = addErrRn (badImportItemErr mod item) `thenRn_`
261 returnRn NotAvailable
264 | not (maybeToBool maybe_in_import_avails) ||
265 (case filtered_avail of { NotAvailable -> True; other -> False })
266 = addErrRn (badImportItemErr mod item) `thenRn_`
267 returnRn NotAvailable
269 | otherwise = returnRn filtered_avail
272 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
273 Just avail = maybe_in_import_avails
274 filtered_avail = filterAvail item avail
279 %************************************************************************
281 \subsection{Qualifiying imports}
283 %************************************************************************
285 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
286 of an import decl, and deals with producing an @RnEnv@ with the
287 right qualified names. It also turns the @Names@ in the @ExportEnv@ into
288 fully fledged @Names@.
291 qualifyImports :: Module -- Imported module
292 -> Bool -- True <=> want qualified import
293 -> Bool -- True <=> want unqualified import
294 -> Maybe Module -- Optional "as M" part
295 -> [AvailInfo] -- What's to be hidden
296 -> Avails -> (Name -> HowInScope) -- Whats imported and how
297 -> [(OccName, (Fixity, HowInScope))] -- Ditto for fixities
298 -> RnMG (RnEnv, ExportAvails)
300 qualifyImports this_mod qual_imp unqual_imp as_mod hides
301 avails name_to_his fixities
303 -- Make the name environment. Even though we're talking about a
304 -- single import module there might still be name clashes,
305 -- because it might be the module being compiled.
306 foldlRn add_avail emptyGlobalNameEnv avails `thenRn` \ name_env1 ->
308 -- Delete things that are hidden
309 name_env2 = foldl del_avail name_env1 hides
311 -- Create the fixity env
312 fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
314 -- Create the export-availability info
315 export_avails = mkExportAvails qual_mod unqual_imp name_env2 avails
317 returnRn (RnEnv name_env2 fixity_env, export_avails)
319 qual_mod = case as_mod of
321 Just another_name -> another_name
323 add_avail :: GlobalNameEnv -> AvailInfo -> RnMG GlobalNameEnv
324 add_avail env avail = foldlRn add_name env (availNames avail)
326 add_name env name = add qual_imp env (Qual qual_mod occ err_hif) `thenRn` \ env1 ->
327 add unqual_imp env1 (Unqual occ)
329 add False env rdr_name = returnRn env
330 add True env rdr_name = addOneToGlobalNameEnv env rdr_name (name, name_to_his name)
331 occ = nameOccName name
333 del_avail env avail = foldl delOneFromGlobalNameEnv env rdr_names
335 rdr_names = map (Unqual . nameOccName) (availNames avail)
337 add_fixity name_env fix_env (occ_name, fixity)
338 = add qual $ add unqual $ fix_env
340 qual = Qual qual_mod occ_name err_hif
341 unqual = Unqual occ_name
343 add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
344 = addOneToFixityEnv fix_env rdr_name fixity
348 err_hif = error "qualifyImports: hif" -- Not needed in key to mapping
351 unQualify adds an Unqual binding for every existing Qual binding.
354 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
355 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ _, elt) <- fmToList fm]
358 %************************************************************************
360 \subsection{Local declarations}
362 %************************************************************************
366 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, HowInScope))
368 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
369 = returnRn (rdrNameOcc rdr_name, (fixity, FromLocalDefn loc))
373 %************************************************************************
375 \subsection{Export list processing
377 %************************************************************************
379 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
380 When exporting we need to combine the availabilities for a particular
381 exported thing, and we also need to check for name clashes -- that
382 is: two exported things must have different @OccNames@.
385 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo, Int{-no. of clashes-})
386 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
387 -- for error reporting, as well as to its AvailInfo
389 emptyAvailEnv = emptyFM
392 Add new entry to environment. Checks for name clashes, i.e.,
393 plain duplicates or exported entity pairs that have different OccNames.
394 (c.f. 5.1.1 of Haskell 1.4 report.)
396 addAvailEnv :: Bool -> RdrNameIE -> AvailEnv -> AvailInfo -> RnM s d AvailEnv
397 addAvailEnv warn_dups ie env NotAvailable = returnRn env
398 addAvailEnv warn_dups ie env (AvailTC _ []) = returnRn env
399 addAvailEnv warn_dups ie env avail
400 | warn_dups = mapMaybeRn (addErrRn . availClashErr) () conflict `thenRn_`
401 returnRn (addToFM_C addAvail env key elt)
402 | otherwise = returnRn (addToFM_C addAvail env key elt)
404 key = nameOccName (availName avail)
405 elt = (ie,avail,reports_on)
408 | maybeToBool dup = 1
411 conflict = conflictFM bad_avail env key elt
413 | warn_dups = conflictFM dup_avail env key elt
414 | otherwise = Nothing
416 addListToAvailEnv :: AvailEnv -> RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
417 addListToAvailEnv env ie items = foldlRn (addAvailEnv False ie) env items
419 bad_avail (ie1,avail1,r1) (ie2,avail2,r2)
420 = availName avail1 /= availName avail2 -- Same OccName, different Name
421 dup_avail (ie1,avail1,r1) (ie2,avail2,r2)
422 = availName avail1 == availName avail2 -- Same OccName & avail.
424 addAvail (ie1,a1,r1) (ie2,a2,r2) = (ie1, a1 `plusAvail` a2, r1 + r2)
427 Processing the export list.
429 You might think that we should record things that appear in the export list as
430 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
431 that they are in scope, but there is no need to slurp in their actual declaration
432 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
433 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
434 includes ConcBase.StateAndSynchVar#, and so on...
437 exportsFromAvail :: Module
438 -> Maybe [RdrNameIE] -- Export spec
441 -> RnMG (Name -> ExportFlag, ExportEnv)
442 -- Complains if two distinct exports have same OccName
443 -- Warns about identical exports.
444 -- Complains about exports items not in scope
445 exportsFromAvail this_mod Nothing export_avails rn_env
446 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
448 exportsFromAvail this_mod (Just export_items)
449 (mod_avail_env, entity_avail_env)
450 (RnEnv global_name_env fixity_env)
451 = checkForModuleExportDups export_items `thenRn` \ export_items' ->
452 foldlRn exports_from_item emptyAvailEnv export_items' `thenRn` \ export_avail_env ->
454 dup_entries = fmToList (filterFM (\ _ (_,_,clashes) -> clashes > 0) export_avail_env)
456 mapRn (addWarnRn . dupExportWarn) dup_entries `thenRn_`
458 export_avails = map (\ (_,a,_) -> a) (eltsFM export_avail_env)
459 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
460 export_fn = mk_export_fn export_avails
462 returnRn (export_fn, ExportEnv export_avails export_fixities)
465 exports_from_item :: AvailEnv -> RdrNameIE -> RnMG AvailEnv
466 exports_from_item export_avail_env ie@(IEModuleContents mod)
467 = case lookupFM mod_avail_env mod of
468 Nothing -> failWithRn export_avail_env (modExportErr mod)
469 Just avails -> addListToAvailEnv export_avail_env ie avails
471 exports_from_item export_avail_env ie
472 | not (maybeToBool maybe_in_scope)
473 = failWithRn export_avail_env (unknownNameErr (ieName ie))
476 -- I can't see why this should ever happen; if the thing is in scope
477 -- at all it ought to have some availability
478 | not (maybeToBool maybe_avail)
479 = pprTrace "exportsFromAvail: curious Nothing:" (ppr name)
480 returnRn export_avail_env
484 = failWithRn export_avail_env (exportItemErr ie export_avail)
486 | otherwise -- Phew! It's OK!
487 = addAvailEnv opt_WarnDuplicateExports ie export_avail_env export_avail
489 maybe_in_scope = lookupFM global_name_env (ieName ie)
490 Just (name,_) = maybe_in_scope
491 maybe_avail = lookupUFM entity_avail_env name
492 Just avail = maybe_avail
493 export_avail = filterAvail ie avail
494 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
496 -- We export a fixity iff we export a thing with the same (qualified) RdrName
497 mk_exported_fixities :: NameSet -> [(OccName, Fixity)]
498 mk_exported_fixities exports
499 = fmToList (foldr (perhaps_add_fixity exports)
501 (fmToList fixity_env))
503 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, HowInScope))
504 -> FiniteMap OccName Fixity
505 -> FiniteMap OccName Fixity
506 perhaps_add_fixity exports (rdr_name, (fixity, how_in_scope)) fix_env
508 do_nothing = fix_env -- The default is to pass on the env unchanged
510 -- Step 1: check whether the rdr_name is in scope; if so find its Name
511 case lookupFM global_name_env rdr_name of {
512 Nothing -> do_nothing;
513 Just (fixity_name,_) ->
515 -- Step 2: check whether the fixity thing is exported
516 if not (fixity_name `elemNameSet` exports) then
520 -- Step 3: check whether we already have a fixity for the
521 -- Name's OccName in the fix_env we are building up. This can easily
522 -- happen. the original fixity_env might contain bindings for
523 -- M.a and N.a, if a was imported via M and N.
524 -- If this does happen, we expect the fixity to be the same either way.
526 occ_name = rdrNameOcc rdr_name
528 case lookupFM fix_env occ_name of {
529 Just fixity1 -> -- Got it already
530 ASSERT( fixity == fixity1 )
534 -- Step 3: add it to the outgoing fix_env
535 addToFM fix_env occ_name fixity
538 {- warn and weed out duplicate module entries from export list. -}
539 checkForModuleExportDups :: [RdrNameIE] -> RnMG [RdrNameIE]
540 checkForModuleExportDups ls
541 | opt_WarnDuplicateExports = check_modules ls
542 | otherwise = returnRn ls
544 -- NOTE: reorders the export list by moving all module-contents
545 -- exports to the end (removing duplicates in the process.)
549 ls -> mapRn (\ ds@(IEModuleContents x:_) ->
550 addWarnRn (dupModuleExport x (length ds))) ls `thenRn_`
551 returnRn ()) `thenRn_`
552 returnRn (ls_no_modules ++ no_module_dups)
554 (ls_no_modules,modules) = foldr split_mods ([],[]) ls
556 split_mods i@(IEModuleContents _) ~(no_ms,ms) = (no_ms,i:ms)
557 split_mods i ~(no_ms,ms) = (i:no_ms,ms)
559 (no_module_dups, dups) = removeDups cmp_mods modules
561 cmp_mods (IEModuleContents m1) (IEModuleContents m2) = m1 `compare` m2
563 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
565 = \name -> if name `elemNameSet` exported_names
569 exported_names :: NameSet
570 exported_names = availsToNameSet avails
573 %************************************************************************
577 %************************************************************************
580 badImportItemErr mod ie
581 = sep [ptext SLIT("Module"), quotes (pprModule mod),
582 ptext SLIT("does not export"), quotes (ppr ie)]
585 = hsep [ ptext SLIT("Unknown module in export list: module"), quotes (pprModule mod)]
587 exportItemErr export_item NotAvailable
588 = sep [ ptext SLIT("Export item not in scope:"), quotes (ppr export_item)]
590 exportItemErr export_item avail
591 = hang (ptext SLIT("Export item not fully in scope:"))
592 4 (vcat [hsep [ptext SLIT("Wanted: "), ppr export_item],
593 hsep [ptext SLIT("Available:"), ppr (ieOcc export_item), pprAvail avail]])
595 availClashErr (occ_name, ((ie1,avail1,_), (ie2,avail2,_)))
596 = hsep [ptext SLIT("The export items"), quotes (ppr ie1), ptext SLIT("and"), quotes (ppr ie2),
597 ptext SLIT("create conflicting exports for"), quotes (ppr occ_name)]
599 dupExportWarn (occ_name, (_,_,times))
600 = hsep [quotes (ppr occ_name),
601 ptext SLIT("mentioned"), speakNTimes (times+1),
602 ptext SLIT("in export list")]
604 dupModuleExport mod times
605 = hsep [ptext SLIT("Module"), quotes (pprModule mod),
606 ptext SLIT("mentioned"), speakNTimes times,
607 ptext SLIT("in export list")]