2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
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(..),
19 ForeignDecl(..), ExtName(..), ForKind(..),
23 import RdrHsSyn ( RdrName(..), RdrNameIE, RdrNameImportDecl,
24 RdrNameHsModule, RdrNameFixityDecl,
27 import RnIfaces ( getInterfaceExports, getDeclBinders, recordSlurp, checkUpToDate )
28 import BasicTypes ( IfaceFlavour(..) )
34 import UniqFM ( lookupUFM )
35 import Bag ( bagToList )
36 import Maybes ( maybeToBool )
38 import NameSet ( elemNameSet )
40 import Util ( removeDups )
45 %************************************************************************
47 \subsection{Get global names}
49 %************************************************************************
52 getGlobalNames :: RdrNameHsModule
53 -> RnMG (Maybe (ExportEnv,
55 FiniteMap Name HowInScope, -- Locally defined or explicitly imported
56 Name -> PrintUnqualified))
57 -- Nothing => no need to recompile
59 getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
60 = fixRn (\ ~(rec_exp_fn, _) ->
62 -- PROCESS LOCAL DECLS
63 -- Do these *first* so that the correct provenance gets
64 -- into the global name cache.
65 importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails, local_info) ->
67 -- PROCESS IMPORT DECLS
68 mapAndUnzip3Rn importsFromImportDecl all_imports
69 `thenRn` \ (imp_rn_envs, imp_avails_s, explicit_imports_s) ->
72 -- We put the local env second, 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 imp_rn_env local_rn_env `thenRn` \ rn_env ->
78 -- We can't go for an early exit before this because we have to check
79 -- for name clashes. Consider:
81 -- module A where module B where
85 -- Suppose I've compiled everything up, and then I add a
86 -- new definition to module B, that defines "f".
88 -- Then I must detect the name clash in A before going for an early
89 -- exit. The early-exit code checks what's actually needed from B
90 -- to compile A, and of course that doesn't include B.f. That's
91 -- why we wait till after the plusRnEnv stuff to do the early-exit.
92 checkEarlyExit this_mod `thenRn` \ up_to_date ->
94 returnRn (error "early exit", Nothing)
98 -- PROCESS EXPORT LISTS
100 export_avails :: ExportAvails
101 export_avails = foldr plusExportAvails local_mod_avails imp_avails_s
103 explicit_info :: FiniteMap Name HowInScope -- Locally defined or explicitly imported
104 explicit_info = foldr plusFM local_info explicit_imports_s
106 exportsFromAvail this_mod exports export_avails rn_env
107 `thenRn` \ (export_fn, export_env) ->
109 -- BUILD THE "IMPORT FN". It just tells whether a name is in
110 -- scope in an unqualified form.
112 print_unqual = mkImportFn imp_rn_env
115 returnRn (export_fn, Just (export_env, rn_env, explicit_info, print_unqual))
116 ) `thenRn` \ (_, result) ->
119 junk_exp_fn = error "RnNames:export_fn"
121 all_imports = prel_imports ++ imports
123 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
124 -- because the former doesn't even look at Prelude.hi for instance declarations,
125 -- whereas the latter does.
126 prel_imports | this_mod == pRELUDE ||
127 explicit_prelude_import ||
128 opt_NoImplicitPrelude
131 | otherwise = [ImportDecl pRELUDE
132 False {- Not qualified -}
133 HiFile {- Not source imported -}
134 Nothing {- No "as" -}
135 Nothing {- No import list -}
138 explicit_prelude_import
139 = not (null [ () | (ImportDecl mod qual _ _ _ _) <- imports, mod == pRELUDE ])
144 = checkErrsRn `thenRn` \ no_errs_so_far ->
145 if not no_errs_so_far then
146 -- Found errors already, so exit now
150 traceRn (text "Considering whether compilation is required...") `thenRn_`
151 if not opt_SourceUnchanged then
152 -- Source code changed and no errors yet... carry on
153 traceRn (nest 4 (text "source file changed or recompilation check turned off")) `thenRn_`
157 -- Unchanged source, and no errors yet; see if usage info
158 -- up to date, and exit if so
159 checkUpToDate mod `thenRn` \ up_to_date ->
160 putDocRn (text "Compilation" <+>
161 text (if up_to_date then "IS NOT" else "IS") <+>
162 text "required") `thenRn_`
167 importsFromImportDecl :: RdrNameImportDecl
170 FiniteMap Name HowInScope) -- Records the explicitly-imported things
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
178 explicit_info = listToFM [(name, how_in_scope)
179 | avail <- explicits,
180 name <- availNames avail
184 True -- Want qualified names
185 (not qual_only) -- Maybe want unqualified names
188 filtered_avails (\n -> how_in_scope)
189 [ (occ,(fixity,how_in_scope)) | (occ,fixity) <- fixities ]
190 `thenRn` \ (rn_env, mod_avails) ->
191 returnRn (rn_env, mod_avails, explicit_info)
196 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
197 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
199 -- Record that locally-defined things are available
200 mapRn (recordSlurp Nothing Compulsory) avails `thenRn_`
203 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
205 -- Record where the available stuff came from
207 explicit_info = listToFM [(name, FromLocalDefn (getSrcLoc name))
209 name <- availNames avail
213 False -- Don't want qualified names
214 True -- Want unqualified names
215 Nothing -- No "as M" part
217 avails (\n -> FromLocalDefn (getSrcLoc n))
219 `thenRn` \ (rn_env, mod_avails) ->
220 returnRn (rn_env, mod_avails, explicit_info)
222 newLocalName rdr_name loc
223 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
225 getLocalDeclBinders avails (ValD binds)
226 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
227 returnRn (val_avails ++ avails)
229 -- foreign import declaration
230 getLocalDeclBinders avails (ForD (ForeignDecl nm (FoImport _) _ _ _ loc))
231 = do_one (nm,loc) `thenRn` \ for_avail ->
232 returnRn (for_avail : avails)
234 -- foreign import declaration
235 getLocalDeclBinders avails (ForD (ForeignDecl nm FoLabel _ _ _ loc))
236 = do_one (nm,loc) `thenRn` \ for_avail ->
237 returnRn (for_avail : avails)
239 -- foreign export dynamic declaration
240 getLocalDeclBinders avails (ForD (ForeignDecl nm FoExport _ Dynamic _ loc))
241 = do_one (nm,loc) `thenRn` \ for_avail ->
242 returnRn (for_avail : avails)
244 getLocalDeclBinders avails decl
245 = getDeclBinders newLocalName decl `thenRn` \ avail ->
247 NotAvailable -> returnRn avails -- Instance decls and suchlike
248 other -> returnRn (avail : avails)
250 do_one (rdr_name, loc)
251 = newLocalName rdr_name loc `thenRn` \ name ->
252 returnRn (Avail name)
255 %************************************************************************
257 \subsection{Filtering imports}
259 %************************************************************************
261 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
262 available, and filters it through the import spec (if any).
265 filterImports :: Module
266 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
267 -> [AvailInfo] -- What's available
268 -> RnMG ([AvailInfo], -- What's actually imported
269 [AvailInfo], -- What's to be hidden (the unqualified version, that is)
270 [AvailInfo]) -- What was imported explicitly
272 -- Complains if import spec mentions things that the module doesn't export
273 -- Warns/informs if import spec contains duplicates.
274 filterImports mod Nothing imports
275 = returnRn (imports, [], [])
277 filterImports mod (Just (want_hiding, import_items)) avails
278 = mapRn check_item import_items `thenRn` \ item_avails ->
281 returnRn (avails, item_avails, []) -- All imported; item_avails to be hidden
283 returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
286 import_fm :: FiniteMap OccName AvailInfo
287 import_fm = listToFM [ (nameOccName name, avail)
289 name <- availEntityNames avail]
291 check_item item@(IEModuleContents _)
292 = addErrRn (badImportItemErr mod item) `thenRn_`
293 returnRn NotAvailable
296 | not (maybeToBool maybe_in_import_avails) ||
297 (case filtered_avail of { NotAvailable -> True; other -> False })
298 = addErrRn (badImportItemErr mod item) `thenRn_`
299 returnRn NotAvailable
301 | dodgy_import = addWarnRn (dodgyImportWarn mod item) `thenRn_`
302 returnRn filtered_avail
304 | otherwise = returnRn filtered_avail
307 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
308 Just avail = maybe_in_import_avails
309 filtered_avail = filterAvail item avail
310 dodgy_import = case (item, avail) of
311 (IEThingAll _, AvailTC _ [n]) -> True
312 -- This occurs when you import T(..), but
313 -- only export T abstractly. The single [n]
314 -- in the AvailTC is the type or class itself
322 %************************************************************************
324 \subsection{Qualifiying imports}
326 %************************************************************************
328 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
329 of an import decl, and deals with producing an @RnEnv@ with the
330 right qualified names. It also turns the @Names@ in the @ExportEnv@ into
331 fully fledged @Names@.
334 qualifyImports :: Module -- Imported module
335 -> Bool -- True <=> want qualified import
336 -> Bool -- True <=> want unqualified import
337 -> Maybe Module -- Optional "as M" part
338 -> [AvailInfo] -- What's to be hidden
339 -> Avails -> (Name -> HowInScope) -- Whats imported and how
340 -> [(OccName, (Fixity, HowInScope))] -- Ditto for fixities
341 -> RnMG (RnEnv, ExportAvails)
343 qualifyImports this_mod qual_imp unqual_imp as_mod hides
344 avails name_to_his fixities
346 -- Make the name environment. Even though we're talking about a
347 -- single import module there might still be name clashes,
348 -- because it might be the module being compiled.
349 foldlRn add_avail emptyGlobalNameEnv avails `thenRn` \ name_env1 ->
351 -- Delete things that are hidden
352 name_env2 = foldl del_avail name_env1 hides
354 -- Create the fixity env
355 fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
357 -- Create the export-availability info
358 export_avails = mkExportAvails qual_mod unqual_imp name_env2 avails
360 returnRn (RnEnv name_env2 fixity_env, export_avails)
362 qual_mod = case as_mod of
364 Just another_name -> another_name
366 add_avail :: GlobalNameEnv -> AvailInfo -> RnMG GlobalNameEnv
367 add_avail env avail = foldlRn add_name env (availNames avail)
369 add_name env name = add qual_imp env (Qual qual_mod occ err_hif) `thenRn` \ env1 ->
370 add unqual_imp env1 (Unqual occ)
372 add False env rdr_name = returnRn env
373 add True env rdr_name = addOneToGlobalNameEnv env rdr_name (name, name_to_his name)
374 occ = nameOccName name
376 del_avail env avail = foldl delOneFromGlobalNameEnv env rdr_names
378 rdr_names = map (Unqual . nameOccName) (availNames avail)
380 add_fixity name_env fix_env (occ_name, fixity)
381 = add qual $ add unqual $ fix_env
383 qual = Qual qual_mod occ_name err_hif
384 unqual = Unqual occ_name
386 add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
387 = addOneToFixityEnv fix_env rdr_name fixity
391 err_hif = error "qualifyImports: hif" -- Not needed in key to mapping
394 unQualify adds an Unqual binding for every existing Qual binding.
397 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
398 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ _, elt) <- fmToList fm]
401 %************************************************************************
403 \subsection{Local declarations}
405 %************************************************************************
409 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, HowInScope))
411 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
412 = returnRn (rdrNameOcc rdr_name, (fixity, FromLocalDefn loc))
416 %************************************************************************
418 \subsection{Export list processing
420 %************************************************************************
422 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
423 When exporting we need to combine the availabilities for a particular
424 exported thing, and we also need to check for name clashes -- that
425 is: two exported things must have different @OccNames@.
428 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo, Int{-no. of clashes-})
429 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
430 -- for error reporting, as well as to its AvailInfo
432 emptyAvailEnv = emptyFM
435 Add new entry to environment. Checks for name clashes, i.e.,
436 plain duplicates or exported entity pairs that have different OccNames.
437 (c.f. 5.1.1 of Haskell 1.4 report.)
439 addAvailEnv :: Bool -> RdrNameIE -> AvailEnv -> AvailInfo -> RnM s d AvailEnv
440 addAvailEnv warn_dups ie env NotAvailable = returnRn env
441 addAvailEnv warn_dups ie env (AvailTC _ []) = returnRn env
442 addAvailEnv warn_dups ie env avail
443 | warn_dups = mapMaybeRn (addErrRn . availClashErr) () conflict `thenRn_`
444 returnRn (addToFM_C addAvail env key elt)
445 | otherwise = returnRn (addToFM_C addAvail env key elt)
447 occ_avail = nameOccName (availName avail)
450 | not warn_dups || occ_ie == occ_avail = occ_avail
452 -- export item is a class method, use export occ name instead.
453 -- (this is only needed to get more precise warnings about
455 elt = (ie,avail,reports_on)
458 | maybeToBool dup = 1
461 conflict = conflictFM bad_avail env key elt
463 | warn_dups = conflictFM dup_avail env key elt
464 | otherwise = Nothing
466 addListToAvailEnv :: AvailEnv -> RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
467 addListToAvailEnv env ie items
468 = foldlRn (addAvailEnv False{-don't warn about dups-} ie) env items
470 bad_avail (ie1,avail1,r1) (ie2,avail2,r2)
471 = availName avail1 /= availName avail2 -- Same OccName, different Name
472 dup_avail (ie1,avail1,r1) (ie2,avail2,r2)
473 = availName avail1 == availName avail2 -- Same OccName & avail.
475 addAvail (ie1,a1,r1) (ie2,a2,r2) = (ie1, a1 `plusAvail` a2, r1 + r2)
478 Processing the export list.
480 You might think that we should record things that appear in the export list as
481 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
482 that they are in scope, but there is no need to slurp in their actual declaration
483 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
484 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
485 includes ConcBase.StateAndSynchVar#, and so on...
488 exportsFromAvail :: Module
489 -> Maybe [RdrNameIE] -- Export spec
492 -> RnMG (Name -> ExportFlag, ExportEnv)
493 -- Complains if two distinct exports have same OccName
494 -- Warns about identical exports.
495 -- Complains about exports items not in scope
496 exportsFromAvail this_mod Nothing export_avails rn_env
497 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
499 exportsFromAvail this_mod (Just export_items)
500 (mod_avail_env, entity_avail_env)
501 (RnEnv global_name_env fixity_env)
502 = checkForModuleExportDups export_items `thenRn` \ export_items' ->
503 foldlRn exports_from_item emptyAvailEnv export_items' `thenRn` \ export_avail_env ->
505 dup_entries = fmToList (filterFM (\ _ (_,_,clashes) -> clashes > 0) export_avail_env)
507 mapRn (addWarnRn . dupExportWarn) dup_entries `thenRn_`
509 export_avails = map (\ (_,a,_) -> a) (eltsFM export_avail_env)
510 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
511 export_fn = mk_export_fn export_avails
513 returnRn (export_fn, ExportEnv export_avails export_fixities)
516 exports_from_item :: AvailEnv -> RdrNameIE -> RnMG AvailEnv
517 exports_from_item export_avail_env ie@(IEModuleContents mod)
518 = case lookupFM mod_avail_env mod of
519 Nothing -> failWithRn export_avail_env (modExportErr mod)
520 Just avails -> addListToAvailEnv export_avail_env ie avails
522 exports_from_item export_avail_env ie
523 | not (maybeToBool maybe_in_scope)
524 = failWithRn export_avail_env (unknownNameErr (ieName ie))
527 -- I can't see why this should ever happen; if the thing is in scope
528 -- at all it ought to have some availability
529 | not (maybeToBool maybe_avail)
530 = pprTrace "exportsFromAvail: curious Nothing:" (ppr name)
531 returnRn export_avail_env
535 = failWithRn export_avail_env (exportItemErr ie export_avail)
537 | otherwise -- Phew! It's OK!
538 = addAvailEnv opt_WarnDuplicateExports ie export_avail_env export_avail
540 maybe_in_scope = lookupFM global_name_env (ieName ie)
541 Just (name,_) = maybe_in_scope
542 maybe_avail = lookupUFM entity_avail_env name
543 Just avail = maybe_avail
544 export_avail = filterAvail ie avail
545 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
547 -- We export a fixity iff we export a thing with the same (qualified) RdrName
548 mk_exported_fixities :: NameSet -> [(OccName, Fixity)]
549 mk_exported_fixities exports
550 = fmToList (foldr (perhaps_add_fixity exports)
552 (fmToList fixity_env))
554 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, HowInScope))
555 -> FiniteMap OccName Fixity
556 -> FiniteMap OccName Fixity
557 perhaps_add_fixity exports (rdr_name, (fixity, how_in_scope)) fix_env
559 do_nothing = fix_env -- The default is to pass on the env unchanged
561 -- Step 1: check whether the rdr_name is in scope; if so find its Name
562 case lookupFM global_name_env rdr_name of {
563 Nothing -> do_nothing;
564 Just (fixity_name,_) ->
566 -- Step 2: check whether the fixity thing is exported
567 if not (fixity_name `elemNameSet` exports) then
571 -- Step 3: check whether we already have a fixity for the
572 -- Name's OccName in the fix_env we are building up. This can easily
573 -- happen. the original fixity_env might contain bindings for
574 -- M.a and N.a, if a was imported via M and N.
575 -- If this does happen, we expect the fixity to be the same either way.
577 occ_name = rdrNameOcc rdr_name
579 case lookupFM fix_env occ_name of {
580 Just fixity1 -> -- Got it already
581 ASSERT( fixity == fixity1 )
585 -- Step 3: add it to the outgoing fix_env
586 addToFM fix_env occ_name fixity
589 {- warn and weed out duplicate module entries from export list. -}
590 checkForModuleExportDups :: [RdrNameIE] -> RnMG [RdrNameIE]
591 checkForModuleExportDups ls
592 | opt_WarnDuplicateExports = check_modules ls
593 | otherwise = returnRn ls
595 -- NOTE: reorders the export list by moving all module-contents
596 -- exports to the end (removing duplicates in the process.)
600 ls -> mapRn (\ ds@(IEModuleContents x:_) ->
601 addWarnRn (dupModuleExport x (length ds))) ls `thenRn_`
602 returnRn ()) `thenRn_`
603 returnRn (ls_no_modules ++ no_module_dups)
605 (ls_no_modules,modules) = foldr split_mods ([],[]) ls
607 split_mods i@(IEModuleContents _) (no_ms,ms) = (no_ms,i:ms)
608 split_mods i (no_ms,ms) = (i:no_ms,ms)
610 (no_module_dups, dups) = removeDups cmp_mods modules
612 cmp_mods (IEModuleContents m1) (IEModuleContents m2) = m1 `compare` m2
614 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
616 = \name -> if name `elemNameSet` exported_names
620 exported_names :: NameSet
621 exported_names = availsToNameSet avails
624 %************************************************************************
628 %************************************************************************
631 badImportItemErr mod ie
632 = sep [ptext SLIT("Module"), quotes (pprModule mod),
633 ptext SLIT("does not export"), quotes (ppr ie)]
635 dodgyImportWarn mod (IEThingAll tc)
636 = sep [ptext SLIT("Module") <+> quotes (pprModule mod) <+> ptext SLIT("exports") <+> quotes (ppr tc),
637 ptext SLIT("with no constructors/class operations;"),
638 ptext SLIT("yet it is imported with a (..)")]
641 = hsep [ ptext SLIT("Unknown module in export list: module"), quotes (pprModule mod)]
643 exportItemErr export_item NotAvailable
644 = sep [ ptext SLIT("Export item not in scope:"), quotes (ppr export_item)]
646 exportItemErr export_item avail
647 = hang (ptext SLIT("Export item not fully in scope:"))
648 4 (vcat [hsep [ptext SLIT("Wanted: "), ppr export_item],
649 hsep [ptext SLIT("Available:"), ppr (ieOcc export_item), pprAvail avail]])
651 availClashErr (occ_name, ((ie1,avail1,_), (ie2,avail2,_)))
652 = hsep [ptext SLIT("The export items"), quotes (ppr ie1), ptext SLIT("and"), quotes (ppr ie2),
653 ptext SLIT("create conflicting exports for"), quotes (ppr occ_name)]
655 dupExportWarn (occ_name, (_,_,times))
656 = hsep [quotes (ppr occ_name),
657 ptext SLIT("mentioned"), speakNTimes (times+1),
658 ptext SLIT("in export list")]
660 dupModuleExport mod times
661 = hsep [ptext SLIT("Module"), quotes (pprModule mod),
662 ptext SLIT("mentioned"), speakNTimes times,
663 ptext SLIT("in export list")]