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,
53 FiniteMap Name HowInScope, -- Locally defined or explicitly imported
54 Name -> PrintUnqualified))
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_info) ->
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_info :: FiniteMap Name HowInScope -- Locally defined or explicitly imported
102 explicit_info = foldr plusFM local_info explicit_imports_s
104 exportsFromAvail this_mod exports export_avails rn_env
105 `thenRn` \ (export_fn, export_env) ->
107 -- BUILD THE "IMPORT FN". It just tells whether a name is in
108 -- scope in an unqualified form.
110 print_unqual = mkImportFn imp_rn_env
113 returnRn (export_fn, Just (export_env, rn_env, explicit_info, print_unqual))
114 ) `thenRn` \ (_, result) ->
117 junk_exp_fn = error "RnNames:export_fn"
119 all_imports = prel_imports ++ imports
121 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
122 -- because the former doesn't even look at Prelude.hi for instance declarations,
123 -- whereas the latter does.
124 prel_imports | this_mod == pRELUDE ||
125 explicit_prelude_import ||
126 opt_NoImplicitPrelude
129 | otherwise = [ImportDecl pRELUDE
130 False {- Not qualified -}
131 HiFile {- Not source imported -}
132 Nothing {- No "as" -}
133 Nothing {- No import list -}
136 explicit_prelude_import
137 = not (null [ () | (ImportDecl mod qual _ _ _ _) <- imports, mod == pRELUDE ])
142 = checkErrsRn `thenRn` \ no_errs_so_far ->
143 if not no_errs_so_far then
144 -- Found errors already, so exit now
148 traceRn (text "Considering whether compilation is required...") `thenRn_`
149 if not opt_SourceUnchanged then
150 -- Source code changed and no errors yet... carry on
151 traceRn (nest 4 (text "source file changed or recompilation check turned off")) `thenRn_`
155 -- Unchanged source, and no errors yet; see if usage info
156 -- up to date, and exit if so
157 checkUpToDate mod `thenRn` \ up_to_date ->
158 putDocRn (text "Compilation" <+>
159 text (if up_to_date then "IS NOT" else "IS") <+>
160 text "required") `thenRn_`
165 importsFromImportDecl :: RdrNameImportDecl
168 FiniteMap Name HowInScope) -- Records the explicitly-imported things
170 importsFromImportDecl (ImportDecl mod qual_only as_source as_mod import_spec loc)
172 getInterfaceExports mod as_source `thenRn` \ (avails, fixities) ->
173 filterImports mod import_spec avails `thenRn` \ (filtered_avails, hides, explicits) ->
175 how_in_scope = FromImportDecl mod loc
176 explicit_info = listToFM [(name, how_in_scope)
177 | avail <- explicits,
178 name <- availNames avail
182 True -- Want qualified names
183 (not qual_only) -- Maybe want unqualified names
186 filtered_avails (\n -> how_in_scope)
187 [ (occ,(fixity,how_in_scope)) | (occ,fixity) <- fixities ]
188 `thenRn` \ (rn_env, mod_avails) ->
189 returnRn (rn_env, mod_avails, explicit_info)
194 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
195 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
197 -- Record that locally-defined things are available
198 mapRn (recordSlurp Nothing Compulsory) avails `thenRn_`
201 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
203 -- Record where the available stuff came from
205 explicit_info = listToFM [(name, FromLocalDefn (getSrcLoc name))
207 name <- availNames avail
211 False -- Don't want qualified names
212 True -- Want unqualified names
213 Nothing -- No "as M" part
215 avails (\n -> FromLocalDefn (getSrcLoc n))
217 `thenRn` \ (rn_env, mod_avails) ->
218 returnRn (rn_env, mod_avails, explicit_info)
220 newLocalName rdr_name loc
221 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
223 getLocalDeclBinders avails (ValD binds)
224 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
225 returnRn (val_avails ++ avails)
227 getLocalDeclBinders avails decl
228 = getDeclBinders newLocalName decl `thenRn` \ avail ->
230 NotAvailable -> returnRn avails -- Instance decls and suchlike
231 other -> returnRn (avail : avails)
233 do_one (rdr_name, loc)
234 = newLocalName rdr_name loc `thenRn` \ name ->
235 returnRn (Avail name)
238 %************************************************************************
240 \subsection{Filtering imports}
242 %************************************************************************
244 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
245 available, and filters it through the import spec (if any).
248 filterImports :: Module
249 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
250 -> [AvailInfo] -- What's available
251 -> RnMG ([AvailInfo], -- What's actually imported
252 [AvailInfo], -- What's to be hidden (the unqualified version, that is)
253 [AvailInfo]) -- What was imported explicitly
255 -- Complains if import spec mentions things that the module doesn't export
256 -- Warns/informs if import spec contains duplicates.
257 filterImports mod Nothing imports
258 = returnRn (imports, [], [])
260 filterImports mod (Just (want_hiding, import_items)) avails
261 = mapRn check_item import_items `thenRn` \ item_avails ->
264 returnRn (avails, item_avails, []) -- All imported; item_avails to be hidden
266 returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
269 import_fm :: FiniteMap OccName AvailInfo
270 import_fm = listToFM [ (nameOccName name, avail)
272 name <- availEntityNames avail]
274 check_item item@(IEModuleContents _)
275 = addErrRn (badImportItemErr mod item) `thenRn_`
276 returnRn NotAvailable
279 | not (maybeToBool maybe_in_import_avails) ||
280 (case filtered_avail of { NotAvailable -> True; other -> False })
281 = addErrRn (badImportItemErr mod item) `thenRn_`
282 returnRn NotAvailable
284 | otherwise = returnRn filtered_avail
287 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
288 Just avail = maybe_in_import_avails
289 filtered_avail = filterAvail item avail
294 %************************************************************************
296 \subsection{Qualifiying imports}
298 %************************************************************************
300 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
301 of an import decl, and deals with producing an @RnEnv@ with the
302 right qualified names. It also turns the @Names@ in the @ExportEnv@ into
303 fully fledged @Names@.
306 qualifyImports :: Module -- Imported module
307 -> Bool -- True <=> want qualified import
308 -> Bool -- True <=> want unqualified import
309 -> Maybe Module -- Optional "as M" part
310 -> [AvailInfo] -- What's to be hidden
311 -> Avails -> (Name -> HowInScope) -- Whats imported and how
312 -> [(OccName, (Fixity, HowInScope))] -- Ditto for fixities
313 -> RnMG (RnEnv, ExportAvails)
315 qualifyImports this_mod qual_imp unqual_imp as_mod hides
316 avails name_to_his fixities
318 -- Make the name environment. Even though we're talking about a
319 -- single import module there might still be name clashes,
320 -- because it might be the module being compiled.
321 foldlRn add_avail emptyGlobalNameEnv avails `thenRn` \ name_env1 ->
323 -- Delete things that are hidden
324 name_env2 = foldl del_avail name_env1 hides
326 -- Create the fixity env
327 fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
329 -- Create the export-availability info
330 export_avails = mkExportAvails qual_mod unqual_imp name_env2 avails
332 returnRn (RnEnv name_env2 fixity_env, export_avails)
334 qual_mod = case as_mod of
336 Just another_name -> another_name
338 add_avail :: GlobalNameEnv -> AvailInfo -> RnMG GlobalNameEnv
339 add_avail env avail = foldlRn add_name env (availNames avail)
341 add_name env name = add qual_imp env (Qual qual_mod occ err_hif) `thenRn` \ env1 ->
342 add unqual_imp env1 (Unqual occ)
344 add False env rdr_name = returnRn env
345 add True env rdr_name = addOneToGlobalNameEnv env rdr_name (name, name_to_his name)
346 occ = nameOccName name
348 del_avail env avail = foldl delOneFromGlobalNameEnv env rdr_names
350 rdr_names = map (Unqual . nameOccName) (availNames avail)
352 add_fixity name_env fix_env (occ_name, fixity)
353 = add qual $ add unqual $ fix_env
355 qual = Qual qual_mod occ_name err_hif
356 unqual = Unqual occ_name
358 add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
359 = addOneToFixityEnv fix_env rdr_name fixity
363 err_hif = error "qualifyImports: hif" -- Not needed in key to mapping
366 unQualify adds an Unqual binding for every existing Qual binding.
369 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
370 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ _, elt) <- fmToList fm]
373 %************************************************************************
375 \subsection{Local declarations}
377 %************************************************************************
381 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, HowInScope))
383 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
384 = returnRn (rdrNameOcc rdr_name, (fixity, FromLocalDefn loc))
388 %************************************************************************
390 \subsection{Export list processing
392 %************************************************************************
394 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
395 When exporting we need to combine the availabilities for a particular
396 exported thing, and we also need to check for name clashes -- that
397 is: two exported things must have different @OccNames@.
400 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo, Int{-no. of clashes-})
401 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
402 -- for error reporting, as well as to its AvailInfo
404 emptyAvailEnv = emptyFM
407 Add new entry to environment. Checks for name clashes, i.e.,
408 plain duplicates or exported entity pairs that have different OccNames.
409 (c.f. 5.1.1 of Haskell 1.4 report.)
411 addAvailEnv :: Bool -> RdrNameIE -> AvailEnv -> AvailInfo -> RnM s d AvailEnv
412 addAvailEnv warn_dups ie env NotAvailable = returnRn env
413 addAvailEnv warn_dups ie env (AvailTC _ []) = returnRn env
414 addAvailEnv warn_dups ie env avail
415 | warn_dups = mapMaybeRn (addErrRn . availClashErr) () conflict `thenRn_`
416 returnRn (addToFM_C addAvail env key elt)
417 | otherwise = returnRn (addToFM_C addAvail env key elt)
419 occ_avail = nameOccName (availName avail)
422 | not warn_dups || occ_ie == occ_avail = occ_avail
424 -- export item is a class method, use export occ name instead.
425 -- (this is only needed to get more precise warnings about
427 elt = (ie,avail,reports_on)
430 | maybeToBool dup = 1
433 conflict = conflictFM bad_avail env key elt
435 | warn_dups = conflictFM dup_avail env key elt
436 | otherwise = Nothing
438 addListToAvailEnv :: AvailEnv -> RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
439 addListToAvailEnv env ie items
440 = foldlRn (addAvailEnv False{-don't warn about dups-} ie) env items
442 bad_avail (ie1,avail1,r1) (ie2,avail2,r2)
443 = availName avail1 /= availName avail2 -- Same OccName, different Name
444 dup_avail (ie1,avail1,r1) (ie2,avail2,r2)
445 = availName avail1 == availName avail2 -- Same OccName & avail.
447 addAvail (ie1,a1,r1) (ie2,a2,r2) = (ie1, a1 `plusAvail` a2, r1 + r2)
450 Processing the export list.
452 You might think that we should record things that appear in the export list as
453 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
454 that they are in scope, but there is no need to slurp in their actual declaration
455 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
456 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
457 includes ConcBase.StateAndSynchVar#, and so on...
460 exportsFromAvail :: Module
461 -> Maybe [RdrNameIE] -- Export spec
464 -> RnMG (Name -> ExportFlag, ExportEnv)
465 -- Complains if two distinct exports have same OccName
466 -- Warns about identical exports.
467 -- Complains about exports items not in scope
468 exportsFromAvail this_mod Nothing export_avails rn_env
469 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
471 exportsFromAvail this_mod (Just export_items)
472 (mod_avail_env, entity_avail_env)
473 (RnEnv global_name_env fixity_env)
474 = checkForModuleExportDups export_items `thenRn` \ export_items' ->
475 foldlRn exports_from_item emptyAvailEnv export_items' `thenRn` \ export_avail_env ->
477 dup_entries = fmToList (filterFM (\ _ (_,_,clashes) -> clashes > 0) export_avail_env)
479 mapRn (addWarnRn . dupExportWarn) dup_entries `thenRn_`
481 export_avails = map (\ (_,a,_) -> a) (eltsFM export_avail_env)
482 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
483 export_fn = mk_export_fn export_avails
485 returnRn (export_fn, ExportEnv export_avails export_fixities)
488 exports_from_item :: AvailEnv -> RdrNameIE -> RnMG AvailEnv
489 exports_from_item export_avail_env ie@(IEModuleContents mod)
490 = case lookupFM mod_avail_env mod of
491 Nothing -> failWithRn export_avail_env (modExportErr mod)
492 Just avails -> addListToAvailEnv export_avail_env ie avails
494 exports_from_item export_avail_env ie
495 | not (maybeToBool maybe_in_scope)
496 = failWithRn export_avail_env (unknownNameErr (ieName ie))
499 -- I can't see why this should ever happen; if the thing is in scope
500 -- at all it ought to have some availability
501 | not (maybeToBool maybe_avail)
502 = pprTrace "exportsFromAvail: curious Nothing:" (ppr name)
503 returnRn export_avail_env
507 = failWithRn export_avail_env (exportItemErr ie export_avail)
509 | otherwise -- Phew! It's OK!
510 = addAvailEnv opt_WarnDuplicateExports ie export_avail_env export_avail
512 maybe_in_scope = lookupFM global_name_env (ieName ie)
513 Just (name,_) = maybe_in_scope
514 maybe_avail = lookupUFM entity_avail_env name
515 Just avail = maybe_avail
516 export_avail = filterAvail ie avail
517 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
519 -- We export a fixity iff we export a thing with the same (qualified) RdrName
520 mk_exported_fixities :: NameSet -> [(OccName, Fixity)]
521 mk_exported_fixities exports
522 = fmToList (foldr (perhaps_add_fixity exports)
524 (fmToList fixity_env))
526 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, HowInScope))
527 -> FiniteMap OccName Fixity
528 -> FiniteMap OccName Fixity
529 perhaps_add_fixity exports (rdr_name, (fixity, how_in_scope)) fix_env
531 do_nothing = fix_env -- The default is to pass on the env unchanged
533 -- Step 1: check whether the rdr_name is in scope; if so find its Name
534 case lookupFM global_name_env rdr_name of {
535 Nothing -> do_nothing;
536 Just (fixity_name,_) ->
538 -- Step 2: check whether the fixity thing is exported
539 if not (fixity_name `elemNameSet` exports) then
543 -- Step 3: check whether we already have a fixity for the
544 -- Name's OccName in the fix_env we are building up. This can easily
545 -- happen. the original fixity_env might contain bindings for
546 -- M.a and N.a, if a was imported via M and N.
547 -- If this does happen, we expect the fixity to be the same either way.
549 occ_name = rdrNameOcc rdr_name
551 case lookupFM fix_env occ_name of {
552 Just fixity1 -> -- Got it already
553 ASSERT( fixity == fixity1 )
557 -- Step 3: add it to the outgoing fix_env
558 addToFM fix_env occ_name fixity
561 {- warn and weed out duplicate module entries from export list. -}
562 checkForModuleExportDups :: [RdrNameIE] -> RnMG [RdrNameIE]
563 checkForModuleExportDups ls
564 | opt_WarnDuplicateExports = check_modules ls
565 | otherwise = returnRn ls
567 -- NOTE: reorders the export list by moving all module-contents
568 -- exports to the end (removing duplicates in the process.)
572 ls -> mapRn (\ ds@(IEModuleContents x:_) ->
573 addWarnRn (dupModuleExport x (length ds))) ls `thenRn_`
574 returnRn ()) `thenRn_`
575 returnRn (ls_no_modules ++ no_module_dups)
577 (ls_no_modules,modules) = foldr split_mods ([],[]) ls
579 split_mods i@(IEModuleContents _) (no_ms,ms) = (no_ms,i:ms)
580 split_mods i (no_ms,ms) = (i:no_ms,ms)
582 (no_module_dups, dups) = removeDups cmp_mods modules
584 cmp_mods (IEModuleContents m1) (IEModuleContents m2) = m1 `compare` m2
586 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
588 = \name -> if name `elemNameSet` exported_names
592 exported_names :: NameSet
593 exported_names = availsToNameSet avails
596 %************************************************************************
600 %************************************************************************
603 badImportItemErr mod ie
604 = sep [ptext SLIT("Module"), quotes (pprModule mod),
605 ptext SLIT("does not export"), quotes (ppr ie)]
608 = hsep [ ptext SLIT("Unknown module in export list: module"), quotes (pprModule mod)]
610 exportItemErr export_item NotAvailable
611 = sep [ ptext SLIT("Export item not in scope:"), quotes (ppr export_item)]
613 exportItemErr export_item avail
614 = hang (ptext SLIT("Export item not fully in scope:"))
615 4 (vcat [hsep [ptext SLIT("Wanted: "), ppr export_item],
616 hsep [ptext SLIT("Available:"), ppr (ieOcc export_item), pprAvail avail]])
618 availClashErr (occ_name, ((ie1,avail1,_), (ie2,avail2,_)))
619 = hsep [ptext SLIT("The export items"), quotes (ppr ie1), ptext SLIT("and"), quotes (ppr ie2),
620 ptext SLIT("create conflicting exports for"), quotes (ppr occ_name)]
622 dupExportWarn (occ_name, (_,_,times))
623 = hsep [quotes (ppr occ_name),
624 ptext SLIT("mentioned"), speakNTimes (times+1),
625 ptext SLIT("in export list")]
627 dupModuleExport mod times
628 = hsep [ptext SLIT("Module"), quotes (pprModule mod),
629 ptext SLIT("mentioned"), speakNTimes times,
630 ptext SLIT("in export list")]