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