f69ebb329cabe859e992364b1d59e7348a36fb34
[ghc-hetmet.git] / ghc / compiler / rename / RnNames.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[RnNames]{Extracting imported and top-level names in scope}
5
6 \begin{code}
7 module RnNames (
8         getGlobalNames
9     ) where
10
11 #include "HsVersions.h"
12
13 import CmdLineOpts    ( opt_NoImplicitPrelude, opt_WarnDuplicateExports, 
14                         opt_SourceUnchanged
15                       )
16
17 import HsSyn    ( HsModule(..), ImportDecl(..), HsDecl(..), 
18                   IE(..), ieName,
19                   FixityDecl(..),
20                   collectTopBinders
21                 )
22 import RdrHsSyn ( RdrNameHsDecl(..), RdrName(..), RdrNameIE(..), RdrNameImportDecl,
23                   RdrNameHsModule, RdrNameFixityDecl,
24                   rdrNameOcc, ieOcc
25                 )
26 import RnIfaces ( getInterfaceExports, getDeclBinders, recordSlurp, checkUpToDate )
27 import BasicTypes ( IfaceFlavour(..) )
28 import RnEnv
29 import RnMonad
30
31 import FiniteMap
32 import PrelMods
33 import UniqFM   ( UniqFM, addListToUFM_C, lookupUFM )
34 import Bag      ( Bag, bagToList )
35 import Maybes   ( maybeToBool )
36 import Name
37 import Outputable
38 import Util     ( removeDups )
39 \end{code}
40
41
42
43 %************************************************************************
44 %*                                                                      *
45 \subsection{Get global names}
46 %*                                                                      *
47 %************************************************************************
48
49 \begin{code}
50 getGlobalNames :: RdrNameHsModule
51                -> RnMG (Maybe (ExportEnv, RnEnv, NameSet, Name -> PrintUnqualified))
52                         -- The NameSet is the set of names that are
53                         --      either locally defined,
54                         --      or explicitly imported
55                         -- Nothing => no need to recompile
56
57 getGlobalNames m@(HsModule this_mod _ exports imports _ _ mod_loc)
58   = fixRn (\ ~(rec_exp_fn, _) ->
59
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) ->
64
65         -- PROCESS IMPORT DECLS
66       mapAndUnzip3Rn importsFromImportDecl all_imports
67                                                 `thenRn` \ (imp_rn_envs, imp_avails_s, explicit_imports_s) ->
68
69         -- COMBINE RESULTS
70         -- We put the local env second, so that a local provenance
71         -- "wins", even if a module imports itself.
72       foldlRn plusRnEnv emptyRnEnv imp_rn_envs          `thenRn` \ imp_rn_env ->
73       plusRnEnv imp_rn_env local_rn_env                 `thenRn` \ rn_env ->
74
75         -- TRY FOR EARLY EXIT
76         -- We can't go for an early exit before this because we have to check
77         -- for name clashes.  Consider:
78         --
79         --      module A where          module B where
80         --         import B                h = True
81         --         f = h
82         --
83         -- Suppose I've compiled everything up, and then I add a
84         -- new definition to module B, that defines "f".
85         --
86         -- Then I must detect the name clash in A before going for an early
87         -- exit.  The early-exit code checks what's actually needed from B
88         -- to compile A, and of course that doesn't include B.f.  That's
89         -- why we wait till after the plusRnEnv stuff to do the early-exit.
90       checkEarlyExit this_mod                           `thenRn` \ up_to_date ->
91       if up_to_date then
92         returnRn (error "early exit", Nothing)
93       else
94  
95
96         -- PROCESS EXPORT LISTS
97       let
98          export_avails :: ExportAvails
99          export_avails = foldr plusExportAvails local_mod_avails imp_avails_s
100
101          explicit_names :: NameSet      -- locally defined or explicitly imported
102          explicit_names = foldr add_on emptyNameSet (local_avails : explicit_imports_s)
103          add_on avails names = foldr (unionNameSets . mkNameSet . availNames) names avails
104       in
105       exportsFromAvail this_mod exports export_avails rn_env    
106                                                         `thenRn` \ (export_fn, export_env) ->
107
108         -- RECORD THAT LOCALLY DEFINED THINGS ARE AVAILABLE
109       mapRn (recordSlurp Nothing Compulsory) local_avails       `thenRn_`
110
111         -- BUILD THE "IMPORT FN".  It just tells whether a name is in
112         -- scope in an unqualified form.
113       let 
114           print_unqual = mkImportFn imp_rn_env
115       in   
116
117       returnRn (export_fn, Just (export_env, rn_env, explicit_names, print_unqual))
118     )                                                   `thenRn` \ (_, result) ->
119     returnRn result
120   where
121     junk_exp_fn = error "RnNames:export_fn"
122
123     all_imports = prel_imports ++ imports
124
125         -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
126         -- because the former doesn't even look at Prelude.hi for instance declarations,
127         -- whereas the latter does.
128     prel_imports | this_mod == pRELUDE ||
129                    explicit_prelude_import ||
130                    opt_NoImplicitPrelude
131                  = []
132
133                  | otherwise               = [ImportDecl pRELUDE 
134                                                          False          {- Not qualified -}
135                                                          HiFile         {- Not source imported -}
136                                                          Nothing        {- No "as" -}
137                                                          Nothing        {- No import list -}
138                                                          mod_loc]
139     
140     explicit_prelude_import
141       = not (null [ () | (ImportDecl mod qual _ _ _ _) <- imports, mod == pRELUDE ])
142 \end{code}
143         
144 \begin{code}
145 checkEarlyExit mod
146   = checkErrsRn                         `thenRn` \ no_errs_so_far ->
147     if not no_errs_so_far then
148         -- Found errors already, so exit now
149         returnRn True
150     else
151
152     traceRn (text "Considering whether compilation is required...")     `thenRn_`
153     if not opt_SourceUnchanged then
154         -- Source code changed and no errors yet... carry on 
155         traceRn (nest 4 (text "source file changed or recompilation check turned off")) `thenRn_` 
156         returnRn False
157     else
158
159         -- Unchanged source, and no errors yet; see if usage info
160         -- up to date, and exit if so
161     checkUpToDate mod                                           `thenRn` \ up_to_date ->
162     putDocRn (text "Compilation" <+> 
163               text (if up_to_date then "IS NOT" else "IS") <+>
164               text "required")                                  `thenRn_`
165     returnRn up_to_date
166 \end{code}
167         
168 \begin{code}
169 importsFromImportDecl :: RdrNameImportDecl
170                       -> RnMG (RnEnv, ExportAvails, [AvailInfo])
171
172 importsFromImportDecl (ImportDecl mod qual_only as_source as_mod import_spec loc)
173   = pushSrcLocRn loc $
174     getInterfaceExports mod as_source           `thenRn` \ (avails, fixities) ->
175     filterImports mod import_spec avails        `thenRn` \ (filtered_avails, hides, explicits) ->
176     let
177         how_in_scope = FromImportDecl mod loc
178     in
179     qualifyImports mod 
180                    True                 -- Want qualified names
181                    (not qual_only)      -- Maybe want unqualified names
182                    as_mod
183                    hides
184                    filtered_avails (\n -> how_in_scope)
185                    [ (occ,(fixity,how_in_scope)) | (occ,fixity) <- fixities ]
186                                                         `thenRn` \ (rn_env, mod_avails) ->
187     returnRn (rn_env, mod_avails, explicits)
188 \end{code}
189
190
191 \begin{code}
192 importsFromLocalDecls rec_exp_fn (HsModule mod _ _ _ fix_decls decls _)
193   = foldlRn getLocalDeclBinders [] decls                `thenRn` \ avails ->
194     mapRn fixityFromFixDecl fix_decls                   `thenRn` \ fixities ->
195     qualifyImports mod 
196                    False        -- Don't want qualified names
197                    True         -- Want unqualified names
198                    Nothing      -- No "as M" part
199                    []           -- Hide nothing
200                    avails (\n -> FromLocalDefn (getSrcLoc n))
201                    fixities
202                                                         `thenRn` \ (rn_env, mod_avails) ->
203     returnRn (rn_env, mod_avails, avails)
204   where
205     newLocalName rdr_name loc
206       = newLocallyDefinedGlobalName mod (rdrNameOcc rdr_name) rec_exp_fn loc
207
208     getLocalDeclBinders avails (ValD binds)
209       = mapRn do_one (bagToList (collectTopBinders binds))      `thenRn` \ val_avails ->
210         returnRn (val_avails ++ avails)
211
212     getLocalDeclBinders avails decl
213       = getDeclBinders newLocalName decl        `thenRn` \ avail ->
214         case avail of
215            NotAvailable -> returnRn avails              -- Instance decls and suchlike
216            other        -> returnRn (avail : avails)
217
218     do_one (rdr_name, loc)
219       = newLocalName rdr_name loc       `thenRn` \ name ->
220         returnRn (Avail name)
221 \end{code}
222
223 %************************************************************************
224 %*                                                                      *
225 \subsection{Filtering imports}
226 %*                                                                      *
227 %************************************************************************
228
229 @filterImports@ takes the @ExportEnv@ telling what the imported module makes
230 available, and filters it through the import spec (if any).
231
232 \begin{code}
233 filterImports :: Module
234               -> Maybe (Bool, [RdrNameIE])              -- Import spec; True => hidin
235               -> [AvailInfo]                            -- What's available
236               -> RnMG ([AvailInfo],                     -- What's actually imported
237                        [AvailInfo],                     -- What's to be hidden (the unqualified version, that is)
238                        [AvailInfo])                     -- What was imported explicitly
239
240         -- Complains if import spec mentions things that the module doesn't export
241         -- Warns/informs if import spec contains duplicates.
242 filterImports mod Nothing imports
243   = returnRn (imports, [], [])
244
245 filterImports mod (Just (want_hiding, import_items)) avails
246   = mapRn check_item import_items               `thenRn` \ item_avails ->
247     if want_hiding 
248     then        
249         returnRn (avails, item_avails, [])      -- All imported; item_avails to be hidden
250     else
251         returnRn (item_avails, [], item_avails) -- Just item_avails imported; nothing to be hidden
252
253   where
254     import_fm :: FiniteMap OccName AvailInfo
255     import_fm = listToFM [ (nameOccName name, avail) 
256                          | avail <- avails,
257                            name  <- availEntityNames avail]
258
259     check_item item@(IEModuleContents _)
260       = addErrRn (badImportItemErr mod item)    `thenRn_`
261         returnRn NotAvailable
262
263     check_item item
264       | not (maybeToBool maybe_in_import_avails) ||
265         (case filtered_avail of { NotAvailable -> True; other -> False })
266       = addErrRn (badImportItemErr mod item)    `thenRn_`
267         returnRn NotAvailable
268
269       | otherwise   = returnRn filtered_avail
270                 
271       where
272         maybe_in_import_avails = lookupFM import_fm (ieOcc item)
273         Just avail             = maybe_in_import_avails
274         filtered_avail         = filterAvail item avail
275 \end{code}
276
277
278
279 %************************************************************************
280 %*                                                                      *
281 \subsection{Qualifiying imports}
282 %*                                                                      *
283 %************************************************************************
284
285 @qualifyImports@ takes the @ExportEnv@ after filtering through the import spec
286 of an import decl, and deals with producing an @RnEnv@ with the 
287 right qualified names.  It also turns the @Names@ in the @ExportEnv@ into
288 fully fledged @Names@.
289
290 \begin{code}
291 qualifyImports :: Module                                -- Imported module
292                -> Bool                                  -- True <=> want qualified import
293                -> Bool                                  -- True <=> want unqualified import
294                -> Maybe Module                          -- Optional "as M" part 
295                -> [AvailInfo]                           -- What's to be hidden
296                -> Avails -> (Name -> HowInScope)        -- Whats imported and how
297                -> [(OccName, (Fixity, HowInScope))]     -- Ditto for fixities
298                -> RnMG (RnEnv, ExportAvails)
299
300 qualifyImports this_mod qual_imp unqual_imp as_mod hides
301                avails name_to_his fixities
302   = 
303         -- Make the name environment.  Even though we're talking about a 
304         -- single import module there might still be name clashes, 
305         -- because it might be the module being compiled.
306     foldlRn add_avail emptyGlobalNameEnv avails `thenRn` \ name_env1 ->
307     let
308         -- Delete things that are hidden
309         name_env2 = foldl del_avail name_env1 hides
310
311         -- Create the fixity env
312         fixity_env = foldl (add_fixity name_env2) emptyFixityEnv fixities
313
314         -- Create the export-availability info
315         export_avails = mkExportAvails qual_mod unqual_imp name_env2 avails
316     in
317     returnRn (RnEnv name_env2 fixity_env, export_avails)
318   where
319     qual_mod = case as_mod of
320                   Nothing           -> this_mod
321                   Just another_name -> another_name
322
323     add_avail :: GlobalNameEnv -> AvailInfo -> RnMG GlobalNameEnv
324     add_avail env avail = foldlRn add_name env (availNames avail)
325
326     add_name env name   = add qual_imp   env  (Qual qual_mod occ err_hif) `thenRn` \ env1 ->
327                           add unqual_imp env1 (Unqual occ)
328                         where
329                           add False env rdr_name = returnRn env
330                           add True  env rdr_name = addOneToGlobalNameEnv env rdr_name (name, name_to_his name)
331                           occ  = nameOccName name
332
333     del_avail env avail = foldl delOneFromGlobalNameEnv env rdr_names
334                         where
335                           rdr_names = map (Unqual . nameOccName) (availNames avail)
336                         
337     add_fixity name_env fix_env (occ_name, fixity)
338         = add qual $ add unqual $ fix_env
339         where
340           qual   = Qual qual_mod occ_name err_hif
341           unqual = Unqual occ_name
342
343           add rdr_name fix_env | maybeToBool (lookupFM name_env rdr_name)
344                                = addOneToFixityEnv fix_env rdr_name fixity
345                                | otherwise
346                                = fix_env
347
348 err_hif = error "qualifyImports: hif"   -- Not needed in key to mapping
349 \end{code}
350
351 unQualify adds an Unqual binding for every existing Qual binding.
352
353 \begin{code}
354 unQualify :: FiniteMap RdrName elt -> FiniteMap RdrName elt
355 unQualify fm = addListToFM fm [(Unqual occ, elt) | (Qual _ occ _, elt) <- fmToList fm]
356 \end{code}
357
358 %************************************************************************
359 %*                                                                      *
360 \subsection{Local declarations}
361 %*                                                                      *
362 %************************************************************************
363
364
365 \begin{code}
366 fixityFromFixDecl :: RdrNameFixityDecl -> RnMG (OccName, (Fixity, HowInScope))
367
368 fixityFromFixDecl (FixityDecl rdr_name fixity loc)
369   = returnRn (rdrNameOcc rdr_name, (fixity, FromLocalDefn loc))
370 \end{code}
371
372
373 %************************************************************************
374 %*                                                                      *
375 \subsection{Export list processing
376 %*                                                                      *
377 %************************************************************************
378
379 The @AvailEnv@ type is just used internally in @exportsFromAvail@.
380 When exporting we need to combine the availabilities for a particular
381 exported thing, and we also need to check for name clashes -- that
382 is: two exported things must have different @OccNames@.
383
384 \begin{code}
385 type AvailEnv = FiniteMap OccName (RdrNameIE, AvailInfo, Int{-no. of clashes-})
386         -- The FM maps each OccName to the RdrNameIE that gave rise to it,
387         -- for error reporting, as well as to its AvailInfo
388
389 emptyAvailEnv = emptyFM
390
391 {-
392  Add new entry to environment. Checks for name clashes, i.e.,
393  plain duplicates or exported entity pairs that have different OccNames.
394  (c.f. 5.1.1 of Haskell 1.4 report.)
395 -}
396 addAvailEnv :: Bool -> RdrNameIE -> AvailEnv -> AvailInfo -> RnM s d AvailEnv
397 addAvailEnv warn_dups ie env NotAvailable   = returnRn env
398 addAvailEnv warn_dups ie env (AvailTC _ []) = returnRn env
399 addAvailEnv warn_dups ie env avail
400   | warn_dups = mapMaybeRn (addErrRn  . availClashErr) () conflict `thenRn_`
401                 returnRn (addToFM_C addAvail env key elt)
402   | otherwise = returnRn (addToFM_C addAvail env key elt)
403   where
404    key  = nameOccName (availName avail)
405    elt  = (ie,avail,reports_on)
406
407    reports_on
408     | maybeToBool dup = 1
409     | otherwise       = 0
410
411    conflict = conflictFM bad_avail env key elt
412    dup 
413     | warn_dups = conflictFM dup_avail env key elt
414     | otherwise = Nothing
415
416 addListToAvailEnv :: AvailEnv -> RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
417 addListToAvailEnv env ie items = foldlRn (addAvailEnv False ie) env items
418
419 bad_avail  (ie1,avail1,r1) (ie2,avail2,r2) 
420    = availName avail1 /= availName avail2  -- Same OccName, different Name
421 dup_avail  (ie1,avail1,r1) (ie2,avail2,r2) 
422    = availName avail1 == availName avail2 -- Same OccName & avail.
423
424 addAvail (ie1,a1,r1) (ie2,a2,r2) = (ie1, a1 `plusAvail` a2, r1 + r2)
425 \end{code}
426
427 Processing the export list.
428
429 You might think that we should record things that appear in the export list as
430 ``occurrences'' (using addOccurrenceName), but you'd be wrong.  We do check (here)
431 that they are in scope, but there is no need to slurp in their actual declaration
432 (which is what addOccurrenceName forces).  Indeed, doing so would big trouble when
433 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
434 includes ConcBase.StateAndSynchVar#, and so on...
435
436 \begin{code}
437 exportsFromAvail :: Module
438                  -> Maybe [RdrNameIE]   -- Export spec
439                  -> ExportAvails
440                  -> RnEnv
441                  -> RnMG (Name -> ExportFlag, ExportEnv)
442         -- Complains if two distinct exports have same OccName
443         -- Warns about identical exports.
444         -- Complains about exports items not in scope
445 exportsFromAvail this_mod Nothing export_avails rn_env
446   = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
447
448 exportsFromAvail this_mod (Just export_items) 
449                  (mod_avail_env, entity_avail_env)
450                  (RnEnv global_name_env fixity_env)
451   = checkForModuleExportDups export_items                 `thenRn` \ export_items' ->
452     foldlRn exports_from_item emptyAvailEnv export_items' `thenRn` \ export_avail_env ->
453     let
454      dup_entries = fmToList (filterFM (\ _ (_,_,clashes) -> clashes > 0) export_avail_env)
455     in
456     mapRn (addWarnRn . dupExportWarn) dup_entries         `thenRn_`
457     let
458         export_avails   = map (\ (_,a,_) -> a) (eltsFM export_avail_env)
459         export_fixities = mk_exported_fixities (availsToNameSet export_avails)
460         export_fn       = mk_export_fn export_avails
461     in
462     returnRn (export_fn, ExportEnv export_avails export_fixities)
463
464   where
465     exports_from_item :: AvailEnv -> RdrNameIE -> RnMG AvailEnv
466     exports_from_item export_avail_env ie@(IEModuleContents mod)
467         = case lookupFM mod_avail_env mod of
468                 Nothing     -> failWithRn export_avail_env (modExportErr mod)
469                 Just avails -> addListToAvailEnv export_avail_env ie avails
470
471     exports_from_item export_avail_env ie
472         | not (maybeToBool maybe_in_scope) 
473         = failWithRn export_avail_env (unknownNameErr (ieName ie))
474
475 #ifdef DEBUG
476         -- I can't see why this should ever happen; if the thing is in scope
477         -- at all it ought to have some availability
478         | not (maybeToBool maybe_avail)
479         = pprTrace "exportsFromAvail: curious Nothing:" (ppr name)
480           returnRn export_avail_env
481 #endif
482
483         | not enough_avail
484         = failWithRn export_avail_env (exportItemErr ie export_avail)
485
486         | otherwise     -- Phew!  It's OK!
487         = addAvailEnv opt_WarnDuplicateExports ie export_avail_env export_avail
488        where
489           maybe_in_scope  = lookupFM global_name_env (ieName ie)
490           Just (name,_)   = maybe_in_scope
491           maybe_avail     = lookupUFM entity_avail_env name
492           Just avail      = maybe_avail
493           export_avail    = filterAvail ie avail
494           enough_avail    = case export_avail of {NotAvailable -> False; other -> True}
495
496         -- We export a fixity iff we export a thing with the same (qualified) RdrName
497     mk_exported_fixities :: NameSet -> [(OccName, Fixity)]
498     mk_exported_fixities exports
499         = fmToList (foldr (perhaps_add_fixity exports) 
500                           emptyFM
501                           (fmToList fixity_env))
502
503     perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, HowInScope))
504                        -> FiniteMap OccName Fixity
505                        -> FiniteMap OccName Fixity
506     perhaps_add_fixity exports (rdr_name, (fixity, how_in_scope)) fix_env
507       =  let
508             do_nothing = fix_env                -- The default is to pass on the env unchanged
509          in
510                 -- Step 1: check whether the rdr_name is in scope; if so find its Name
511          case lookupFM global_name_env rdr_name of {
512            Nothing              -> do_nothing;
513            Just (fixity_name,_) -> 
514
515                 -- Step 2: check whether the fixity thing is exported
516          if not (fixity_name `elemNameSet` exports) then
517                 do_nothing
518          else
519         
520                 -- Step 3: check whether we already have a fixity for the
521                 -- Name's OccName in the fix_env we are building up.  This can easily
522                 -- happen.  the original fixity_env might contain bindings for
523                 --      M.a and N.a, if a was imported via M and N.
524                 -- If this does happen, we expect the fixity to be the same either way.
525         let
526             occ_name = rdrNameOcc rdr_name
527         in
528         case lookupFM fix_env occ_name of {
529           Just fixity1 ->       -- Got it already
530                            ASSERT( fixity == fixity1 )
531                            do_nothing;
532           Nothing -> 
533
534                 -- Step 3: add it to the outgoing fix_env
535         addToFM fix_env occ_name fixity
536         }}
537
538 {- warn and weed out duplicate module entries from export list. -}
539 checkForModuleExportDups :: [RdrNameIE] -> RnMG [RdrNameIE]
540 checkForModuleExportDups ls 
541   | opt_WarnDuplicateExports = check_modules ls
542   | otherwise                = returnRn ls
543   where
544    -- NOTE: reorders the export list by moving all module-contents
545    -- exports to the end (removing duplicates in the process.)
546    check_modules ls = 
547      (case dups of
548         [] -> returnRn ()
549         ls -> mapRn (\ ds@(IEModuleContents x:_) -> 
550                        addWarnRn (dupModuleExport x (length ds))) ls `thenRn_`
551               returnRn ()) `thenRn_`
552      returnRn (ls_no_modules ++ no_module_dups)
553      where
554       (ls_no_modules,modules) = foldr split_mods ([],[]) ls
555
556       split_mods i@(IEModuleContents _) ~(no_ms,ms) = (no_ms,i:ms)
557       split_mods i ~(no_ms,ms) = (i:no_ms,ms)
558
559       (no_module_dups, dups) = removeDups cmp_mods modules
560
561       cmp_mods (IEModuleContents m1) (IEModuleContents m2) = m1 `compare` m2
562   
563 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
564 mk_export_fn avails
565   = \name -> if name `elemNameSet` exported_names
566              then Exported
567              else NotExported
568   where
569     exported_names :: NameSet
570     exported_names = availsToNameSet avails
571 \end{code}
572
573 %************************************************************************
574 %*                                                                      *
575 \subsection{Errors}
576 %*                                                                      *
577 %************************************************************************
578
579 \begin{code}
580 badImportItemErr mod ie
581   = sep [ptext SLIT("Module"), quotes (pprModule mod), 
582          ptext SLIT("does not export"), quotes (ppr ie)]
583
584 modExportErr mod
585   = hsep [ ptext SLIT("Unknown module in export list: module"), quotes (pprModule mod)]
586
587 exportItemErr export_item NotAvailable
588   = sep [ ptext SLIT("Export item not in scope:"), quotes (ppr export_item)]
589
590 exportItemErr export_item avail
591   = hang (ptext SLIT("Export item not fully in scope:"))
592            4 (vcat [hsep [ptext SLIT("Wanted:   "), ppr export_item],
593                     hsep [ptext SLIT("Available:"), ppr (ieOcc export_item), pprAvail avail]])
594
595 availClashErr (occ_name, ((ie1,avail1,_), (ie2,avail2,_)))
596   = hsep [ptext SLIT("The export items"), quotes (ppr ie1), ptext SLIT("and"), quotes (ppr ie2),
597           ptext SLIT("create conflicting exports for"), quotes (ppr occ_name)]
598
599 dupExportWarn (occ_name, (_,_,times))
600   = hsep [quotes (ppr occ_name), 
601           ptext SLIT("mentioned"), speakNTimes (times+1),
602           ptext SLIT("in export list")]
603
604 dupModuleExport mod times
605   = hsep [ptext SLIT("Module"), quotes (pprModule mod), 
606           ptext SLIT("mentioned"), speakNTimes times,
607           ptext SLIT("in export list")]
608 \end{code}
609