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 opt_WarnDuplicateExports
18 import HsSyn ( HsModule(..), HsDecl(..), FixityDecl(..), Fixity, Fake, InPat, IE(..), HsTyVar,
19 TyDecl, ClassDecl, InstDecl, DefaultDecl, ImportDecl(..), HsBinds, IfaceSig,
22 import HsImpExp ( ieName )
23 import RdrHsSyn ( RdrNameHsDecl(..), RdrName(..), RdrNameIE(..), SYN_IE(RdrNameImportDecl),
24 SYN_IE(RdrNameHsModule), SYN_IE(RdrNameFixityDecl),
27 import RnHsSyn ( RenamedHsModule(..), RenamedFixityDecl(..) )
28 import RnIfaces ( getInterfaceExports, getDeclBinders, checkUpToDate, recordSlurp )
29 import BasicTypes ( IfaceFlavour(..) )
35 import UniqFM ( UniqFM, emptyUFM, addListToUFM_C, lookupUFM )
36 import Bag ( Bag, bagToList )
37 import Maybes ( maybeToBool, expectJust )
40 import Outputable ( Outputable(..), PprStyle(..) )
41 import Util ( panic, pprTrace, assertPanic, removeDups, cmpPString )
46 %************************************************************************
48 \subsection{Get global names}
50 %************************************************************************
53 getGlobalNames :: RdrNameHsModule
54 -> RnMG (Maybe (ExportEnv, RnEnv, NameSet))
55 -- Nothing <=> no need to recompile
56 -- The NameSet is the set of names that are
57 -- either locally defined,
58 -- or explicitly imported
60 getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
61 = fixRn (\ ~(rec_exp_fn, _) ->
63 -- PROCESS LOCAL DECLS
64 -- Do these *first* so that the correct provenance gets
65 -- into the global name cache.
66 importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails, local_avails) ->
68 -- PROCESS IMPORT DECLS
69 mapAndUnzip3Rn importsFromImportDecl all_imports
70 `thenRn` \ (imp_rn_envs, imp_avails_s, explicit_imports_s) ->
72 -- CHECK FOR EARLY EXIT
73 checkEarlyExit this_mod `thenRn` \ early_exit ->
75 returnRn (junk_exp_fn, Nothing)
79 -- We put the local env second, so that a local provenance
80 -- "wins", even if a module imports itself.
81 foldlRn plusRnEnv emptyRnEnv imp_rn_envs `thenRn` \ imp_rn_env ->
82 plusRnEnv imp_rn_env local_rn_env `thenRn` \ rn_env ->
84 export_avails :: ExportAvails
85 export_avails = foldr plusExportAvails local_mod_avails imp_avails_s
87 explicit_names :: NameSet -- locally defined or explicitly imported
88 explicit_names = foldr add_on emptyNameSet (local_avails : explicit_imports_s)
89 add_on avails names = foldr (unionNameSets . mkNameSet . availNames) names avails
92 -- PROCESS EXPORT LISTS
93 exportsFromAvail this_mod exports export_avails rn_env
94 `thenRn` \ (export_fn, export_env) ->
96 -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
97 mapRn (recordSlurp Nothing Compulsory) local_avails `thenRn_`
99 returnRn (export_fn, Just (export_env, rn_env, explicit_names))
100 ) `thenRn` \ (_, result) ->
103 junk_exp_fn = error "RnNames:export_fn"
105 all_imports = prel_imports ++ imports
107 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
108 -- because the former doesn't even look at Prelude.hi for instance declarations,
109 -- whereas the latter does.
110 prel_imports | this_mod == pRELUDE ||
111 explicit_prelude_import ||
112 opt_NoImplicitPrelude
115 | otherwise = [ImportDecl pRELUDE
116 False {- Not qualified -}
117 HiFile {- Not source imported -}
118 Nothing {- No "as" -}
119 Nothing {- No import list -}
122 explicit_prelude_import
123 = not (null [ () | (ImportDecl mod qual _ _ _ _) <- imports, mod == pRELUDE ])
128 = checkErrsRn `thenRn` \ no_errs_so_far ->
129 if not no_errs_so_far then
130 -- Found errors already, so exit now
133 traceRn (text "Considering whether compilation is required...") `thenRn_`
134 if not opt_SourceUnchanged then
135 -- Source code changed and no errors yet... carry on
136 traceRn (nest 4 (text "source file changed or recompilation check turned off")) `thenRn_`
139 -- Unchanged source, and no errors yet; see if usage info
140 -- up to date, and exit if so
141 checkUpToDate mod `thenRn` \ up_to_date ->
142 putDocRn (text "Compilation" <+>
143 text (if up_to_date then "IS NOT" else "IS") <+>
144 text "required") `thenRn_`
150 importsFromImportDecl :: RdrNameImportDecl
151 -> RnMG (RnEnv, ExportAvails, [AvailInfo])
153 importsFromImportDecl (ImportDecl mod qual_only as_source as_mod import_spec loc)
155 getInterfaceExports mod as_source `thenRn` \ (avails, fixities) ->
156 filterImports mod import_spec avails `thenRn` \ (filtered_avails, hides, explicits) ->
158 filtered_avails' = map set_avail_prov filtered_avails
159 fixities' = [ (occ,(fixity,provenance)) | (occ,fixity) <- fixities ]
162 True -- Want qualified names
163 (not qual_only) -- Maybe want unqualified names
165 (ExportEnv filtered_avails' fixities')
167 `thenRn` \ (rn_env, mod_avails) ->
168 returnRn (rn_env, mod_avails, explicits)
170 set_avail_prov NotAvailable = NotAvailable
171 set_avail_prov (Avail n) = Avail (set_name_prov n)
172 set_avail_prov (AvailTC n ns) = AvailTC (set_name_prov n) (map set_name_prov ns)
173 set_name_prov name | isWiredInName name = name
174 | otherwise = setNameProvenance name provenance
175 provenance = Imported mod loc as_source
180 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
181 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
182 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
184 False -- Don't want qualified names
185 True -- Want unqualified names
186 Nothing -- No "as M" part
187 (ExportEnv avails fixities)
189 `thenRn` \ (rn_env, mod_avails) ->
190 returnRn (rn_env, mod_avails, avails)
192 newLocalName rdr_name loc
193 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
195 getLocalDeclBinders avails (ValD binds)
196 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
197 returnRn (val_avails ++ avails)
199 getLocalDeclBinders avails decl
200 = getDeclBinders newLocalName decl `thenRn` \ avail ->
202 NotAvailable -> returnRn avails -- Instance decls and suchlike
203 other -> returnRn (avail : avails)
205 do_one (rdr_name, loc)
206 = newLocalName rdr_name loc `thenRn` \ name ->
207 returnRn (Avail name)
210 %************************************************************************
212 \subsection{Filtering imports}
214 %************************************************************************
216 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
217 available, and filters it through the import spec (if any).
220 filterImports :: Module
221 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
222 -> [AvailInfo] -- What's available
223 -> RnMG ([AvailInfo], -- What's actually imported
224 [AvailInfo], -- What's to be hidden (the unqualified version, that is)
225 [AvailInfo]) -- What was imported explicitly
227 -- Complains if import spec mentions things that the module doesn't export
228 -- Warns/informs if import spec contains duplicates.
229 filterImports mod Nothing imports
230 = returnRn (imports, [], [])
232 filterImports mod (Just (want_hiding, import_items)) avails
233 = mapRn check_item import_items `thenRn` \ item_avails ->
236 returnRn (avails, item_avails, []) -- All imported; item_avails to be hidden
238 returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
241 import_fm :: FiniteMap OccName AvailInfo
242 import_fm = listToFM [ (nameOccName name, avail)
244 name <- availEntityNames avail]
246 check_item item@(IEModuleContents _)
247 = addErrRn (badImportItemErr mod item) `thenRn_`
248 returnRn NotAvailable
251 | not (maybeToBool maybe_in_import_avails) ||
252 (case filtered_avail of { NotAvailable -> True; other -> False })
253 = addErrRn (badImportItemErr mod item) `thenRn_`
254 returnRn NotAvailable
256 | otherwise = returnRn filtered_avail
259 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
260 Just avail = maybe_in_import_avails
261 filtered_avail = filterAvail item avail
266 %************************************************************************
268 \subsection{Qualifiying imports}
270 %************************************************************************
272 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
273 of an import decl, and deals with producing an @RnEnv@ with the
274 right qualified names. It also turns the @Names@ in the @ExportEnv@ into
275 fully fledged @Names@.
278 qualifyImports :: Module -- Imported module
279 -> Bool -- True <=> want qualified import
280 -> Bool -- True <=> want unqualified import
281 -> Maybe Module -- Optional "as M" part
282 -> ExportEnv -- What's imported
283 -> [AvailInfo] -- What's to be hidden
284 -> RnMG (RnEnv, ExportAvails)
286 qualifyImports this_mod qual_imp unqual_imp as_mod (ExportEnv avails fixities) hides
288 -- Make the name environment. Even though we're talking about a
289 -- single import module there might still be name clashes,
290 -- because it might be the module being compiled.
291 foldlRn add_avail emptyNameEnv avails `thenRn` \ name_env1 ->
293 -- Delete things that are hidden
294 name_env2 = foldl del_avail name_env1 hides
296 -- Create the fixity env
297 fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
299 -- Create the export-availability info
300 export_avails = mkExportAvails unqual_imp qual_mod avails
302 returnRn (RnEnv name_env2 fixity_env, export_avails)
304 qual_mod = case as_mod of
306 Just another_name -> another_name
308 add_avail env avail = foldlRn add_name env (availNames avail)
309 add_name env name = add qual_imp env (Qual qual_mod occ err_hif) `thenRn` \ env1 ->
310 add unqual_imp env1 (Unqual occ)
312 add False env rdr_name = returnRn env
313 add True env rdr_name = addOneToNameEnv env rdr_name name
314 occ = nameOccName name
316 del_avail env avail = foldl delOneFromNameEnv env rdr_names
318 rdr_names = map (Unqual . nameOccName) (availNames avail)
320 add_fixity name_env fix_env (occ_name, (fixity, provenance))
321 = add qual $ add unqual $ fix_env
323 qual = Qual qual_mod occ_name err_hif
324 unqual = Unqual occ_name
326 add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
327 = addOneToFixityEnv fix_env rdr_name (fixity,provenance)
331 err_hif = error "qualifyImports: hif" -- Not needed in key to mapping
334 unQualify adds an Unqual binding for every existing Qual binding.
337 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
338 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ _, elt) <- fmToList fm]
341 %************************************************************************
343 \subsection{Local declarations}
345 %************************************************************************
349 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, Provenance))
351 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
352 = returnRn (rdrNameOcc rdr_name, (fixity, LocalDef (panic "export-flag") loc))
356 %************************************************************************
358 \subsection{Export list processing
360 %************************************************************************
362 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
363 When exporting we need to combine the availabilities for a particular
364 exported thing, and we also need to check for name clashes -- that
365 is: two exported things must have different @OccNames@.
368 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo, Int{-no. of clashes-})
369 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
370 -- for error reporting, as well as to its AvailInfo
372 emptyAvailEnv = emptyFM
375 Add new entry to environment. Checks for name clashes, i.e.,
376 plain duplicates or exported entity pairs that have different OccNames.
377 (c.f. 5.1.1 of Haskell 1.4 report.)
379 addAvailEnv :: Bool -> RdrNameIE -> AvailEnv -> AvailInfo -> RnM s d AvailEnv
380 addAvailEnv warn_dups ie env NotAvailable = returnRn env
381 addAvailEnv warn_dups ie env (AvailTC _ []) = returnRn env
382 addAvailEnv warn_dups ie env avail
383 | warn_dups = mapMaybeRn (addErrRn . availClashErr) () conflict `thenRn_`
384 returnRn (addToFM_C add_avail env key elt)
385 | otherwise = returnRn (addToFM_C add_avail env key elt)
387 key = nameOccName (availName avail)
388 elt = (ie,avail,reports_on)
391 | maybeToBool dup = 1
394 conflict = conflictFM bad_avail env key elt
396 | warn_dups = conflictFM dup_avail env key elt
397 | otherwise = Nothing
399 addListToAvailEnv :: AvailEnv -> RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
400 addListToAvailEnv env ie items = foldlRn (addAvailEnv False ie) env items
402 bad_avail (ie1,avail1,r1) (ie2,avail2,r2)
403 = availName avail1 /= availName avail2 -- Same OccName, different Name
404 dup_avail (ie1,avail1,r1) (ie2,avail2,r2)
405 = availName avail1 == availName avail2 -- Same OccName & avail.
407 add_avail (ie1,a1,r1) (ie2,a2,r2) = (ie1, a1 `plusAvail` a2, r1 + r2)
411 Processing the export list.
413 You might think that we should record things that appear in the export list as
414 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
415 that they are in scope, but there is no need to slurp in their actual declaration
416 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
417 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
418 includes ConcBase.StateAndSynchVar#, and so on...
421 exportsFromAvail :: Module
422 -> Maybe [RdrNameIE] -- Export spec
425 -> RnMG (Name -> ExportFlag, ExportEnv)
426 -- Complains if two distinct exports have same OccName
427 -- Warns about identical exports.
428 -- Complains about exports items not in scope
429 exportsFromAvail this_mod Nothing export_avails rn_env
430 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
432 exportsFromAvail this_mod (Just export_items)
433 (mod_avail_env, entity_avail_env)
434 (RnEnv name_env fixity_env)
435 = checkForModuleExportDups export_items `thenRn` \ export_items' ->
436 foldlRn exports_from_item emptyAvailEnv export_items' `thenRn` \ export_avail_env ->
438 dup_entries = fmToList (filterFM (\ _ (_,_,clashes) -> clashes > 0) export_avail_env)
440 mapRn (addWarnRn . dupExportWarn) dup_entries `thenRn_`
442 export_avails = map (\ (_,a,_) -> a) (eltsFM export_avail_env)
443 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
444 export_fn = mk_export_fn export_avails
446 returnRn (export_fn, ExportEnv export_avails export_fixities)
449 exports_from_item :: AvailEnv -> RdrNameIE -> RnMG AvailEnv
450 exports_from_item export_avail_env ie@(IEModuleContents mod)
451 = case lookupFM mod_avail_env mod of
452 Nothing -> failWithRn export_avail_env (modExportErr mod)
453 Just avails -> addListToAvailEnv export_avail_env ie avails
455 exports_from_item export_avail_env ie
456 | not (maybeToBool maybe_in_scope)
457 = failWithRn export_avail_env (unknownNameErr (ieName ie))
460 -- I can't see why this should ever happen; if the thing is in scope
461 -- at all it ought to have some availability
462 | not (maybeToBool maybe_avail)
463 = pprTrace "exportsFromAvail: curious Nothing:" (ppr PprDebug name)
464 returnRn export_avail_env
468 = failWithRn export_avail_env (exportItemErr ie export_avail)
470 | otherwise -- Phew! It's OK!
471 = addAvailEnv opt_WarnDuplicateExports ie export_avail_env export_avail
473 maybe_in_scope = lookupNameEnv name_env (ieName ie)
474 Just name = maybe_in_scope
475 maybe_avail = lookupUFM entity_avail_env name
476 Just avail = maybe_avail
477 export_avail = filterAvail ie avail
478 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
480 -- We export a fixity iff we export a thing with the same (qualified) RdrName
481 mk_exported_fixities :: NameSet -> [(OccName, (Fixity, Provenance))]
482 mk_exported_fixities exports
483 = fmToList (foldr (perhaps_add_fixity exports)
485 (fmToList fixity_env))
487 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, Provenance))
488 -> FiniteMap OccName (Fixity,Provenance)
489 -> FiniteMap OccName (Fixity,Provenance)
490 perhaps_add_fixity exports (rdr_name, (fixity, prov)) fix_env
492 do_nothing = fix_env -- The default is to pass on the env unchanged
494 -- Step 1: check whether the rdr_name is in scope; if so find its Name
495 case lookupFM name_env rdr_name of {
496 Nothing -> do_nothing;
499 -- Step 2: check whether the fixity thing is exported
500 if not (fixity_name `elemNameSet` exports) then
504 -- Step 3: check whether we already have a fixity for the
505 -- Name's OccName in the fix_env we are building up. This can easily
506 -- happen. the original fixity_env might contain bindings for
507 -- M.a and N.a, if a was imported via M and N.
508 -- If this does happen, we expect the fixity to be the same either way.
510 occ_name = rdrNameOcc rdr_name
512 case lookupFM fix_env occ_name of {
513 Just (fixity1, prov1) -> -- Got it already
514 ASSERT( fixity == fixity1 )
518 -- Step 3: add it to the outgoing fix_env
519 addToFM fix_env occ_name (fixity,prov)
522 {- warn and weed out duplicate module entries from export list. -}
523 checkForModuleExportDups :: [RdrNameIE] -> RnMG [RdrNameIE]
524 checkForModuleExportDups ls
525 | opt_WarnDuplicateExports = check_modules ls
526 | otherwise = returnRn ls
528 -- NOTE: reorders the export list by moving all module-contents
529 -- exports to the end (removing duplicates in the process.)
533 ls -> mapRn (\ ds@(IEModuleContents x:_) ->
534 addWarnRn (dupModuleExport x (length ds))) ls `thenRn_`
535 returnRn ()) `thenRn_`
536 returnRn (ls_no_modules ++ no_module_dups)
538 (ls_no_modules,modules) = foldr split_mods ([],[]) ls
540 split_mods i@(IEModuleContents _) ~(no_ms,ms) = (no_ms,i:ms)
541 split_mods i ~(no_ms,ms) = (i:no_ms,ms)
543 (no_module_dups, dups) = removeDups cmp_mods modules
545 cmp_mods (IEModuleContents m1) (IEModuleContents m2) = m1 `cmpPString` m2
547 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
549 = \name -> if name `elemNameSet` exported_names
553 exported_names :: NameSet
554 exported_names = availsToNameSet avails
557 %************************************************************************
561 %************************************************************************
564 badImportItemErr mod ie sty
565 = sep [ptext SLIT("Module"), pprModule sty mod, ptext SLIT("does not export"), ppr sty ie]
568 = hsep [ ptext SLIT("Unknown module in export list: module"), ptext mod]
570 exportItemErr export_item NotAvailable sty
571 = sep [ ptext SLIT("Export item not in scope:"), ppr sty export_item ]
573 exportItemErr export_item avail sty
574 = hang (ptext SLIT("Export item not fully in scope:"))
575 4 (vcat [hsep [ptext SLIT("Wanted: "), ppr sty export_item],
576 hsep [ptext SLIT("Available:"), ppr sty (ieOcc export_item), pprAvail sty avail]])
578 availClashErr (occ_name, ((ie1,avail1,_), (ie2,avail2,_))) sty
579 = hsep [ptext SLIT("The export items"), ppr sty ie1, ptext SLIT("and"), ppr sty ie2,
580 ptext SLIT("create conflicting exports for"), ppr sty occ_name]
582 dupExportWarn (occ_name, (_,_,times)) sty
583 = hsep [ppr sty occ_name,
584 ptext SLIT("mentioned"), text (speak_times (times+1)),
585 ptext SLIT("in export list")]
587 dupModuleExport mod times sty
588 = hsep [ptext SLIT("Module"), pprModule sty mod,
589 ptext SLIT("mentioned"), text (speak_times times),
590 ptext SLIT("in export list")]
592 speak_times :: Int{- >=1 -} -> String
593 speak_times t | t == 1 = "once"
595 | otherwise = show t ++ " times"