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 )
31 import UniqFM ( UniqFM, emptyUFM, addListToUFM_C, lookupUFM )
32 import Bag ( Bag, bagToList )
33 import Maybes ( maybeToBool, expectJust )
36 import Outputable ( Outputable(..), PprStyle(..) )
37 import Util ( panic, pprTrace, assertPanic )
42 %************************************************************************
44 \subsection{Get global names}
46 %************************************************************************
49 getGlobalNames :: RdrNameHsModule
50 -> RnMG (Maybe (ExportEnv, RnEnv, NameSet))
51 -- Nothing <=> no need to recompile
52 -- The NameSet is the set of names that are
53 -- either locally defined,
54 -- or explicitly imported
56 getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
57 = fixRn (\ ~(rec_exp_fn, _) ->
59 -- PROCESS LOCAL DECLS
60 -- Do these *first* so that the correct provenance gets
61 -- into the global name cache.
62 importsFromLocalDecls rec_exp_fn m `thenRn` \ (local_rn_env, local_mod_avails, local_avails) ->
64 -- PROCESS IMPORT DECLS
65 mapAndUnzip3Rn importsFromImportDecl all_imports
66 `thenRn` \ (imp_rn_envs, imp_avails_s, explicit_imports_s) ->
68 -- CHECK FOR EARLY EXIT
69 checkEarlyExit this_mod `thenRn` \ early_exit ->
71 returnRn (junk_exp_fn, Nothing)
75 -- We put the local env first, so that a local provenance
76 -- "wins", even if a module imports itself.
77 foldlRn plusRnEnv emptyRnEnv imp_rn_envs `thenRn` \ imp_rn_env ->
78 plusRnEnv local_rn_env imp_rn_env `thenRn` \ rn_env ->
80 all_avails :: ModuleAvails
81 all_avails = foldr plusModuleAvails local_mod_avails imp_avails_s
83 explicit_names :: NameSet -- locally defined or explicitly imported
84 explicit_names = foldr add_on emptyNameSet (local_avails : explicit_imports_s)
85 add_on avails names = foldr (unionNameSets . mkNameSet . availNames) names avails
88 -- PROCESS EXPORT LISTS
89 exportsFromAvail this_mod exports all_avails rn_env
90 `thenRn` \ (export_fn, export_env) ->
92 -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
93 mapRn (recordSlurp Nothing Compulsory) local_avails `thenRn_`
95 returnRn (export_fn, Just (export_env, rn_env, explicit_names))
96 ) `thenRn` \ (_, result) ->
99 junk_exp_fn = error "RnNames:export_fn"
101 all_imports = prel_imports ++ imports
103 -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
104 -- because the former doesn't even look at Prelude.hi for instance declarations,
105 -- whereas the latter does.
106 prel_imports | this_mod == pRELUDE ||
107 explicit_prelude_import ||
108 opt_NoImplicitPrelude
111 | otherwise = [ImportDecl pRELUDE
112 False {- Not qualified -}
113 Nothing {- No "as" -}
114 Nothing {- No import list -}
117 explicit_prelude_import
118 = not (null [ () | (ImportDecl mod qual _ _ _) <- imports, mod == pRELUDE ])
123 = checkErrsRn `thenRn` \ no_errs_so_far ->
124 if not no_errs_so_far then
125 -- Found errors already, so exit now
128 traceRn (text "Considering whether compilation is required...") `thenRn_`
129 (if not opt_SourceUnchanged then
130 -- Source code changed and no errors yet... carry on
131 traceRn (nest 4 (text "source file changed")) `thenRn_`
134 -- Unchanged source, and no errors yet; see if usage info
135 -- up to date, and exit if so
137 ) `thenRn` \ up_to_date ->
138 traceRn (text "Hence, compilation" <+>
139 text (if up_to_date then "IS NOT" else "IS") <+>
140 text "required") `thenRn_`
146 importsFromImportDecl :: RdrNameImportDecl
147 -> RnMG (RnEnv, ModuleAvails, [AvailInfo])
149 importsFromImportDecl (ImportDecl mod qual_only as_mod import_spec loc)
151 getInterfaceExports mod `thenRn` \ (avails, fixities) ->
152 filterImports mod import_spec avails `thenRn` \ (filtered_avails, hides, explicits) ->
154 filtered_avails' = map set_avail_prov filtered_avails
155 fixities' = [ (occ,(fixity,provenance)) | (occ,fixity) <- fixities ]
158 True -- Want qualified names
159 (not qual_only) -- Maybe want unqualified names
161 (ExportEnv filtered_avails' fixities')
163 `thenRn` \ (rn_env, mod_avails) ->
164 returnRn (rn_env, mod_avails, explicits)
166 set_avail_prov NotAvailable = NotAvailable
167 set_avail_prov (Avail n) = Avail (set_name_prov n)
168 set_avail_prov (AvailTC n ns) = AvailTC (set_name_prov n) (map set_name_prov ns)
169 set_name_prov name = setNameProvenance name provenance
170 provenance = Imported mod loc
175 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
176 = foldlRn getLocalDeclBinders [] decls `thenRn` \ avails ->
177 mapRn fixityFromFixDecl fix_decls `thenRn` \ fixities ->
179 False -- Don't want qualified names
180 True -- Want unqualified names
181 Nothing -- No "as M" part
182 (ExportEnv avails fixities)
184 `thenRn` \ (rn_env, mod_avails) ->
185 returnRn (rn_env, mod_avails, avails)
187 newLocalName rdr_name loc
188 = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
190 getLocalDeclBinders avails (ValD binds)
191 = mapRn do_one (bagToList (collectTopBinders binds)) `thenRn` \ val_avails ->
192 returnRn (val_avails ++ avails)
194 getLocalDeclBinders avails decl
195 = getDeclBinders newLocalName decl `thenRn` \ avail ->
197 NotAvailable -> returnRn avails -- Instance decls and suchlike
198 other -> returnRn (avail : avails)
200 do_one (rdr_name, loc)
201 = newLocalName rdr_name loc `thenRn` \ name ->
202 returnRn (Avail name)
205 %************************************************************************
207 \subsection{Filtering imports}
209 %************************************************************************
211 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
212 available, and filters it through the import spec (if any).
215 filterImports :: Module
216 -> Maybe (Bool, [RdrNameIE]) -- Import spec; True => hidin
217 -> [AvailInfo] -- What's available
218 -> RnMG ([AvailInfo], -- What's actually imported
219 [AvailInfo], -- What's to be hidden (the unqualified version, that is)
220 [AvailInfo]) -- What was imported explicitly
222 -- Complains if import spec mentions things that the module doesn't export
224 filterImports mod Nothing imports
225 = returnRn (imports, [], [])
227 filterImports mod (Just (want_hiding, import_items)) avails
228 = mapRn check_item import_items `thenRn` \ item_avails ->
231 returnRn (avails, item_avails, []) -- All imported; item_avails to be hidden
233 returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
236 import_fm :: FiniteMap OccName AvailInfo
237 import_fm = listToFM [ (nameOccName name, avail)
239 name <- availEntityNames avail]
241 check_item item@(IEModuleContents _)
242 = addErrRn (badImportItemErr mod item) `thenRn_`
243 returnRn NotAvailable
246 | not (maybeToBool maybe_in_import_avails) ||
247 (case filtered_avail of { NotAvailable -> True; other -> False })
248 = addErrRn (badImportItemErr mod item) `thenRn_`
249 returnRn NotAvailable
251 | otherwise = returnRn filtered_avail
254 maybe_in_import_avails = lookupFM import_fm (ieOcc item)
255 Just avail = maybe_in_import_avails
256 filtered_avail = filterAvail item avail
261 %************************************************************************
263 \subsection{Qualifiying imports}
265 %************************************************************************
267 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
268 of an import decl, and deals with producing an @RnEnv@ with the
269 right qaulified names. It also turns the @Names@ in the @ExportEnv@ into
270 fully fledged @Names@.
273 qualifyImports :: Module -- Imported module
274 -> Bool -- True <=> want qualified import
275 -> Bool -- True <=> want unqualified import
276 -> Maybe Module -- Optional "as M" part
277 -> ExportEnv -- What's imported
278 -> [AvailInfo] -- What's to be hidden
279 -> RnMG (RnEnv, ModuleAvails)
281 qualifyImports this_mod qual_imp unqual_imp as_mod (ExportEnv avails fixities) hides
283 -- Make the name environment. Since we're talking about a single import module
284 -- there can't be name clashes, so we don't need to be in the monad
285 name_env1 = foldl add_avail emptyNameEnv avails
287 -- Delete things that are hidden
288 name_env2 = foldl del_avail name_env1 hides
290 -- Create the fixity env
291 fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
293 -- The "module M" syntax only applies to *unqualified* imports (1.4 Report, Section 5.1.1)
294 mod_avail_env | unqual_imp = unitFM qual_mod avails
295 | otherwise = emptyFM
297 returnRn (RnEnv name_env2 fixity_env, mod_avail_env)
299 qual_mod = case as_mod of
301 Just another_name -> another_name
303 add_avail env avail = foldl add_name env (availNames avail)
304 add_name env name = env2
306 env1 | qual_imp = addOneToNameEnv env (Qual qual_mod occ) name
308 env2 | unqual_imp = addOneToNameEnv env1 (Unqual occ) name
310 occ = nameOccName name
312 del_avail env avail = foldl delOneFromNameEnv env rdr_names
314 rdr_names = map (Unqual . nameOccName) (availNames avail)
316 add_fixity name_env fix_env (occ_name, (fixity, provenance))
317 = add qual $ add unqual $ fix_env
319 qual = Qual qual_mod occ_name
320 unqual = Unqual occ_name
322 add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
323 = addOneToFixityEnv fix_env rdr_name (fixity,provenance)
328 unQualify adds an Unqual binding for every existing Qual binding.
331 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
332 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ, elt) <- fmToList fm]
335 %************************************************************************
337 \subsection{Local declarations}
339 %************************************************************************
343 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, Provenance))
345 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
346 = returnRn (rdrNameOcc rdr_name, (fixity, LocalDef (panic "export-flag") loc))
350 %************************************************************************
352 \subsection{Export list processing
354 %************************************************************************
356 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
357 When exporting we need to combine the availabilities for a particular
358 exported thing, and we also need to check for name clashes -- that
359 is: two exported things must have different @OccNames@.
362 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo)
363 -- The FM maps each OccName to the RdrNameIE that gave rise to it,
364 -- for error reporting, as well as to its AvailInfo
366 emptyAvailEnv = emptyFM
368 unitAvailEnv :: RdrNameIE -> AvailInfo -> AvailEnv
369 unitAvailEnv ie NotAvailable = emptyFM
370 unitAvailEnv ie (AvailTC _ []) = emptyFM
371 unitAvailEnv ie avail = unitFM (nameOccName (availName avail)) (ie,avail)
374 = mapRn (addErrRn.availClashErr) (conflictsFM bad_avail a1 a2) `thenRn_`
375 returnRn (plusFM_C plus_avail a1 a2)
377 listToAvailEnv :: RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
378 listToAvailEnv ie items
379 = foldlRn plusAvailEnv emptyAvailEnv (map (unitAvailEnv ie) items)
381 bad_avail (ie1,avail1) (ie2,avail2) = availName avail1 /= availName avail2 -- Same OccName, different Name
382 plus_avail (ie1,a1) (ie2,a2) = (ie1, a1 `plusAvail` a2)
385 Processing the export list.
387 You might think that we should record things that appear in the export list as
388 ``occurrences'' (using addOccurrenceName), but you'd be wrong. We do check (here)
389 that they are in scope, but there is no need to slurp in their actual declaration
390 (which is what addOccurrenceName forces). Indeed, doing so would big trouble when
391 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
392 includes ConcBase.StateAndSynchVar#, and so on...
395 exportsFromAvail :: Module
396 -> Maybe [RdrNameIE] -- Export spec
399 -> RnMG (Name -> ExportFlag, ExportEnv)
400 -- Complains if two distinct exports have same OccName
401 -- Complains about exports items not in scope
402 exportsFromAvail this_mod Nothing all_avails rn_env
403 = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) all_avails rn_env
405 exportsFromAvail this_mod (Just export_items) all_avails (RnEnv name_env fixity_env)
406 = mapRn exports_from_item export_items `thenRn` \ avail_envs ->
407 foldlRn plusAvailEnv emptyAvailEnv avail_envs `thenRn` \ export_avail_env ->
409 export_avails = map snd (eltsFM export_avail_env)
410 export_fixities = mk_exported_fixities (availsToNameSet export_avails)
411 export_fn = mk_export_fn export_avails
413 returnRn (export_fn, ExportEnv export_avails export_fixities)
416 full_avail_env :: UniqFM AvailInfo
417 full_avail_env = addListToUFM_C plusAvail emptyUFM
418 [(name, avail) | avail <- concat (eltsFM all_avails),
419 name <- availEntityNames avail
422 -- NB: full_avail_env will contain bindings for class ops but not constructors
423 -- (see defn of availEntityNames)
425 exports_from_item :: RdrNameIE -> RnMG AvailEnv
426 exports_from_item ie@(IEModuleContents mod)
427 = case lookupFM all_avails mod of
428 Nothing -> failWithRn emptyAvailEnv (modExportErr mod)
429 Just avails -> listToAvailEnv ie avails
432 | not (maybeToBool maybe_in_scope)
433 = failWithRn emptyAvailEnv (unknownNameErr (ieName ie))
436 -- I can't see why this should ever happen; if the thing is in scope
437 -- at all it ought to have some availability
438 | not (maybeToBool maybe_avail)
439 = pprTrace "exportsFromAvail: curious Nothing:" (ppr PprDebug name)
440 returnRn emptyAvailEnv
444 = failWithRn emptyAvailEnv (exportItemErr ie export_avail)
446 | otherwise -- Phew! It's OK!
447 = returnRn (unitAvailEnv ie export_avail)
449 maybe_in_scope = lookupNameEnv name_env (ieName ie)
450 Just name = maybe_in_scope
451 maybe_avail = lookupUFM full_avail_env name
452 Just avail = maybe_avail
453 export_avail = filterAvail ie avail
454 enough_avail = case export_avail of {NotAvailable -> False; other -> True}
456 -- We export a fixity iff we export a thing with the same (qualified) RdrName
457 mk_exported_fixities :: NameSet -> [(OccName, (Fixity, Provenance))]
458 mk_exported_fixities exports
459 = fmToList (foldr (perhaps_add_fixity exports)
461 (fmToList fixity_env))
463 perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, Provenance))
464 -> FiniteMap OccName (Fixity,Provenance)
465 -> FiniteMap OccName (Fixity,Provenance)
466 perhaps_add_fixity exports (rdr_name, (fixity, prov)) fix_env
468 do_nothing = fix_env -- The default is to pass on the env unchanged
470 -- Step 1: check whether the rdr_name is in scope; if so find its Name
471 case lookupFM name_env rdr_name of {
472 Nothing -> do_nothing;
475 -- Step 2: check whether the fixity thing is exported
476 if not (fixity_name `elemNameSet` exports) then
480 -- Step 3: check whether we already have a fixity for the
481 -- Name's OccName in the fix_env we are building up. This can easily
482 -- happen. the original fixity_env might contain bindings for
483 -- M.a and N.a, if a was imported via M and N.
484 -- If this does happen, we expect the fixity to be the same either way.
486 occ_name = rdrNameOcc rdr_name
488 case lookupFM fix_env occ_name of {
489 Just (fixity1, prov1) -> -- Got it already
490 ASSERT( fixity == fixity1 )
494 -- Step 3: add it to the outgoing fix_env
495 addToFM fix_env occ_name (fixity,prov)
498 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
500 = \name -> if name `elemNameSet` exported_names
504 exported_names :: NameSet
505 exported_names = availsToNameSet avails
509 %************************************************************************
513 %************************************************************************
516 badImportItemErr mod ie sty
517 = sep [ptext SLIT("Module"), pprModule sty mod, ptext SLIT("does not export"), ppr sty ie]
520 = hsep [ ptext SLIT("Unknown module in export list: module"), ptext mod]
522 exportItemErr export_item NotAvailable sty
523 = sep [ ptext SLIT("Export item not in scope:"), ppr sty export_item ]
525 exportItemErr export_item avail sty
526 = hang (ptext SLIT("Export item not fully in scope:"))
527 4 (vcat [hsep [ptext SLIT("Wanted: "), ppr sty export_item],
528 hsep [ptext SLIT("Available: "), ppr sty (ieOcc export_item), pprAvail sty avail]])
530 availClashErr (occ_name, ((ie1,avail1), (ie2,avail2))) sty
531 = hang (hsep [ptext SLIT("Conflicting exports for local name: "), ppr sty occ_name])
532 4 (vcat [ppr sty ie1, ppr sty ie2])