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(..),
19 ForeignDecl(..), ExtName(..), ForKind(..),
23 import RdrHsSyn ( RdrNameHsDecl, RdrName(..), RdrNameIE, RdrNameImportDecl,
24 RdrNameHsModule, RdrNameFixityDecl,
27 import RnIfaces ( getInterfaceExports, getDeclBinders, recordSlurp, checkUpToDate )
28 import BasicTypes ( IfaceFlavour(..) )
34 import UniqFM ( UniqFM, addListToUFM_C, lookupUFM )
35 import Bag ( Bag, bagToList )
36 import Maybes ( maybeToBool )
39 import Util ( removeDups )
44 %************************************************************************
46 \subsection{Get global names}
48 %************************************************************************
51 getGlobalNames :: RdrNameHsModule
52 -> RnMG (Maybe (ExportEnv,
54 FiniteMap Name HowInScope, -- Locally defined or explicitly imported
55 Name -> PrintUnqualified))
56 -- Nothing => no need to recompile
58 getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
59 = fixRn (\ ~(rec_exp_fn, _) ->
61 -- PROCESS LOCAL DECLS
62 -- Do these *first* so that the correct provenance gets
63 -- into the global name cache.
64 importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails, local_info) ->
66 -- PROCESS IMPORT DECLS
67 mapAndUnzip3Rn importsFromImportDecl all_imports
68 `thenRn` \ (imp_rn_envs, imp_avails_s, explicit_imports_s) ->
71 -- We put the local env second, so that a local provenance
72 -- "wins", even if a module imports itself.
73 foldlRn plusRnEnv emptyRnEnv imp_rn_envs `thenRn` \ imp_rn_env ->
74 plusRnEnv imp_rn_env local_rn_env `thenRn` \ rn_env ->
77 -- We can't go for an early exit before this because we have to check
78 -- for name clashes. Consider:
80 -- module A where module B where
84 -- Suppose I've compiled everything up, and then I add a
85 -- new definition to module B, that defines "f".
87 -- Then I must detect the name clash in A before going for an early
88 -- exit. The early-exit code checks what's actually needed from B
89 -- to compile A, and of course that doesn't include B.f. That's
90 -- why we wait till after the plusRnEnv stuff to do the early-exit.
91 checkEarlyExit this_mod `thenRn` \ up_to_date ->
93 returnRn (error "early exit", Nothing)
97 -- PROCESS EXPORT LISTS
99 export_avails :: ExportAvails
100 export_avails = foldr plusExportAvails local_mod_avails imp_avails_s
102 explicit_info :: FiniteMap Name HowInScope -- Locally defined or explicitly imported
103 explicit_info = foldr plusFM local_info explicit_imports_s
105 exportsFromAvail this_mod exports export_avails rn_env
106 `thenRn` \ (export_fn, export_env) ->
108 -- BUILD THE "IMPORT FN". It just tells whether a name is in
109 -- scope in an unqualified form.
111 print_unqual = mkImportFn imp_rn_env
114 returnRn (export_fn, Just (export_env, rn_env, explicit_info, print_unqual))
115 ) `thenRn` \ (_, result) ->
118 junk_exp_fn = error "RnNames:export_fn"
120 all_imports = prel_imports ++ imports
122 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
123 -- because the former doesn't even look at Prelude.hi for instance declarations,
124 -- whereas the latter does.
125 prel_imports | this_mod == pRELUDE ||
126 explicit_prelude_import ||
127 opt_NoImplicitPrelude
130 | otherwise = [ImportDecl pRELUDE
131 False {- Not qualified -}
132 HiFile {- Not source imported -}
133 Nothing {- No "as" -}
134 Nothing {- No import list -}
137 explicit_prelude_import
138 = not (null [ () | (ImportDecl mod qual _ _ _ _) <- imports, mod == pRELUDE ])
143 = checkErrsRn `thenRn` \ no_errs_so_far ->
144 if not no_errs_so_far then
145 -- Found errors already, so exit now
149 traceRn (text "Considering whether compilation is required...") `thenRn_`
150 if not opt_SourceUnchanged then
151 -- Source code changed and no errors yet... carry on
152 traceRn (nest 4 (text "source file changed or recompilation check turned off")) `thenRn_`
156 -- Unchanged source, and no errors yet; see if usage info
157 -- up to date, and exit if so
158 checkUpToDate mod `thenRn` \ up_to_date ->
159 putDocRn (text "Compilation" <+>
160 text (if up_to_date then "IS NOT" else "IS") <+>
161 text "required") `thenRn_`
166 importsFromImportDecl :: RdrNameImportDecl
169 FiniteMap Name HowInScope) -- Records the explicitly-imported things
171 importsFromImportDecl (ImportDecl mod qual_only as_source as_mod import_spec loc)
173 getInterfaceExports mod as_source `thenRn` \ (avails, fixities) ->
174 filterImports mod import_spec avails `thenRn` \ (filtered_avails, hides, explicits) ->
176 how_in_scope = FromImportDecl mod loc
177 explicit_info = listToFM [(name, how_in_scope)
178 | avail <- explicits,
179 name <- availNames avail
183 True -- Want qualified names
184 (not qual_only) -- Maybe want unqualified names
187 filtered_avails (\n -> how_in_scope)
188 [ (occ,(fixity,how_in_scope)) | (occ,fixity) <- fixities ]
189 `thenRn` \ (rn_env, mod_avails) ->
190 returnRn (rn_env, mod_avails, explicit_info)
195 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
196 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
198 -- Record that locally-defined things are available
199 mapRn (recordSlurp Nothing Compulsory) avails `thenRn_`
202 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
204 -- Record where the available stuff came from
206 explicit_info = listToFM [(name, FromLocalDefn (getSrcLoc name))
208 name <- availNames avail
212 False -- Don't want qualified names
213 True -- Want unqualified names
214 Nothing -- No "as M" part
216 avails (\n -> FromLocalDefn (getSrcLoc n))
218 `thenRn` \ (rn_env, mod_avails) ->
219 returnRn (rn_env, mod_avails, explicit_info)
221 newLocalName rdr_name loc
222 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
224 getLocalDeclBinders avails (ValD binds)
225 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
226 returnRn (val_avails ++ avails)
228 -- foreign import declaration
229 getLocalDeclBinders avails (ForD (ForeignDecl nm (FoImport _) _ _ _ loc))
230 = do_one (nm,loc) `thenRn` \ for_avail ->
231 returnRn (for_avail : avails)
233 -- foreign import declaration
234 getLocalDeclBinders avails (ForD (ForeignDecl nm FoLabel _ _ _ loc))
235 = do_one (nm,loc) `thenRn` \ for_avail ->
236 returnRn (for_avail : avails)
238 -- foreign export dynamic declaration
239 getLocalDeclBinders avails (ForD (ForeignDecl nm FoExport _ Dynamic _ loc))
240 = do_one (nm,loc) `thenRn` \ for_avail ->
241 returnRn (for_avail : avails)
243 getLocalDeclBinders avails decl
244 = getDeclBinders newLocalName decl `thenRn` \ avail ->
246 NotAvailable -> returnRn avails -- Instance decls and suchlike
247 other -> returnRn (avail : avails)
249 do_one (rdr_name, loc)
250 = newLocalName rdr_name loc `thenRn` \ name ->
251 returnRn (Avail name)
254 %************************************************************************
256 \subsection{Filtering imports}
258 %************************************************************************
260 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
261 available, and filters it through the import spec (if any).
264 filterImports :: Module
265 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
266 -> [AvailInfo] -- What's available
267 -> RnMG ([AvailInfo], -- What's actually imported
268 [AvailInfo], -- What's to be hidden (the unqualified version, that is)
269 [AvailInfo]) -- What was imported explicitly
271 -- Complains if import spec mentions things that the module doesn't export
272 -- Warns/informs if import spec contains duplicates.
273 filterImports mod Nothing imports
274 = returnRn (imports, [], [])
276 filterImports mod (Just (want_hiding, import_items)) avails
277 = mapRn check_item import_items `thenRn` \ item_avails ->
280 returnRn (avails, item_avails, []) -- All imported; item_avails to be hidden
282 returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
285 import_fm :: FiniteMap OccName AvailInfo
286 import_fm = listToFM [ (nameOccName name, avail)
288 name <- availEntityNames avail]
290 check_item item@(IEModuleContents _)
291 = addErrRn (badImportItemErr mod item) `thenRn_`
292 returnRn NotAvailable
295 | not (maybeToBool maybe_in_import_avails) ||
296 (case filtered_avail of { NotAvailable -> True; other -> False })
297 = addErrRn (badImportItemErr mod item) `thenRn_`
298 returnRn NotAvailable
300 | dodgy_import = addWarnRn (dodgyImportWarn mod item) `thenRn_`
301 returnRn filtered_avail
303 | otherwise = returnRn filtered_avail
306 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
307 Just avail = maybe_in_import_avails
308 filtered_avail = filterAvail item avail
309 dodgy_import = case (item, avail) of
310 (IEThingAll _, AvailTC _ [n]) -> True
311 -- This occurs when you import T(..), but
312 -- only export T abstractly. The single [n]
313 -- in the AvailTC is the type or class itself
321 %************************************************************************
323 \subsection{Qualifiying imports}
325 %************************************************************************
327 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
328 of an import decl, and deals with producing an @RnEnv@ with the
329 right qualified names. It also turns the @Names@ in the @ExportEnv@ into
330 fully fledged @Names@.
333 qualifyImports :: Module -- Imported module
334 -> Bool -- True <=> want qualified import
335 -> Bool -- True <=> want unqualified import
336 -> Maybe Module -- Optional "as M" part
337 -> [AvailInfo] -- What's to be hidden
338 -> Avails -> (Name -> HowInScope) -- Whats imported and how
339 -> [(OccName, (Fixity, HowInScope))] -- Ditto for fixities
340 -> RnMG (RnEnv, ExportAvails)
342 qualifyImports this_mod qual_imp unqual_imp as_mod hides
343 avails name_to_his fixities
345 -- Make the name environment. Even though we're talking about a
346 -- single import module there might still be name clashes,
347 -- because it might be the module being compiled.
348 foldlRn add_avail emptyGlobalNameEnv avails `thenRn` \ name_env1 ->
350 -- Delete things that are hidden
351 name_env2 = foldl del_avail name_env1 hides
353 -- Create the fixity env
354 fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
356 -- Create the export-availability info
357 export_avails = mkExportAvails qual_mod unqual_imp name_env2 avails
359 returnRn (RnEnv name_env2 fixity_env, export_avails)
361 qual_mod = case as_mod of
363 Just another_name -> another_name
365 add_avail :: GlobalNameEnv -> AvailInfo -> RnMG GlobalNameEnv
366 add_avail env avail = foldlRn add_name env (availNames avail)
368 add_name env name = add qual_imp env (Qual qual_mod occ err_hif) `thenRn` \ env1 ->
369 add unqual_imp env1 (Unqual occ)
371 add False env rdr_name = returnRn env
372 add True env rdr_name = addOneToGlobalNameEnv env rdr_name (name, name_to_his name)
373 occ = nameOccName name
375 del_avail env avail = foldl delOneFromGlobalNameEnv env rdr_names
377 rdr_names = map (Unqual . nameOccName) (availNames avail)
379 add_fixity name_env fix_env (occ_name, fixity)
380 = add qual $ add unqual $ fix_env
382 qual = Qual qual_mod occ_name err_hif
383 unqual = Unqual occ_name
385 add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
386 = addOneToFixityEnv fix_env rdr_name fixity
390 err_hif = error "qualifyImports: hif" -- Not needed in key to mapping
393 unQualify adds an Unqual binding for every existing Qual binding.
396 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
397 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ _, elt) <- fmToList fm]
400 %************************************************************************
402 \subsection{Local declarations}
404 %************************************************************************
408 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, HowInScope))
410 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
411 = returnRn (rdrNameOcc rdr_name, (fixity, FromLocalDefn loc))
415 %************************************************************************
417 \subsection{Export list processing
419 %************************************************************************
421 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
422 When exporting we need to combine the availabilities for a particular
423 exported thing, and we also need to check for name clashes -- that
424 is: two exported things must have different @OccNames@.
427 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo, Int{-no. of clashes-})
428 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
429 -- for error reporting, as well as to its AvailInfo
431 emptyAvailEnv = emptyFM
434 Add new entry to environment. Checks for name clashes, i.e.,
435 plain duplicates or exported entity pairs that have different OccNames.
436 (c.f. 5.1.1 of Haskell 1.4 report.)
438 addAvailEnv :: Bool -> RdrNameIE -> AvailEnv -> AvailInfo -> RnM s d AvailEnv
439 addAvailEnv warn_dups ie env NotAvailable = returnRn env
440 addAvailEnv warn_dups ie env (AvailTC _ []) = returnRn env
441 addAvailEnv warn_dups ie env avail
442 | warn_dups = mapMaybeRn (addErrRn . availClashErr) () conflict `thenRn_`
443 returnRn (addToFM_C addAvail env key elt)
444 | otherwise = returnRn (addToFM_C addAvail env key elt)
446 occ_avail = nameOccName (availName avail)
449 | not warn_dups || occ_ie == occ_avail = occ_avail
451 -- export item is a class method, use export occ name instead.
452 -- (this is only needed to get more precise warnings about
454 elt = (ie,avail,reports_on)
457 | maybeToBool dup = 1
460 conflict = conflictFM bad_avail env key elt
462 | warn_dups = conflictFM dup_avail env key elt
463 | otherwise = Nothing
465 addListToAvailEnv :: AvailEnv -> RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
466 addListToAvailEnv env ie items
467 = foldlRn (addAvailEnv False{-don't warn about dups-} ie) env items
469 bad_avail (ie1,avail1,r1) (ie2,avail2,r2)
470 = availName avail1 /= availName avail2 -- Same OccName, different Name
471 dup_avail (ie1,avail1,r1) (ie2,avail2,r2)
472 = availName avail1 == availName avail2 -- Same OccName & avail.
474 addAvail (ie1,a1,r1) (ie2,a2,r2) = (ie1, a1 `plusAvail` a2, r1 + r2)
477 Processing the export list.
479 You might think that we should record things that appear in the export list as
480 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
481 that they are in scope, but there is no need to slurp in their actual declaration
482 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
483 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
484 includes ConcBase.StateAndSynchVar#, and so on...
487 exportsFromAvail :: Module
488 -> Maybe [RdrNameIE] -- Export spec
491 -> RnMG (Name -> ExportFlag, ExportEnv)
492 -- Complains if two distinct exports have same OccName
493 -- Warns about identical exports.
494 -- Complains about exports items not in scope
495 exportsFromAvail this_mod Nothing export_avails rn_env
496 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
498 exportsFromAvail this_mod (Just export_items)
499 (mod_avail_env, entity_avail_env)
500 (RnEnv global_name_env fixity_env)
501 = checkForModuleExportDups export_items `thenRn` \ export_items' ->
502 foldlRn exports_from_item emptyAvailEnv export_items' `thenRn` \ export_avail_env ->
504 dup_entries = fmToList (filterFM (\ _ (_,_,clashes) -> clashes > 0) export_avail_env)
506 mapRn (addWarnRn . dupExportWarn) dup_entries `thenRn_`
508 export_avails = map (\ (_,a,_) -> a) (eltsFM export_avail_env)
509 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
510 export_fn = mk_export_fn export_avails
512 returnRn (export_fn, ExportEnv export_avails export_fixities)
515 exports_from_item :: AvailEnv -> RdrNameIE -> RnMG AvailEnv
516 exports_from_item export_avail_env ie@(IEModuleContents mod)
517 = case lookupFM mod_avail_env mod of
518 Nothing -> failWithRn export_avail_env (modExportErr mod)
519 Just avails -> addListToAvailEnv export_avail_env ie avails
521 exports_from_item export_avail_env ie
522 | not (maybeToBool maybe_in_scope)
523 = failWithRn export_avail_env (unknownNameErr (ieName ie))
526 -- I can't see why this should ever happen; if the thing is in scope
527 -- at all it ought to have some availability
528 | not (maybeToBool maybe_avail)
529 = pprTrace "exportsFromAvail: curious Nothing:" (ppr name)
530 returnRn export_avail_env
534 = failWithRn export_avail_env (exportItemErr ie export_avail)
536 | otherwise -- Phew! It's OK!
537 = addAvailEnv opt_WarnDuplicateExports ie export_avail_env export_avail
539 maybe_in_scope = lookupFM global_name_env (ieName ie)
540 Just (name,_) = maybe_in_scope
541 maybe_avail = lookupUFM entity_avail_env name
542 Just avail = maybe_avail
543 export_avail = filterAvail ie avail
544 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
546 -- We export a fixity iff we export a thing with the same (qualified) RdrName
547 mk_exported_fixities :: NameSet -> [(OccName, Fixity)]
548 mk_exported_fixities exports
549 = fmToList (foldr (perhaps_add_fixity exports)
551 (fmToList fixity_env))
553 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, HowInScope))
554 -> FiniteMap OccName Fixity
555 -> FiniteMap OccName Fixity
556 perhaps_add_fixity exports (rdr_name, (fixity, how_in_scope)) fix_env
558 do_nothing = fix_env -- The default is to pass on the env unchanged
560 -- Step 1: check whether the rdr_name is in scope; if so find its Name
561 case lookupFM global_name_env rdr_name of {
562 Nothing -> do_nothing;
563 Just (fixity_name,_) ->
565 -- Step 2: check whether the fixity thing is exported
566 if not (fixity_name `elemNameSet` exports) then
570 -- Step 3: check whether we already have a fixity for the
571 -- Name's OccName in the fix_env we are building up. This can easily
572 -- happen. the original fixity_env might contain bindings for
573 -- M.a and N.a, if a was imported via M and N.
574 -- If this does happen, we expect the fixity to be the same either way.
576 occ_name = rdrNameOcc rdr_name
578 case lookupFM fix_env occ_name of {
579 Just fixity1 -> -- Got it already
580 ASSERT( fixity == fixity1 )
584 -- Step 3: add it to the outgoing fix_env
585 addToFM fix_env occ_name fixity
588 {- warn and weed out duplicate module entries from export list. -}
589 checkForModuleExportDups :: [RdrNameIE] -> RnMG [RdrNameIE]
590 checkForModuleExportDups ls
591 | opt_WarnDuplicateExports = check_modules ls
592 | otherwise = returnRn ls
594 -- NOTE: reorders the export list by moving all module-contents
595 -- exports to the end (removing duplicates in the process.)
599 ls -> mapRn (\ ds@(IEModuleContents x:_) ->
600 addWarnRn (dupModuleExport x (length ds))) ls `thenRn_`
601 returnRn ()) `thenRn_`
602 returnRn (ls_no_modules ++ no_module_dups)
604 (ls_no_modules,modules) = foldr split_mods ([],[]) ls
606 split_mods i@(IEModuleContents _) (no_ms,ms) = (no_ms,i:ms)
607 split_mods i (no_ms,ms) = (i:no_ms,ms)
609 (no_module_dups, dups) = removeDups cmp_mods modules
611 cmp_mods (IEModuleContents m1) (IEModuleContents m2) = m1 `compare` m2
613 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
615 = \name -> if name `elemNameSet` exported_names
619 exported_names :: NameSet
620 exported_names = availsToNameSet avails
623 %************************************************************************
627 %************************************************************************
630 badImportItemErr mod ie
631 = sep [ptext SLIT("Module"), quotes (pprModule mod),
632 ptext SLIT("does not export"), quotes (ppr ie)]
634 dodgyImportWarn mod (IEThingAll tc)
635 = sep [ptext SLIT("Module") <+> quotes (pprModule mod) <+> ptext SLIT("exports") <+> quotes (ppr tc),
636 ptext SLIT("with no constructors/class operations;"),
637 ptext SLIT("yet it is imported with a (..)")]
640 = hsep [ ptext SLIT("Unknown module in export list: module"), quotes (pprModule mod)]
642 exportItemErr export_item NotAvailable
643 = sep [ ptext SLIT("Export item not in scope:"), quotes (ppr export_item)]
645 exportItemErr export_item avail
646 = hang (ptext SLIT("Export item not fully in scope:"))
647 4 (vcat [hsep [ptext SLIT("Wanted: "), ppr export_item],
648 hsep [ptext SLIT("Available:"), ppr (ieOcc export_item), pprAvail avail]])
650 availClashErr (occ_name, ((ie1,avail1,_), (ie2,avail2,_)))
651 = hsep [ptext SLIT("The export items"), quotes (ppr ie1), ptext SLIT("and"), quotes (ppr ie2),
652 ptext SLIT("create conflicting exports for"), quotes (ppr occ_name)]
654 dupExportWarn (occ_name, (_,_,times))
655 = hsep [quotes (ppr occ_name),
656 ptext SLIT("mentioned"), speakNTimes (times+1),
657 ptext SLIT("in export list")]
659 dupModuleExport mod times
660 = hsep [ptext SLIT("Module"), quotes (pprModule mod),
661 ptext SLIT("mentioned"), speakNTimes times,
662 ptext SLIT("in export list")]