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 import HsSyn ( HsModule(..), HsDecl(..), FixityDecl(..), Fixity, Fake, InPat, IE(..), HsTyVar,
17 TyDecl, ClassDecl, InstDecl, DefaultDecl, ImportDecl(..), HsBinds, IfaceSig,
20 import HsImpExp ( ieName )
21 import RdrHsSyn ( RdrNameHsDecl(..), RdrName(..), RdrNameIE(..), SYN_IE(RdrNameImportDecl),
22 SYN_IE(RdrNameHsModule), SYN_IE(RdrNameFixityDecl),
25 import RnHsSyn ( RenamedHsModule(..), RenamedFixityDecl(..) )
26 import RnIfaces ( getInterfaceExports, getDeclBinders, checkUpToDate, recordSlurp )
27 import BasicTypes ( IfaceFlavour(..) )
32 import UniqFM ( UniqFM, emptyUFM, addListToUFM_C, lookupUFM )
33 import Bag ( Bag, bagToList )
34 import Maybes ( maybeToBool, expectJust )
37 import Outputable ( Outputable(..), PprStyle(..) )
38 import Util ( panic, pprTrace, assertPanic )
43 %************************************************************************
45 \subsection{Get global names}
47 %************************************************************************
50 getGlobalNames :: RdrNameHsModule
51 -> RnMG (Maybe (ExportEnv, RnEnv, NameSet))
52 -- Nothing <=> no need to recompile
53 -- The NameSet is the set of names that are
54 -- either locally defined,
55 -- or explicitly imported
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) ->
69 -- CHECK FOR EARLY EXIT
70 checkEarlyExit this_mod `thenRn` \ early_exit ->
72 returnRn (junk_exp_fn, Nothing)
76 -- We put the local env second, so that a local provenance
77 -- "wins", even if a module imports itself.
78 foldlRn plusRnEnv emptyRnEnv imp_rn_envs `thenRn` \ imp_rn_env ->
79 plusRnEnv imp_rn_env local_rn_env `thenRn` \ rn_env ->
81 export_avails :: ExportAvails
82 export_avails = foldr plusExportAvails local_mod_avails imp_avails_s
84 explicit_names :: NameSet -- locally defined or explicitly imported
85 explicit_names = foldr add_on emptyNameSet (local_avails : explicit_imports_s)
86 add_on avails names = foldr (unionNameSets . mkNameSet . availNames) names avails
89 -- PROCESS EXPORT LISTS
90 exportsFromAvail this_mod exports export_avails rn_env
91 `thenRn` \ (export_fn, export_env) ->
93 -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
94 mapRn (recordSlurp Nothing Compulsory) local_avails `thenRn_`
96 returnRn (export_fn, Just (export_env, rn_env, explicit_names))
97 ) `thenRn` \ (_, result) ->
100 junk_exp_fn = error "RnNames:export_fn"
102 all_imports = prel_imports ++ imports
104 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
105 -- because the former doesn't even look at Prelude.hi for instance declarations,
106 -- whereas the latter does.
107 prel_imports | this_mod == pRELUDE ||
108 explicit_prelude_import ||
109 opt_NoImplicitPrelude
112 | otherwise = [ImportDecl pRELUDE
113 False {- Not qualified -}
114 HiFile {- Not source imported -}
115 Nothing {- No "as" -}
116 Nothing {- No import list -}
119 explicit_prelude_import
120 = not (null [ () | (ImportDecl mod qual _ _ _ _) <- imports, mod == pRELUDE ])
125 = checkErrsRn `thenRn` \ no_errs_so_far ->
126 if not no_errs_so_far then
127 -- Found errors already, so exit now
130 traceRn (text "Considering whether compilation is required...") `thenRn_`
131 if not opt_SourceUnchanged then
132 -- Source code changed and no errors yet... carry on
133 traceRn (nest 4 (text "source file changed or recompilation check turned off")) `thenRn_`
136 -- Unchanged source, and no errors yet; see if usage info
137 -- up to date, and exit if so
138 checkUpToDate mod `thenRn` \ up_to_date ->
139 putDocRn (text "Compilation" <+>
140 text (if up_to_date then "IS NOT" else "IS") <+>
141 text "required") `thenRn_`
147 importsFromImportDecl :: RdrNameImportDecl
148 -> RnMG (RnEnv, ExportAvails, [AvailInfo])
150 importsFromImportDecl (ImportDecl mod qual_only as_source as_mod import_spec loc)
152 getInterfaceExports mod as_source `thenRn` \ (avails, fixities) ->
153 filterImports mod import_spec avails `thenRn` \ (filtered_avails, hides, explicits) ->
155 filtered_avails' = map set_avail_prov filtered_avails
156 fixities' = [ (occ,(fixity,provenance)) | (occ,fixity) <- fixities ]
159 True -- Want qualified names
160 (not qual_only) -- Maybe want unqualified names
162 (ExportEnv filtered_avails' fixities')
164 `thenRn` \ (rn_env, mod_avails) ->
165 returnRn (rn_env, mod_avails, explicits)
167 set_avail_prov NotAvailable = NotAvailable
168 set_avail_prov (Avail n) = Avail (set_name_prov n)
169 set_avail_prov (AvailTC n ns) = AvailTC (set_name_prov n) (map set_name_prov ns)
170 set_name_prov name | isWiredInName name = name
171 | otherwise = setNameProvenance name provenance
172 provenance = Imported mod loc as_source
177 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
178 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
179 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
181 False -- Don't want qualified names
182 True -- Want unqualified names
183 Nothing -- No "as M" part
184 (ExportEnv avails fixities)
186 `thenRn` \ (rn_env, mod_avails) ->
187 returnRn (rn_env, mod_avails, avails)
189 newLocalName rdr_name loc
190 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
192 getLocalDeclBinders avails (ValD binds)
193 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
194 returnRn (val_avails ++ avails)
196 getLocalDeclBinders avails decl
197 = getDeclBinders newLocalName decl `thenRn` \ avail ->
199 NotAvailable -> returnRn avails -- Instance decls and suchlike
200 other -> returnRn (avail : avails)
202 do_one (rdr_name, loc)
203 = newLocalName rdr_name loc `thenRn` \ name ->
204 returnRn (Avail name)
207 %************************************************************************
209 \subsection{Filtering imports}
211 %************************************************************************
213 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
214 available, and filters it through the import spec (if any).
217 filterImports :: Module
218 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
219 -> [AvailInfo] -- What's available
220 -> RnMG ([AvailInfo], -- What's actually imported
221 [AvailInfo], -- What's to be hidden (the unqualified version, that is)
222 [AvailInfo]) -- What was imported explicitly
224 -- Complains if import spec mentions things that the module doesn't export
226 filterImports mod Nothing imports
227 = returnRn (imports, [], [])
229 filterImports mod (Just (want_hiding, import_items)) avails
230 = mapRn check_item import_items `thenRn` \ item_avails ->
233 returnRn (avails, item_avails, []) -- All imported; item_avails to be hidden
235 returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
238 import_fm :: FiniteMap OccName AvailInfo
239 import_fm = listToFM [ (nameOccName name, avail)
241 name <- availEntityNames avail]
243 check_item item@(IEModuleContents _)
244 = addErrRn (badImportItemErr mod item) `thenRn_`
245 returnRn NotAvailable
248 | not (maybeToBool maybe_in_import_avails) ||
249 (case filtered_avail of { NotAvailable -> True; other -> False })
250 = addErrRn (badImportItemErr mod item) `thenRn_`
251 returnRn NotAvailable
253 | otherwise = returnRn filtered_avail
256 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
257 Just avail = maybe_in_import_avails
258 filtered_avail = filterAvail item avail
263 %************************************************************************
265 \subsection{Qualifiying imports}
267 %************************************************************************
269 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
270 of an import decl, and deals with producing an @RnEnv@ with the
271 right qualified names. It also turns the @Names@ in the @ExportEnv@ into
272 fully fledged @Names@.
275 qualifyImports :: Module -- Imported module
276 -> Bool -- True <=> want qualified import
277 -> Bool -- True <=> want unqualified import
278 -> Maybe Module -- Optional "as M" part
279 -> ExportEnv -- What's imported
280 -> [AvailInfo] -- What's to be hidden
281 -> RnMG (RnEnv, ExportAvails)
283 qualifyImports this_mod qual_imp unqual_imp as_mod (ExportEnv avails fixities) hides
285 -- Make the name environment. Even though we're talking about a
286 -- single import module there might still be name clashes,
287 -- because it might be the module being compiled.
288 foldlRn add_avail emptyNameEnv avails `thenRn` \ name_env1 ->
290 -- Delete things that are hidden
291 name_env2 = foldl del_avail name_env1 hides
293 -- Create the fixity env
294 fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
296 -- Create the export-availability info
297 export_avails = mkExportAvails unqual_imp qual_mod avails
299 returnRn (RnEnv name_env2 fixity_env, export_avails)
301 qual_mod = case as_mod of
303 Just another_name -> another_name
305 add_avail env avail = foldlRn add_name env (availNames avail)
306 add_name env name = add qual_imp env (Qual qual_mod occ err_hif) `thenRn` \ env1 ->
307 add unqual_imp env1 (Unqual occ)
309 add False env rdr_name = returnRn env
310 add True env rdr_name = addOneToNameEnv env rdr_name name
311 occ = nameOccName name
313 del_avail env avail = foldl delOneFromNameEnv env rdr_names
315 rdr_names = map (Unqual . nameOccName) (availNames avail)
317 add_fixity name_env fix_env (occ_name, (fixity, provenance))
318 = add qual $ add unqual $ fix_env
320 qual = Qual qual_mod occ_name err_hif
321 unqual = Unqual occ_name
323 add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
324 = addOneToFixityEnv fix_env rdr_name (fixity,provenance)
328 err_hif = error "qualifyImports: hif" -- Not needed in key to mapping
331 unQualify adds an Unqual binding for every existing Qual binding.
334 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
335 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ _, elt) <- fmToList fm]
338 %************************************************************************
340 \subsection{Local declarations}
342 %************************************************************************
346 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, Provenance))
348 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
349 = returnRn (rdrNameOcc rdr_name, (fixity, LocalDef (panic "export-flag") loc))
353 %************************************************************************
355 \subsection{Export list processing
357 %************************************************************************
359 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
360 When exporting we need to combine the availabilities for a particular
361 exported thing, and we also need to check for name clashes -- that
362 is: two exported things must have different @OccNames@.
365 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo)
366 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
367 -- for error reporting, as well as to its AvailInfo
369 emptyAvailEnv = emptyFM
371 unitAvailEnv :: RdrNameIE -> AvailInfo -> AvailEnv
372 unitAvailEnv ie NotAvailable = emptyFM
373 unitAvailEnv ie (AvailTC _ []) = emptyFM
374 unitAvailEnv ie avail = unitFM (nameOccName (availName avail)) (ie,avail)
377 = mapRn (addErrRn.availClashErr) (conflictsFM bad_avail a1 a2) `thenRn_`
378 returnRn (plusFM_C plus_avail a1 a2)
380 listToAvailEnv :: RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
381 listToAvailEnv ie items
382 = foldlRn plusAvailEnv emptyAvailEnv (map (unitAvailEnv ie) items)
384 bad_avail (ie1,avail1) (ie2,avail2) = availName avail1 /= availName avail2 -- Same OccName, different Name
385 plus_avail (ie1,a1) (ie2,a2) = (ie1, a1 `plusAvail` a2)
388 Processing the export list.
390 You might think that we should record things that appear in the export list as
391 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
392 that they are in scope, but there is no need to slurp in their actual declaration
393 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
394 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
395 includes ConcBase.StateAndSynchVar#, and so on...
398 exportsFromAvail :: Module
399 -> Maybe [RdrNameIE] -- Export spec
402 -> RnMG (Name -> ExportFlag, ExportEnv)
403 -- Complains if two distinct exports have same OccName
404 -- Complains about exports items not in scope
405 exportsFromAvail this_mod Nothing export_avails rn_env
406 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
408 exportsFromAvail this_mod (Just export_items)
409 (mod_avail_env, entity_avail_env)
410 (RnEnv name_env fixity_env)
411 = mapRn exports_from_item export_items `thenRn` \ avail_envs ->
412 foldlRn plusAvailEnv emptyAvailEnv avail_envs `thenRn` \ export_avail_env ->
414 export_avails = map snd (eltsFM export_avail_env)
415 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
416 export_fn = mk_export_fn export_avails
418 returnRn (export_fn, ExportEnv export_avails export_fixities)
421 exports_from_item :: RdrNameIE -> RnMG AvailEnv
422 exports_from_item ie@(IEModuleContents mod)
423 = case lookupFM mod_avail_env mod of
424 Nothing -> failWithRn emptyAvailEnv (modExportErr mod)
425 Just avails -> listToAvailEnv ie avails
428 | not (maybeToBool maybe_in_scope)
429 = failWithRn emptyAvailEnv (unknownNameErr (ieName ie))
432 -- I can't see why this should ever happen; if the thing is in scope
433 -- at all it ought to have some availability
434 | not (maybeToBool maybe_avail)
435 = pprTrace "exportsFromAvail: curious Nothing:" (ppr PprDebug name)
436 returnRn emptyAvailEnv
440 = failWithRn emptyAvailEnv (exportItemErr ie export_avail)
442 | otherwise -- Phew! It's OK!
443 = returnRn (unitAvailEnv ie export_avail)
445 maybe_in_scope = lookupNameEnv name_env (ieName ie)
446 Just name = maybe_in_scope
447 maybe_avail = lookupUFM entity_avail_env name
448 Just avail = maybe_avail
449 export_avail = filterAvail ie avail
450 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
452 -- We export a fixity iff we export a thing with the same (qualified) RdrName
453 mk_exported_fixities :: NameSet -> [(OccName, (Fixity, Provenance))]
454 mk_exported_fixities exports
455 = fmToList (foldr (perhaps_add_fixity exports)
457 (fmToList fixity_env))
459 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, Provenance))
460 -> FiniteMap OccName (Fixity,Provenance)
461 -> FiniteMap OccName (Fixity,Provenance)
462 perhaps_add_fixity exports (rdr_name, (fixity, prov)) fix_env
464 do_nothing = fix_env -- The default is to pass on the env unchanged
466 -- Step 1: check whether the rdr_name is in scope; if so find its Name
467 case lookupFM name_env rdr_name of {
468 Nothing -> do_nothing;
471 -- Step 2: check whether the fixity thing is exported
472 if not (fixity_name `elemNameSet` exports) then
476 -- Step 3: check whether we already have a fixity for the
477 -- Name's OccName in the fix_env we are building up. This can easily
478 -- happen. the original fixity_env might contain bindings for
479 -- M.a and N.a, if a was imported via M and N.
480 -- If this does happen, we expect the fixity to be the same either way.
482 occ_name = rdrNameOcc rdr_name
484 case lookupFM fix_env occ_name of {
485 Just (fixity1, prov1) -> -- Got it already
486 ASSERT( fixity == fixity1 )
490 -- Step 3: add it to the outgoing fix_env
491 addToFM fix_env occ_name (fixity,prov)
494 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
496 = \name -> if name `elemNameSet` exported_names
500 exported_names :: NameSet
501 exported_names = availsToNameSet avails
505 %************************************************************************
509 %************************************************************************
512 badImportItemErr mod ie sty
513 = sep [ptext SLIT("Module"), pprModule sty mod, ptext SLIT("does not export"), ppr sty ie]
516 = hsep [ ptext SLIT("Unknown module in export list: module"), ptext mod]
518 exportItemErr export_item NotAvailable sty
519 = sep [ ptext SLIT("Export item not in scope:"), ppr sty export_item ]
521 exportItemErr export_item avail sty
522 = hang (ptext SLIT("Export item not fully in scope:"))
523 4 (vcat [hsep [ptext SLIT("Wanted: "), ppr sty export_item],
524 hsep [ptext SLIT("Available:"), ppr sty (ieOcc export_item), pprAvail sty avail]])
526 availClashErr (occ_name, ((ie1,avail1), (ie2,avail2))) sty
527 = hsep [ptext SLIT("The export items"), ppr sty ie1, ptext SLIT("and"), ppr sty ie2,
528 ptext SLIT("create conflicting exports for"), ppr sty occ_name]