730f02db38df56340cef4311ef7817dfb39a0bc3
[ghc-hetmet.git] / ghc / compiler / rename / Rename.lhs
1 %
2 % (c) The GRASP Project, Glasgow University, 1992-1998
3 %
4 \section[Rename]{Renaming and dependency analysis passes}
5
6 \begin{code}
7 module Rename ( renameModule ) where
8
9 #include "HsVersions.h"
10
11 import HsSyn
12 import RdrHsSyn         ( RdrNameHsModule )
13 import RnHsSyn          ( RenamedHsModule, RenamedHsDecl, 
14                           extractHsTyNames, extractHsCtxtTyNames
15                         )
16
17 import CmdLineOpts      ( opt_HiMap, opt_D_dump_rn_trace,
18                           opt_D_dump_rn, opt_D_dump_rn_stats,
19                           opt_WarnUnusedBinds, opt_WarnUnusedImports
20                         )
21 import RnMonad
22 import RnNames          ( getGlobalNames )
23 import RnSource         ( rnSourceDecls, rnDecl )
24 import RnIfaces         ( getImportedInstDecls, importDecl, getImportVersions,
25                           getImportedRules, loadHomeInterface, getSlurped, removeContext
26                         )
27 import RnEnv            ( availName, availNames, availsToNameSet, 
28                           warnUnusedTopNames, mapFvRn, lookupImplicitOccRn,
29                           FreeVars, plusFVs, plusFV, unitFV, emptyFVs, isEmptyFVs
30                         )
31 import Module           ( Module, ModuleName, pprModule, mkSearchPath, mkThisModule )
32 import Name             ( Name, isLocallyDefined,
33                           NamedThing(..), ImportReason(..), Provenance(..),
34                           pprOccName, nameOccName,
35                           getNameProvenance, 
36                           maybeWiredInTyConName, maybeWiredInIdName, isWiredInName
37                         )
38 import Id               ( idType )
39 import DataCon          ( dataConTyCon, dataConType )
40 import TyCon            ( TyCon, tyConDataCons, isSynTyCon, getSynTyConDefn )
41 import RdrName          ( RdrName )
42 import NameSet
43 import PrelMods         ( mAIN_Name, pREL_MAIN_Name )
44 import TysWiredIn       ( unitTyCon, intTyCon, doubleTyCon, boolTyCon )
45 import PrelInfo         ( ioTyCon_NAME, numClass_RDR, thinAirIdNames, derivingOccurrences )
46 import Type             ( namesOfType, funTyCon )
47 import ErrUtils         ( printErrorsAndWarnings, dumpIfSet, ghcExit )
48 import BasicTypes       ( NewOrData(..) )
49 import Bag              ( isEmptyBag, bagToList )
50 import FiniteMap        ( fmToList, delListFromFM, addToFM, sizeFM, eltsFM )
51 import UniqSupply       ( UniqSupply )
52 import UniqFM           ( lookupUFM )
53 import Util             ( equivClasses )
54 import Maybes           ( maybeToBool )
55 import Outputable
56 \end{code}
57
58
59
60 \begin{code}
61 renameModule :: UniqSupply
62              -> RdrNameHsModule
63              -> IO (Maybe 
64                       ( Module
65                       , RenamedHsModule   -- Output, after renaming
66                       , InterfaceDetails  -- Interface; for interface file generation
67                       , RnNameSupply      -- Final env; for renaming derivings
68                       , [ModuleName]      -- Imported modules; for profiling
69                       ))
70
71 renameModule us this_mod@(HsModule mod_name vers exports imports local_decls loc)
72   =     -- Initialise the renamer monad
73     initRn mod_name us (mkSearchPath opt_HiMap) loc
74            (rename this_mod)                            >>=
75         \ ((maybe_rn_stuff, dump_action), rn_errs_bag, rn_warns_bag) ->
76
77         -- Check for warnings
78     printErrorsAndWarnings rn_errs_bag rn_warns_bag     >>
79
80         -- Dump any debugging output
81     dump_action                                         >>
82
83         -- Return results
84     if not (isEmptyBag rn_errs_bag) then
85             ghcExit 1 >> return Nothing
86     else
87             return maybe_rn_stuff
88 \end{code}
89
90
91 \begin{code}
92 rename this_mod@(HsModule mod_name vers exports imports local_decls loc)
93   =     -- FIND THE GLOBAL NAME ENVIRONMENT
94     getGlobalNames this_mod                     `thenRn` \ maybe_stuff ->
95
96         -- CHECK FOR EARLY EXIT
97     if not (maybeToBool maybe_stuff) then
98         -- Everything is up to date; no need to recompile further
99         rnDump [] []            `thenRn` \ dump_action ->
100         returnRn (Nothing, dump_action)
101     else
102     let
103         Just (export_env, gbl_env, fixity_env, global_avail_env) = maybe_stuff
104     in
105
106         -- RENAME THE SOURCE
107     initRnMS gbl_env fixity_env SourceMode (
108         rnSourceDecls local_decls
109     )                                   `thenRn` \ (rn_local_decls, source_fvs) ->
110
111         -- SLURP IN ALL THE NEEDED DECLARATIONS
112     implicitFVs mod_name rn_local_decls         `thenRn` \ implicit_fvs -> 
113     let
114         real_source_fvs = implicit_fvs `plusFV` source_fvs
115                 -- It's important to do the "plus" this way round, so that
116                 -- when compiling the prelude, locally-defined (), Bool, etc
117                 -- override the implicit ones. 
118     in
119     slurpImpDecls real_source_fvs       `thenRn` \ rn_imp_decls ->
120     let
121         rn_all_decls       = rn_imp_decls ++ rn_local_decls 
122     in
123
124         -- EXIT IF ERRORS FOUND
125     checkErrsRn                                 `thenRn` \ no_errs_so_far ->
126     if not no_errs_so_far then
127         -- Found errors already, so exit now
128         rnDump rn_imp_decls rn_all_decls        `thenRn` \ dump_action ->
129         returnRn (Nothing, dump_action)
130     else
131
132         -- GENERATE THE VERSION/USAGE INFO
133     getImportVersions mod_name exports                  `thenRn` \ my_usages ->
134     getNameSupplyRn                                     `thenRn` \ name_supply ->
135
136         -- REPORT UNUSED NAMES
137     reportUnusedNames gbl_env global_avail_env
138                       export_env
139                       source_fvs                        `thenRn_`
140
141         -- RETURN THE RENAMED MODULE
142     let
143         has_orphans        = any isOrphanDecl rn_local_decls
144         direct_import_mods = [mod | ImportDecl mod _ _ _ _ _ <- imports]
145         renamed_module = HsModule mod_name vers 
146                                   trashed_exports trashed_imports
147                                   rn_all_decls
148                                   loc
149     in
150     rnDump rn_imp_decls rn_all_decls            `thenRn` \ dump_action ->
151     returnRn (Just (mkThisModule mod_name,
152                     renamed_module, 
153                     (has_orphans, my_usages, export_env),
154                     name_supply,
155                     direct_import_mods), dump_action)
156   where
157     trashed_exports  = {-trace "rnSource:trashed_exports"-} Nothing
158     trashed_imports  = {-trace "rnSource:trashed_imports"-} []
159 \end{code}
160
161 @implicitFVs@ forces the renamer to slurp in some things which aren't
162 mentioned explicitly, but which might be needed by the type checker.
163
164 \begin{code}
165 implicitFVs mod_name decls
166   = mapRn lookupImplicitOccRn implicit_occs     `thenRn` \ implicit_names ->
167     returnRn (implicit_main             `plusFV` 
168               mkNameSet default_tys     `plusFV`
169               mkNameSet thinAirIdNames  `plusFV`
170               mkNameSet implicit_names)
171     
172   where
173         -- Add occurrences for Int, Double, and (), because they
174         -- are the types to which ambigious type variables may be defaulted by
175         -- the type checker; so they won't always appear explicitly.
176         -- [The () one is a GHC extension for defaulting CCall results.]
177         -- ALSO: funTyCon, since it occurs implicitly everywhere!
178         --       (we don't want to be bothered with making funTyCon a
179         --        free var at every function application!)
180     default_tys = [getName intTyCon, getName doubleTyCon,
181                    getName unitTyCon, getName funTyCon, getName boolTyCon]
182
183         -- Add occurrences for IO or PrimIO
184     implicit_main |  mod_name == mAIN_Name
185                   || mod_name == pREL_MAIN_Name = unitFV ioTyCon_NAME
186                   |  otherwise                  = emptyFVs
187
188         -- Now add extra "occurrences" for things that
189         -- the deriving mechanism, or defaulting, will later need in order to
190         -- generate code
191     implicit_occs = foldr ((++) . get) [] decls
192
193     get (DefD _) = [numClass_RDR]
194     get (TyClD (TyData _ _ _ _ _ (Just deriv_classes) _ _))
195        = concat (map get_deriv deriv_classes)
196     get other = []
197
198     get_deriv cls = case lookupUFM derivingOccurrences cls of
199                         Nothing   -> []
200                         Just occs -> occs
201 \end{code}
202
203 \begin{code}
204 isOrphanDecl (InstD (InstDecl inst_ty _ _ _ _))
205   = not (foldNameSet ((||) . isLocallyDefined) False (extractHsTyNames (removeContext inst_ty)))
206         -- The 'removeContext' is because of
207         --      instance Foo a => Baz T where ...
208         -- The decl is an orphan if Baz and T are both not locally defined,
209         --      even if Foo *is* locally defined
210
211 isOrphanDecl (RuleD (RuleDecl _ _ _ lhs _ _))
212   = check lhs
213   where
214     check (HsVar v)   = not (isLocallyDefined v)
215     check (HsApp f a) = check f && check a
216     check other       = True
217 isOrphanDecl other = False
218 \end{code}
219
220
221 %*********************************************************
222 %*                                                       *
223 \subsection{Slurping declarations}
224 %*                                                       *
225 %*********************************************************
226
227 \begin{code}
228 -------------------------------------------------------
229 slurpImpDecls source_fvs
230   = traceRn (text "slurpImp" <+> fsep (map ppr (nameSetToList source_fvs))) `thenRn_`
231
232         -- The current slurped-set records all local things
233     getSlurped                                  `thenRn` \ source_binders ->
234     slurpSourceRefs source_binders source_fvs   `thenRn` \ (decls, needed) ->
235
236         -- And finally get everything else
237     closeDecls decls needed
238
239 -------------------------------------------------------
240 slurpSourceRefs :: NameSet                      -- Variables defined in source
241                 -> FreeVars                     -- Variables referenced in source
242                 -> RnMG ([RenamedHsDecl],
243                          FreeVars)              -- Un-satisfied needs
244 -- The declaration (and hence home module) of each gate has
245 -- already been loaded
246
247 slurpSourceRefs source_binders source_fvs
248   = go_outer []                         -- Accumulating decls
249              emptyFVs                   -- Unsatisfied needs
250              emptyFVs                   -- Accumulating gates
251              (nameSetToList source_fvs) -- Things whose defn hasn't been loaded yet
252   where
253         -- The outer loop repeatedly slurps the decls for the current gates
254         -- and the instance decls 
255
256         -- The outer loop is needed because consider
257         --      instance Foo a => Baz (Maybe a) where ...
258         -- It may be that @Baz@ and @Maybe@ are used in the source module,
259         -- but not @Foo@; so we need to chase @Foo@ too.
260         --
261         -- We also need to follow superclass refs.  In particular, 'chasing @Foo@' must
262         -- include actually getting in Foo's class decl
263         --      class Wib a => Foo a where ..
264         -- so that its superclasses are discovered.  The point is that Wib is a gate too.
265         -- We do this for tycons too, so that we look through type synonyms.
266
267     go_outer decls fvs all_gates []     
268         = returnRn (decls, fvs)
269
270     go_outer decls fvs all_gates refs   -- refs are not necessarily slurped yet
271         = traceRn (text "go_outer" <+> ppr refs)                `thenRn_`
272           go_inner decls fvs emptyFVs refs                      `thenRn` \ (decls1, fvs1, gates1) ->
273           getImportedInstDecls (all_gates `plusFV` gates1)      `thenRn` \ inst_decls ->
274           rnInstDecls decls1 fvs1 gates1 inst_decls             `thenRn` \ (decls2, fvs2, gates2) ->
275           go_outer decls2 fvs2 (all_gates `plusFV` gates2)
276                                (nameSetToList (gates2 `minusNameSet` all_gates))
277                 -- Knock out the all_gates because even ifwe don't slurp any new
278                 -- decls we can get some apparently-new gates from wired-in names
279
280     go_inner decls fvs gates []
281         = returnRn (decls, fvs, gates)
282
283     go_inner decls fvs gates (wanted_name:refs) 
284         | isWiredInName wanted_name
285         = load_home wanted_name         `thenRn_`
286           go_inner decls fvs (gates `plusFV` getWiredInGates wanted_name) refs
287
288         | otherwise
289         = importDecl wanted_name                `thenRn` \ maybe_decl ->
290           case maybe_decl of
291             Nothing   -> go_inner decls fvs gates refs  -- No declaration... (already slurped, or local)
292             Just decl -> rnIfaceDecl decl               `thenRn` \ (new_decl, fvs1) ->
293                          go_inner (new_decl : decls)
294                                   (fvs1 `plusFV` fvs)
295                                   (gates `plusFV` getGates source_fvs new_decl)
296                                   refs
297
298         -- When we find a wired-in name we must load its
299         -- home module so that we find any instance decls therein
300     load_home name 
301         | name `elemNameSet` source_binders = returnRn ()
302                 -- When compiling the prelude, a wired-in thing may
303                 -- be defined in this module, in which case we don't
304                 -- want to load its home module!
305                 -- Using 'isLocallyDefined' doesn't work because some of
306                 -- the free variables returned are simply 'listTyCon_Name',
307                 -- with a system provenance.  We could look them up every time
308                 -- but that seems a waste.
309         | otherwise                           = loadHomeInterface doc name      `thenRn_`
310                                                 returnRn ()
311         where
312           doc = ptext SLIT("need home module for wired in thing") <+> ppr name
313
314 rnInstDecls decls fvs gates []
315   = returnRn (decls, fvs, gates)
316 rnInstDecls decls fvs gates (d:ds) 
317   = rnIfaceDecl d               `thenRn` \ (new_decl, fvs1) ->
318     rnInstDecls (new_decl:decls) 
319                 (fvs1 `plusFV` fvs)
320                 (gates `plusFV` getInstDeclGates new_decl)
321                 ds
322 \end{code}
323
324
325 \begin{code}
326 -------------------------------------------------------
327 -- closeDecls keeps going until the free-var set is empty
328 closeDecls decls needed
329   | not (isEmptyFVs needed)
330   = slurpDecls decls needed     `thenRn` \ (decls1, needed1) ->
331     closeDecls decls1 needed1
332
333   | otherwise
334   = getImportedRules                    `thenRn` \ rule_decls ->
335     case rule_decls of
336         []    -> returnRn decls -- No new rules, so we are done
337         other -> rnIfaceDecls decls emptyFVs rule_decls         `thenRn` \ (decls1, needed1) ->
338                  closeDecls decls1 needed1
339                  
340
341 -------------------------------------------------------
342 rnIfaceDecls :: [RenamedHsDecl] -> FreeVars
343              -> [(Module, RdrNameHsDecl)]
344              -> RnM d ([RenamedHsDecl], FreeVars)
345 rnIfaceDecls decls fvs []     = returnRn (decls, fvs)
346 rnIfaceDecls decls fvs (d:ds) = rnIfaceDecl d           `thenRn` \ (new_decl, fvs1) ->
347                                 rnIfaceDecls (new_decl:decls) (fvs1 `plusFV` fvs) ds
348
349 rnIfaceDecl (mod, decl) = initIfaceRnMS mod (rnDecl decl)       
350                         
351
352 -------------------------------------------------------
353 -- Augment decls with any decls needed by needed.
354 -- Return also free vars of the new decls (only)
355 slurpDecls decls needed
356   = go decls emptyFVs (nameSetToList needed) 
357   where
358     go decls fvs []         = returnRn (decls, fvs)
359     go decls fvs (ref:refs) = slurpDecl decls fvs ref   `thenRn` \ (decls1, fvs1) ->
360                               go decls1 fvs1 refs
361
362 -------------------------------------------------------
363 slurpDecl decls fvs wanted_name
364   = importDecl wanted_name              `thenRn` \ maybe_decl ->
365     case maybe_decl of
366         -- No declaration... (wired in thing)
367         Nothing -> returnRn (decls, fvs)
368
369         -- Found a declaration... rename it
370         Just decl -> rnIfaceDecl decl           `thenRn` \ (new_decl, fvs1) ->
371                      returnRn (new_decl:decls, fvs1 `plusFV` fvs)
372 \end{code}
373
374
375 %*********************************************************
376 %*                                                       *
377 \subsection{Extracting the `gates'}
378 %*                                                       *
379 %*********************************************************
380
381 When we import a declaration like
382 \begin{verbatim}
383         data T = T1 Wibble | T2 Wobble
384 \end{verbatim}
385 we don't want to treat @Wibble@ and @Wobble@ as gates
386 {\em unless} @T1@, @T2@ respectively are mentioned by the user program.
387 If only @T@ is mentioned
388 we want only @T@ to be a gate;
389 that way we don't suck in useless instance
390 decls for (say) @Eq Wibble@, when they can't possibly be useful.
391
392 @getGates@ takes a newly imported (and renamed) decl, and the free
393 vars of the source program, and extracts from the decl the gate names.
394
395 \begin{code}
396 getGates source_fvs (SigD (IfaceSig _ ty _ _))
397   = extractHsTyNames ty
398
399 getGates source_fvs (TyClD (ClassDecl ctxt cls tvs _ sigs _ _ _ _ _ _))
400   = delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) sigs)
401                        (map getTyVarName tvs)
402     `addOneToNameSet` cls
403   where
404     get (ClassOpSig n _ _ ty _) 
405         | n `elemNameSet` source_fvs = extractHsTyNames ty
406         | otherwise                  = emptyFVs
407
408 getGates source_fvs (TyClD (TySynonym tycon tvs ty _))
409   = delListFromNameSet (extractHsTyNames ty)
410                        (map getTyVarName tvs)
411         -- A type synonym type constructor isn't a "gate" for instance decls
412
413 getGates source_fvs (TyClD (TyData _ ctxt tycon tvs cons _ _ _))
414   = delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) cons)
415                        (map getTyVarName tvs)
416     `addOneToNameSet` tycon
417   where
418     get (ConDecl n tvs ctxt details _)
419         | n `elemNameSet` source_fvs
420                 -- If the constructor is method, get fvs from all its fields
421         = delListFromNameSet (get_details details `plusFV` 
422                               extractHsCtxtTyNames ctxt)
423                              (map getTyVarName tvs)
424     get (ConDecl n tvs ctxt (RecCon fields) _)
425                 -- Even if the constructor isn't mentioned, the fields
426                 -- might be, as selectors.  They can't mention existentially
427                 -- bound tyvars (typechecker checks for that) so no need for 
428                 -- the deleteListFromNameSet part
429         = foldr (plusFV . get_field) emptyFVs fields
430         
431     get other_con = emptyFVs
432
433     get_details (VanillaCon tys) = plusFVs (map get_bang tys)
434     get_details (InfixCon t1 t2) = get_bang t1 `plusFV` get_bang t2
435     get_details (RecCon fields)  = plusFVs [get_bang t | (_, t) <- fields]
436     get_details (NewCon t _)     = extractHsTyNames t
437
438     get_field (fs,t) | any (`elemNameSet` source_fvs) fs = get_bang t
439                      | otherwise                         = emptyFVs
440
441     get_bang (Banged   t) = extractHsTyNames t
442     get_bang (Unbanged t) = extractHsTyNames t
443     get_bang (Unpacked t) = extractHsTyNames t
444
445 getGates source_fvs other_decl = emptyFVs
446 \end{code}
447
448 @getWiredInGates@ is just like @getGates@, but it sees a wired-in @Name@
449 rather than a declaration.
450
451 \begin{code}
452 getWiredInGates :: Name -> FreeVars
453 getWiredInGates name    -- No classes are wired in
454   | is_id                = getWiredInGates_s (namesOfType (idType the_id))
455   | isSynTyCon the_tycon = getWiredInGates_s
456          (delListFromNameSet (namesOfType ty) (map getName tyvars))
457   | otherwise            = unitFV name
458   where
459     maybe_wired_in_id    = maybeWiredInIdName name
460     is_id                = maybeToBool maybe_wired_in_id
461     maybe_wired_in_tycon = maybeWiredInTyConName name
462     Just the_id          = maybe_wired_in_id
463     Just the_tycon       = maybe_wired_in_tycon
464     (tyvars,ty)          = getSynTyConDefn the_tycon
465
466 getWiredInGates_s names = foldr (plusFV . getWiredInGates) emptyFVs (nameSetToList names)
467 \end{code}
468
469 \begin{code}
470 getInstDeclGates (InstD (InstDecl inst_ty _ _ _ _)) = extractHsTyNames inst_ty
471 getInstDeclGates other                              = emptyFVs
472 \end{code}
473
474
475 %*********************************************************
476 %*                                                       *
477 \subsection{Unused names}
478 %*                                                       *
479 %*********************************************************
480
481 \begin{code}
482 reportUnusedNames gbl_env avail_env (ExportEnv export_avails _) mentioned_names
483   = let
484         used_names = mentioned_names `unionNameSets` availsToNameSet export_avails
485
486         -- Now, a use of C implies a use of T,
487         -- if C was brought into scope by T(..) or T(C)
488         really_used_names = used_names `unionNameSets`
489           mkNameSet [ availName avail   
490                     | sub_name <- nameSetToList used_names,
491                       let avail = case lookupNameEnv avail_env sub_name of
492                             Just avail -> avail
493                             Nothing -> WARN( True, text "reportUnusedName: not in avail_env" <+> ppr sub_name )
494                                        Avail sub_name
495                     ]
496
497         defined_names = mkNameSet (concat (rdrEnvElts gbl_env))
498         defined_but_not_used =
499            nameSetToList (defined_names `minusNameSet` really_used_names)
500
501         -- Filter out the ones only defined implicitly
502         bad_guys = filter reportableUnusedName defined_but_not_used
503     in
504     warnUnusedTopNames bad_guys
505
506 reportableUnusedName :: Name -> Bool
507 reportableUnusedName name
508   = explicitlyImported (getNameProvenance name)
509   where
510     explicitlyImported (LocalDef _ _)                        = True
511         -- Report unused defns of local vars
512     explicitlyImported (NonLocalDef (UserImport _ _ expl) _) = expl
513         -- Report unused explicit imports
514     explicitlyImported other                                 = False
515         -- Don't report others
516
517 rnDump  :: [RenamedHsDecl]      -- Renamed imported decls
518         -> [RenamedHsDecl]      -- Renamed local decls
519         -> RnMG (IO ())
520 rnDump imp_decls decls
521         | opt_D_dump_rn_trace || 
522           opt_D_dump_rn_stats ||
523           opt_D_dump_rn 
524         = getRnStats imp_decls          `thenRn` \ stats_msg ->
525
526           returnRn (printErrs stats_msg >> 
527                     dumpIfSet opt_D_dump_rn "Renamer:" (vcat (map ppr decls)))
528
529         | otherwise = returnRn (return ())
530 \end{code}
531
532
533 %*********************************************************
534 %*                                                      *
535 \subsection{Statistics}
536 %*                                                      *
537 %*********************************************************
538
539 \begin{code}
540 getRnStats :: [RenamedHsDecl] -> RnMG SDoc
541 getRnStats imported_decls
542   = getIfacesRn                 `thenRn` \ ifaces ->
543     let
544         n_mods = length [() | (_, _, Just _) <- eltsFM (iImpModInfo ifaces)]
545
546         decls_read     = [decl | (_, avail, True, (_,decl)) <- nameEnvElts (iDecls ifaces),
547                                 -- Data, newtype, and class decls are in the decls_fm
548                                 -- under multiple names; the tycon/class, and each
549                                 -- constructor/class op too.
550                                 -- The 'True' selects just the 'main' decl
551                                  not (isLocallyDefined (availName avail))
552                              ]
553
554         (cd_rd, dd_rd, nd_rd, sd_rd, vd_rd,     _) = count_decls decls_read
555         (cd_sp, dd_sp, nd_sp, sd_sp, vd_sp, id_sp) = count_decls imported_decls
556
557         unslurped_insts       = iInsts ifaces
558         inst_decls_unslurped  = length (bagToList unslurped_insts)
559         inst_decls_read       = id_sp + inst_decls_unslurped
560
561         stats = vcat 
562                 [int n_mods <+> text "interfaces read",
563                  hsep [ int cd_sp, text "class decls imported, out of", 
564                         int cd_rd, text "read"],
565                  hsep [ int dd_sp, text "data decls imported, out of",  
566                         int dd_rd, text "read"],
567                  hsep [ int nd_sp, text "newtype decls imported, out of",  
568                         int nd_rd, text "read"],
569                  hsep [int sd_sp, text "type synonym decls imported, out of",  
570                         int sd_rd, text "read"],
571                  hsep [int vd_sp, text "value signatures imported, out of",  
572                         int vd_rd, text "read"],
573                  hsep [int id_sp, text "instance decls imported, out of",  
574                         int inst_decls_read, text "read"],
575                  text "cls dcls slurp" <+> fsep (map (ppr . tyClDeclName) 
576                                            [d | TyClD d <- imported_decls, isClassDecl d]),
577                  text "cls dcls read"  <+> fsep (map (ppr . tyClDeclName) 
578                                            [d | TyClD d <- decls_read, isClassDecl d])]
579     in
580     returnRn (hcat [text "Renamer stats: ", stats])
581
582 count_decls decls
583   = (class_decls, 
584      data_decls, 
585      newtype_decls,
586      syn_decls, 
587      val_decls, 
588      inst_decls)
589   where
590     tycl_decls = [d | TyClD d <- decls]
591     (class_decls, data_decls, newtype_decls, syn_decls) = countTyClDecls tycl_decls
592
593     val_decls     = length [() | SigD _   <- decls]
594     inst_decls    = length [() | InstD _  <- decls]
595 \end{code}    
596