[project @ 1998-03-03 18:57:49 by sof]
[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    occ_avail = nameOccName (availName avail)
420    occ_ie    = ieOcc ie
421    key
422     | occ_ie == occ_avail = occ_avail
423     | otherwise           = occ_ie 
424         -- export item is a class method, use export occ name instead.
425
426    elt  = (ie,avail,reports_on)
427
428    reports_on
429     | maybeToBool dup = 1
430     | otherwise       = 0
431
432    conflict = conflictFM bad_avail env key elt
433    dup 
434     | warn_dups = conflictFM dup_avail env key elt
435     | otherwise = Nothing
436
437 addListToAvailEnv :: AvailEnv -> RdrNameIE -> [AvailInfo] -> RnM s d AvailEnv
438 addListToAvailEnv env ie items 
439   = foldlRn (addAvailEnv False{-don't warn about dups-} ie) env items
440
441 bad_avail  (ie1,avail1,r1) (ie2,avail2,r2) 
442    = availName avail1 /= availName avail2  -- Same OccName, different Name
443 dup_avail  (ie1,avail1,r1) (ie2,avail2,r2) 
444    = availName avail1 == availName avail2 -- Same OccName & avail.
445
446 addAvail (ie1,a1,r1) (ie2,a2,r2) = (ie1, a1 `plusAvail` a2, r1 + r2)
447 \end{code}
448
449 Processing the export list.
450
451 You might think that we should record things that appear in the export list as
452 ``occurrences'' (using addOccurrenceName), but you'd be wrong.  We do check (here)
453 that they are in scope, but there is no need to slurp in their actual declaration
454 (which is what addOccurrenceName forces).  Indeed, doing so would big trouble when
455 compiling PrelBase, because it re-exports GHC, which includes takeMVar#, whose type
456 includes ConcBase.StateAndSynchVar#, and so on...
457
458 \begin{code}
459 exportsFromAvail :: Module
460                  -> Maybe [RdrNameIE]   -- Export spec
461                  -> ExportAvails
462                  -> RnEnv
463                  -> RnMG (Name -> ExportFlag, ExportEnv)
464         -- Complains if two distinct exports have same OccName
465         -- Warns about identical exports.
466         -- Complains about exports items not in scope
467 exportsFromAvail this_mod Nothing export_avails rn_env
468   = exportsFromAvail this_mod (Just [IEModuleContents this_mod]) export_avails rn_env
469
470 exportsFromAvail this_mod (Just export_items) 
471                  (mod_avail_env, entity_avail_env)
472                  (RnEnv global_name_env fixity_env)
473   = checkForModuleExportDups export_items                 `thenRn` \ export_items' ->
474     foldlRn exports_from_item emptyAvailEnv export_items' `thenRn` \ export_avail_env ->
475     let
476      dup_entries = fmToList (filterFM (\ _ (_,_,clashes) -> clashes > 0) export_avail_env)
477     in
478     mapRn (addWarnRn . dupExportWarn) dup_entries         `thenRn_`
479     let
480         export_avails   = map (\ (_,a,_) -> a) (eltsFM export_avail_env)
481         export_fixities = mk_exported_fixities (availsToNameSet export_avails)
482         export_fn       = mk_export_fn export_avails
483     in
484     returnRn (export_fn, ExportEnv export_avails export_fixities)
485
486   where
487     exports_from_item :: AvailEnv -> RdrNameIE -> RnMG AvailEnv
488     exports_from_item export_avail_env ie@(IEModuleContents mod)
489         = case lookupFM mod_avail_env mod of
490                 Nothing     -> failWithRn export_avail_env (modExportErr mod)
491                 Just avails -> addListToAvailEnv export_avail_env ie avails
492
493     exports_from_item export_avail_env ie
494         | not (maybeToBool maybe_in_scope) 
495         = failWithRn export_avail_env (unknownNameErr (ieName ie))
496
497 #ifdef DEBUG
498         -- I can't see why this should ever happen; if the thing is in scope
499         -- at all it ought to have some availability
500         | not (maybeToBool maybe_avail)
501         = pprTrace "exportsFromAvail: curious Nothing:" (ppr name)
502           returnRn export_avail_env
503 #endif
504
505         | not enough_avail
506         = failWithRn export_avail_env (exportItemErr ie export_avail)
507
508         | otherwise     -- Phew!  It's OK!
509         = addAvailEnv opt_WarnDuplicateExports ie export_avail_env export_avail
510        where
511           maybe_in_scope  = lookupFM global_name_env (ieName ie)
512           Just (name,_)   = maybe_in_scope
513           maybe_avail     = lookupUFM entity_avail_env name
514           Just avail      = maybe_avail
515           export_avail    = filterAvail ie avail
516           enough_avail    = case export_avail of {NotAvailable -> False; other -> True}
517
518         -- We export a fixity iff we export a thing with the same (qualified) RdrName
519     mk_exported_fixities :: NameSet -> [(OccName, Fixity)]
520     mk_exported_fixities exports
521         = fmToList (foldr (perhaps_add_fixity exports) 
522                           emptyFM
523                           (fmToList fixity_env))
524
525     perhaps_add_fixity :: NameSet -> (RdrName, (Fixity, HowInScope))
526                        -> FiniteMap OccName Fixity
527                        -> FiniteMap OccName Fixity
528     perhaps_add_fixity exports (rdr_name, (fixity, how_in_scope)) fix_env
529       =  let
530             do_nothing = fix_env                -- The default is to pass on the env unchanged
531          in
532                 -- Step 1: check whether the rdr_name is in scope; if so find its Name
533          case lookupFM global_name_env rdr_name of {
534            Nothing              -> do_nothing;
535            Just (fixity_name,_) -> 
536
537                 -- Step 2: check whether the fixity thing is exported
538          if not (fixity_name `elemNameSet` exports) then
539                 do_nothing
540          else
541         
542                 -- Step 3: check whether we already have a fixity for the
543                 -- Name's OccName in the fix_env we are building up.  This can easily
544                 -- happen.  the original fixity_env might contain bindings for
545                 --      M.a and N.a, if a was imported via M and N.
546                 -- If this does happen, we expect the fixity to be the same either way.
547         let
548             occ_name = rdrNameOcc rdr_name
549         in
550         case lookupFM fix_env occ_name of {
551           Just fixity1 ->       -- Got it already
552                            ASSERT( fixity == fixity1 )
553                            do_nothing;
554           Nothing -> 
555
556                 -- Step 3: add it to the outgoing fix_env
557         addToFM fix_env occ_name fixity
558         }}
559
560 {- warn and weed out duplicate module entries from export list. -}
561 checkForModuleExportDups :: [RdrNameIE] -> RnMG [RdrNameIE]
562 checkForModuleExportDups ls 
563   | opt_WarnDuplicateExports = check_modules ls
564   | otherwise                = returnRn ls
565   where
566    -- NOTE: reorders the export list by moving all module-contents
567    -- exports to the end (removing duplicates in the process.)
568    check_modules ls = 
569      (case dups of
570         [] -> returnRn ()
571         ls -> mapRn (\ ds@(IEModuleContents x:_) -> 
572                        addWarnRn (dupModuleExport x (length ds))) ls `thenRn_`
573               returnRn ()) `thenRn_`
574      returnRn (ls_no_modules ++ no_module_dups)
575      where
576       (ls_no_modules,modules) = foldr split_mods ([],[]) ls
577
578       split_mods i@(IEModuleContents _) (no_ms,ms) = (no_ms,i:ms)
579       split_mods i (no_ms,ms) = (i:no_ms,ms)
580
581       (no_module_dups, dups) = removeDups cmp_mods modules
582
583       cmp_mods (IEModuleContents m1) (IEModuleContents m2) = m1 `compare` m2
584   
585 mk_export_fn :: [AvailInfo] -> (Name -> ExportFlag)
586 mk_export_fn avails
587   = \name -> if name `elemNameSet` exported_names
588              then Exported
589              else NotExported
590   where
591     exported_names :: NameSet
592     exported_names = availsToNameSet avails
593 \end{code}
594
595 %************************************************************************
596 %*                                                                      *
597 \subsection{Errors}
598 %*                                                                      *
599 %************************************************************************
600
601 \begin{code}
602 badImportItemErr mod ie
603   = sep [ptext SLIT("Module"), quotes (pprModule mod), 
604          ptext SLIT("does not export"), quotes (ppr ie)]
605
606 modExportErr mod
607   = hsep [ ptext SLIT("Unknown module in export list: module"), quotes (pprModule mod)]
608
609 exportItemErr export_item NotAvailable
610   = sep [ ptext SLIT("Export item not in scope:"), quotes (ppr export_item)]
611
612 exportItemErr export_item avail
613   = hang (ptext SLIT("Export item not fully in scope:"))
614            4 (vcat [hsep [ptext SLIT("Wanted:   "), ppr export_item],
615                     hsep [ptext SLIT("Available:"), ppr (ieOcc export_item), pprAvail avail]])
616
617 availClashErr (occ_name, ((ie1,avail1,_), (ie2,avail2,_)))
618   = hsep [ptext SLIT("The export items"), quotes (ppr ie1), ptext SLIT("and"), quotes (ppr ie2),
619           ptext SLIT("create conflicting exports for"), quotes (ppr occ_name)]
620
621 dupExportWarn (occ_name, (_,_,times))
622   = hsep [quotes (ppr occ_name), 
623           ptext SLIT("mentioned"), speakNTimes (times+1),
624           ptext SLIT("in export list")]
625
626 dupModuleExport mod times
627   = hsep [ptext SLIT("Module"), quotes (pprModule mod), 
628           ptext SLIT("mentioned"), speakNTimes times,
629           ptext SLIT("in export list")]
630 \end{code}
631