2 % (c) The GRASP Project, Glasgow University, 1992-1998
4 \section[Rename]{Renaming and dependency analysis passes}
7 module Rename ( renameModule ) where
9 #include "HsVersions.h"
12 import RdrHsSyn ( RdrNameHsModule )
13 import RnHsSyn ( RenamedHsModule, RenamedHsDecl,
14 extractHsTyNames, extractHsCtxtTyNames
17 import CmdLineOpts ( opt_HiMap, opt_D_dump_rn_trace,
18 opt_D_dump_rn, opt_D_dump_rn_stats, opt_WarnDeprecations
21 import RnNames ( getGlobalNames )
22 import RnSource ( rnSourceDecls, rnDecl )
23 import RnIfaces ( getImportedInstDecls, importDecl, getImportVersions,
24 getImportedRules, loadHomeInterface, getSlurped, removeContext
26 import RnEnv ( availName, availsToNameSet,
27 warnUnusedImports, warnUnusedLocalBinds, lookupImplicitOccRn,
28 FreeVars, plusFVs, plusFV, unitFV, emptyFVs, isEmptyFVs
30 import Module ( Module, ModuleName, mkSearchPath, mkThisModule )
31 import Name ( Name, isLocallyDefined, NamedThing(..), getSrcLoc,
32 nameOccName, nameUnique, isUserImportedExplicitlyName,
33 maybeWiredInTyConName, maybeWiredInIdName, isWiredInName
35 import OccName ( occNameFlavour )
37 import TyCon ( isSynTyCon, getSynTyConDefn )
39 import PrelMods ( mAIN_Name, pREL_MAIN_Name )
40 import TysWiredIn ( unitTyCon, intTyCon, doubleTyCon, boolTyCon )
41 import PrelInfo ( ioTyCon_NAME, thinAirIdNames, fractionalClassKeys, derivingOccurrences )
42 import Type ( namesOfType, funTyCon )
43 import ErrUtils ( printErrorsAndWarnings, dumpIfSet, ghcExit )
44 import BasicTypes ( NewOrData(..) )
45 import Bag ( isEmptyBag, bagToList )
46 import FiniteMap ( eltsFM )
47 import UniqSupply ( UniqSupply )
48 import UniqFM ( lookupUFM )
49 import Maybes ( maybeToBool )
56 renameModule :: UniqSupply
60 , RenamedHsModule -- Output, after renaming
61 , InterfaceDetails -- Interface; for interface file generation
62 , RnNameSupply -- Final env; for renaming derivings
63 , [ModuleName] -- Imported modules; for profiling
66 renameModule us this_mod@(HsModule mod_name vers exports imports local_decls _ loc)
67 = -- Initialise the renamer monad
68 initRn mod_name us (mkSearchPath opt_HiMap) loc
70 \ ((maybe_rn_stuff, dump_action), rn_errs_bag, rn_warns_bag) ->
73 printErrorsAndWarnings rn_errs_bag rn_warns_bag >>
75 -- Dump any debugging output
79 if not (isEmptyBag rn_errs_bag) then
80 ghcExit 1 >> return Nothing
87 rename :: RdrNameHsModule
88 -> RnMG (Maybe (Module, RenamedHsModule, InterfaceDetails, RnNameSupply, [ModuleName]), IO ())
89 rename this_mod@(HsModule mod_name vers _ imports local_decls mod_deprec loc)
90 = -- FIND THE GLOBAL NAME ENVIRONMENT
91 getGlobalNames this_mod `thenRn` \ maybe_stuff ->
93 -- CHECK FOR EARLY EXIT
94 if not (maybeToBool maybe_stuff) then
95 -- Everything is up to date; no need to recompile further
96 rnDump [] [] `thenRn` \ dump_action ->
97 returnRn (Nothing, dump_action)
100 Just (export_env, gbl_env, fixity_env, global_avail_env) = maybe_stuff
104 initRnMS gbl_env fixity_env SourceMode (
105 rnSourceDecls local_decls
106 ) `thenRn` \ (rn_local_decls, source_fvs) ->
108 -- SLURP IN ALL THE NEEDED DECLARATIONS
109 implicitFVs mod_name rn_local_decls `thenRn` \ implicit_fvs ->
111 real_source_fvs = implicit_fvs `plusFV` source_fvs
112 -- It's important to do the "plus" this way round, so that
113 -- when compiling the prelude, locally-defined (), Bool, etc
114 -- override the implicit ones.
116 slurpImpDecls real_source_fvs `thenRn` \ rn_imp_decls ->
118 rn_all_decls = rn_local_decls ++ rn_imp_decls
120 -- COLLECT ALL DEPRECATIONS
121 deprec_sigs = [ ds | ValD bnds <- rn_local_decls, ds <- collectDeprecs bnds ]
122 deprecs = case mod_deprec of
123 Nothing -> deprec_sigs
124 Just txt -> Deprecation (IEModuleContents undefined) txt : deprec_sigs
127 -- EXIT IF ERRORS FOUND
128 checkErrsRn `thenRn` \ no_errs_so_far ->
129 if not no_errs_so_far then
130 -- Found errors already, so exit now
131 rnDump rn_imp_decls rn_all_decls `thenRn` \ dump_action ->
132 returnRn (Nothing, dump_action)
135 -- GENERATE THE VERSION/USAGE INFO
136 getImportVersions mod_name export_env `thenRn` \ my_usages ->
137 getNameSupplyRn `thenRn` \ name_supply ->
139 -- REPORT UNUSED NAMES
140 reportUnusedNames gbl_env global_avail_env
144 -- RETURN THE RENAMED MODULE
146 has_orphans = any isOrphanDecl rn_local_decls
147 direct_import_mods = [mod | ImportDecl mod _ _ _ _ _ <- imports]
148 renamed_module = HsModule mod_name vers
149 trashed_exports trashed_imports
154 rnDump rn_imp_decls rn_all_decls `thenRn` \ dump_action ->
155 returnRn (Just (mkThisModule mod_name,
157 (InterfaceDetails has_orphans my_usages export_env deprecs),
159 direct_import_mods), dump_action)
161 trashed_exports = {-trace "rnSource:trashed_exports"-} Nothing
162 trashed_imports = {-trace "rnSource:trashed_imports"-} []
164 collectDeprecs EmptyBinds = []
165 collectDeprecs (ThenBinds x y) = collectDeprecs x ++ collectDeprecs y
166 collectDeprecs (MonoBind _ sigs _) = [ d | DeprecSig d _ <- sigs ]
169 @implicitFVs@ forces the renamer to slurp in some things which aren't
170 mentioned explicitly, but which might be needed by the type checker.
173 implicitFVs mod_name decls
174 = mapRn lookupImplicitOccRn implicit_occs `thenRn` \ implicit_names ->
175 returnRn (implicit_main `plusFV`
176 mkNameSet (map getName default_tycons) `plusFV`
177 mkNameSet thinAirIdNames `plusFV`
178 mkNameSet implicit_names)
180 -- Add occurrences for Int, and (), because they
181 -- are the types to which ambigious type variables may be defaulted by
182 -- the type checker; so they won't always appear explicitly.
183 -- [The () one is a GHC extension for defaulting CCall results.]
184 -- ALSO: funTyCon, since it occurs implicitly everywhere!
185 -- (we don't want to be bothered with making funTyCon a
186 -- free var at every function application!)
187 -- Double is dealt with separately in getGates
188 default_tycons = [unitTyCon, funTyCon, boolTyCon, intTyCon]
190 -- Add occurrences for IO or PrimIO
191 implicit_main | mod_name == mAIN_Name
192 || mod_name == pREL_MAIN_Name = unitFV ioTyCon_NAME
193 | otherwise = emptyFVs
195 -- Now add extra "occurrences" for things that
196 -- the deriving mechanism, or defaulting, will later need in order to
198 implicit_occs = foldr ((++) . get) [] decls
200 get (TyClD (TyData _ _ _ _ _ (Just deriv_classes) _ _))
201 = concat (map get_deriv deriv_classes)
204 get_deriv cls = case lookupUFM derivingOccurrences cls of
210 isOrphanDecl (InstD (InstDecl inst_ty _ _ _ _))
211 = not (foldNameSet ((||) . isLocallyDefined) False (extractHsTyNames (removeContext inst_ty)))
212 -- The 'removeContext' is because of
213 -- instance Foo a => Baz T where ...
214 -- The decl is an orphan if Baz and T are both not locally defined,
215 -- even if Foo *is* locally defined
217 isOrphanDecl (RuleD (RuleDecl _ _ _ lhs _ _))
220 -- At the moment we just check for common LHS forms
221 -- Expand as necessary. Getting it wrong just means
222 -- more orphans than necessary
223 check (HsVar v) = not (isLocallyDefined v)
224 check (HsApp f a) = check f && check a
225 check (HsLit _) = False
226 check (OpApp l o _ r) = check l && check o && check r
227 check (NegApp e _) = check e
228 check (HsPar e) = check e
229 check (SectionL e o) = check e && check o
230 check (SectionR o e) = check e && check o
232 check other = True -- Safe fall through
234 isOrphanDecl other = False
239 dupDefaultDeclErrRn (DefaultDecl _ locn1 : dup_things)
240 = pushSrcLocRn locn1 $
243 msg = hang (ptext SLIT("Multiple default declarations"))
244 4 (vcat (map pp dup_things))
245 pp (DefaultDecl _ locn) = ptext SLIT("here was another default declaration") <+> ppr locn
249 %*********************************************************
251 \subsection{Slurping declarations}
253 %*********************************************************
256 -------------------------------------------------------
257 slurpImpDecls source_fvs
258 = traceRn (text "slurpImp" <+> fsep (map ppr (nameSetToList source_fvs))) `thenRn_`
260 -- The current slurped-set records all local things
261 getSlurped `thenRn` \ source_binders ->
262 slurpSourceRefs source_binders source_fvs `thenRn` \ (decls, needed) ->
264 -- And finally get everything else
265 closeDecls decls needed
267 -------------------------------------------------------
268 slurpSourceRefs :: NameSet -- Variables defined in source
269 -> FreeVars -- Variables referenced in source
270 -> RnMG ([RenamedHsDecl],
271 FreeVars) -- Un-satisfied needs
272 -- The declaration (and hence home module) of each gate has
273 -- already been loaded
275 slurpSourceRefs source_binders source_fvs
276 = go_outer [] -- Accumulating decls
277 emptyFVs -- Unsatisfied needs
278 emptyFVs -- Accumulating gates
279 (nameSetToList source_fvs) -- Things whose defn hasn't been loaded yet
281 -- The outer loop repeatedly slurps the decls for the current gates
282 -- and the instance decls
284 -- The outer loop is needed because consider
285 -- instance Foo a => Baz (Maybe a) where ...
286 -- It may be that @Baz@ and @Maybe@ are used in the source module,
287 -- but not @Foo@; so we need to chase @Foo@ too.
289 -- We also need to follow superclass refs. In particular, 'chasing @Foo@' must
290 -- include actually getting in Foo's class decl
291 -- class Wib a => Foo a where ..
292 -- so that its superclasses are discovered. The point is that Wib is a gate too.
293 -- We do this for tycons too, so that we look through type synonyms.
295 go_outer decls fvs all_gates []
296 = returnRn (decls, fvs)
298 go_outer decls fvs all_gates refs -- refs are not necessarily slurped yet
299 = traceRn (text "go_outer" <+> ppr refs) `thenRn_`
300 go_inner decls fvs emptyFVs refs `thenRn` \ (decls1, fvs1, gates1) ->
301 getImportedInstDecls (all_gates `plusFV` gates1) `thenRn` \ inst_decls ->
302 rnInstDecls decls1 fvs1 gates1 inst_decls `thenRn` \ (decls2, fvs2, gates2) ->
303 go_outer decls2 fvs2 (all_gates `plusFV` gates2)
304 (nameSetToList (gates2 `minusNameSet` all_gates))
305 -- Knock out the all_gates because even if we don't slurp any new
306 -- decls we can get some apparently-new gates from wired-in names
308 go_inner decls fvs gates []
309 = returnRn (decls, fvs, gates)
311 go_inner decls fvs gates (wanted_name:refs)
312 | isWiredInName wanted_name
313 = load_home wanted_name `thenRn_`
314 go_inner decls fvs (gates `plusFV` getWiredInGates wanted_name) refs
317 = importDecl wanted_name `thenRn` \ maybe_decl ->
319 Nothing -> go_inner decls fvs gates refs -- No declaration... (already slurped, or local)
320 Just decl -> rnIfaceDecl decl `thenRn` \ (new_decl, fvs1) ->
321 go_inner (new_decl : decls)
323 (gates `plusFV` getGates source_fvs new_decl)
326 -- When we find a wired-in name we must load its
327 -- home module so that we find any instance decls therein
329 | name `elemNameSet` source_binders = returnRn ()
330 -- When compiling the prelude, a wired-in thing may
331 -- be defined in this module, in which case we don't
332 -- want to load its home module!
333 -- Using 'isLocallyDefined' doesn't work because some of
334 -- the free variables returned are simply 'listTyCon_Name',
335 -- with a system provenance. We could look them up every time
336 -- but that seems a waste.
337 | otherwise = loadHomeInterface doc name `thenRn_`
340 doc = ptext SLIT("need home module for wired in thing") <+> ppr name
342 rnInstDecls decls fvs gates []
343 = returnRn (decls, fvs, gates)
344 rnInstDecls decls fvs gates (d:ds)
345 = rnIfaceDecl d `thenRn` \ (new_decl, fvs1) ->
346 rnInstDecls (new_decl:decls)
348 (gates `plusFV` getInstDeclGates new_decl)
354 -------------------------------------------------------
355 -- closeDecls keeps going until the free-var set is empty
356 closeDecls decls needed
357 | not (isEmptyFVs needed)
358 = slurpDecls decls needed `thenRn` \ (decls1, needed1) ->
359 closeDecls decls1 needed1
362 = getImportedRules `thenRn` \ rule_decls ->
364 [] -> returnRn decls -- No new rules, so we are done
365 other -> rnIfaceDecls decls emptyFVs rule_decls `thenRn` \ (decls1, needed1) ->
366 closeDecls decls1 needed1
369 -------------------------------------------------------
370 rnIfaceDecls :: [RenamedHsDecl] -> FreeVars
371 -> [(Module, RdrNameHsDecl)]
372 -> RnM d ([RenamedHsDecl], FreeVars)
373 rnIfaceDecls decls fvs [] = returnRn (decls, fvs)
374 rnIfaceDecls decls fvs (d:ds) = rnIfaceDecl d `thenRn` \ (new_decl, fvs1) ->
375 rnIfaceDecls (new_decl:decls) (fvs1 `plusFV` fvs) ds
377 rnIfaceDecl (mod, decl) = initIfaceRnMS mod (rnDecl decl)
380 -------------------------------------------------------
381 -- Augment decls with any decls needed by needed.
382 -- Return also free vars of the new decls (only)
383 slurpDecls decls needed
384 = go decls emptyFVs (nameSetToList needed)
386 go decls fvs [] = returnRn (decls, fvs)
387 go decls fvs (ref:refs) = slurpDecl decls fvs ref `thenRn` \ (decls1, fvs1) ->
390 -------------------------------------------------------
391 slurpDecl decls fvs wanted_name
392 = importDecl wanted_name `thenRn` \ maybe_decl ->
394 -- No declaration... (wired in thing)
395 Nothing -> returnRn (decls, fvs)
397 -- Found a declaration... rename it
398 Just decl -> rnIfaceDecl decl `thenRn` \ (new_decl, fvs1) ->
399 returnRn (new_decl:decls, fvs1 `plusFV` fvs)
403 %*********************************************************
405 \subsection{Extracting the `gates'}
407 %*********************************************************
409 When we import a declaration like
411 data T = T1 Wibble | T2 Wobble
413 we don't want to treat @Wibble@ and @Wobble@ as gates
414 {\em unless} @T1@, @T2@ respectively are mentioned by the user program.
415 If only @T@ is mentioned
416 we want only @T@ to be a gate;
417 that way we don't suck in useless instance
418 decls for (say) @Eq Wibble@, when they can't possibly be useful.
420 @getGates@ takes a newly imported (and renamed) decl, and the free
421 vars of the source program, and extracts from the decl the gate names.
424 getGates source_fvs (SigD (IfaceSig _ ty _ _))
425 = extractHsTyNames ty
427 getGates source_fvs (TyClD (ClassDecl ctxt cls tvs _ sigs _ _ _ _ _ _))
428 = (delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) sigs)
429 (map getTyVarName tvs)
430 `addOneToNameSet` cls)
431 `plusFV` maybe_double
433 get (ClassOpSig n _ _ ty _)
434 | n `elemNameSet` source_fvs = extractHsTyNames ty
435 | otherwise = emptyFVs
437 -- If we load any numeric class that doesn't have
438 -- Int as an instance, add Double to the gates.
439 -- This takes account of the fact that Double might be needed for
440 -- defaulting, but we don't want to load Double (and all its baggage)
441 -- if the more exotic classes aren't used at all.
442 maybe_double | nameUnique cls `elem` fractionalClassKeys
443 = unitFV (getName doubleTyCon)
447 getGates source_fvs (TyClD (TySynonym tycon tvs ty _))
448 = delListFromNameSet (extractHsTyNames ty)
449 (map getTyVarName tvs)
450 -- A type synonym type constructor isn't a "gate" for instance decls
452 getGates source_fvs (TyClD (TyData _ ctxt tycon tvs cons _ _ _))
453 = delListFromNameSet (foldr (plusFV . get) (extractHsCtxtTyNames ctxt) cons)
454 (map getTyVarName tvs)
455 `addOneToNameSet` tycon
457 get (ConDecl n tvs ctxt details _)
458 | n `elemNameSet` source_fvs
459 -- If the constructor is method, get fvs from all its fields
460 = delListFromNameSet (get_details details `plusFV`
461 extractHsCtxtTyNames ctxt)
462 (map getTyVarName tvs)
463 get (ConDecl n tvs ctxt (RecCon fields) _)
464 -- Even if the constructor isn't mentioned, the fields
465 -- might be, as selectors. They can't mention existentially
466 -- bound tyvars (typechecker checks for that) so no need for
467 -- the deleteListFromNameSet part
468 = foldr (plusFV . get_field) emptyFVs fields
470 get other_con = emptyFVs
472 get_details (VanillaCon tys) = plusFVs (map get_bang tys)
473 get_details (InfixCon t1 t2) = get_bang t1 `plusFV` get_bang t2
474 get_details (RecCon fields) = plusFVs [get_bang t | (_, t) <- fields]
475 get_details (NewCon t _) = extractHsTyNames t
477 get_field (fs,t) | any (`elemNameSet` source_fvs) fs = get_bang t
478 | otherwise = emptyFVs
480 get_bang (Banged t) = extractHsTyNames t
481 get_bang (Unbanged t) = extractHsTyNames t
482 get_bang (Unpacked t) = extractHsTyNames t
484 getGates source_fvs other_decl = emptyFVs
487 @getWiredInGates@ is just like @getGates@, but it sees a wired-in @Name@
488 rather than a declaration.
491 getWiredInGates :: Name -> FreeVars
492 getWiredInGates name -- No classes are wired in
493 | is_id = getWiredInGates_s (namesOfType (idType the_id))
494 | isSynTyCon the_tycon = getWiredInGates_s
495 (delListFromNameSet (namesOfType ty) (map getName tyvars))
496 | otherwise = unitFV name
498 maybe_wired_in_id = maybeWiredInIdName name
499 is_id = maybeToBool maybe_wired_in_id
500 maybe_wired_in_tycon = maybeWiredInTyConName name
501 Just the_id = maybe_wired_in_id
502 Just the_tycon = maybe_wired_in_tycon
503 (tyvars,ty) = getSynTyConDefn the_tycon
505 getWiredInGates_s names = foldr (plusFV . getWiredInGates) emptyFVs (nameSetToList names)
509 getInstDeclGates (InstD (InstDecl inst_ty _ _ _ _)) = extractHsTyNames inst_ty
510 getInstDeclGates other = emptyFVs
514 %*********************************************************
516 \subsection{Unused names}
518 %*********************************************************
521 reportUnusedNames :: GlobalRdrEnv -> NameEnv AvailInfo -> ExportEnv -> NameSet -> RnM d ()
522 reportUnusedNames gbl_env avail_env (ExportEnv export_avails _ _) mentioned_names
524 used_names = mentioned_names `unionNameSets` availsToNameSet export_avails
526 -- Now, a use of C implies a use of T,
527 -- if C was brought into scope by T(..) or T(C)
528 really_used_names = used_names `unionNameSets`
529 mkNameSet [ availName avail
530 | sub_name <- nameSetToList used_names,
531 let avail = case lookupNameEnv avail_env sub_name of
533 Nothing -> WARN( True, text "reportUnusedName: not in avail_env" <+> ppr sub_name )
537 defined_names = mkNameSet (concat (rdrEnvElts gbl_env))
538 defined_but_not_used =
539 nameSetToList (defined_names `minusNameSet` really_used_names)
541 -- Filter out the ones only defined implicitly
542 bad_locals = [n | n <- defined_but_not_used, isLocallyDefined n]
543 bad_imps = [n | n <- defined_but_not_used, isUserImportedExplicitlyName n]
545 non_locally_used = [ n | n <- nameSetToList really_used_names, not (isLocallyDefined n) ]
546 deprec_used deprec_env = [ (n,txt) | n <- non_locally_used, Just txt <- [lookupNameEnv deprec_env n] ]
548 traceRn (text "really used and non-locally defined" <> colon <+>
549 nest 4 (fsep (punctuate comma [ text (occNameFlavour (nameOccName n)) <+> ppr n
550 | n <- non_locally_used]))) `thenRn_`
551 getIfacesRn `thenRn` \ ifaces ->
552 if opt_WarnDeprecations
553 then mapRn_ warnDeprec (deprec_used (iDeprecs ifaces))
554 else returnRn () `thenRn_`
555 warnUnusedLocalBinds bad_locals `thenRn_`
556 warnUnusedImports bad_imps
558 warnDeprec :: (Name, DeprecTxt) -> RnM d ()
559 warnDeprec (name, txt)
560 = pushSrcLocRn (getSrcLoc name) $
562 sep [ text "Using deprecated entity" <+> ppr name <> colon, nest 4 (ppr txt) ]
564 rnDump :: [RenamedHsDecl] -- Renamed imported decls
565 -> [RenamedHsDecl] -- Renamed local decls
567 rnDump imp_decls decls
568 | opt_D_dump_rn_trace ||
569 opt_D_dump_rn_stats ||
571 = getRnStats imp_decls `thenRn` \ stats_msg ->
573 returnRn (printErrs stats_msg >>
574 dumpIfSet opt_D_dump_rn "Renamer:" (vcat (map ppr decls)))
576 | otherwise = returnRn (return ())
580 %*********************************************************
582 \subsection{Statistics}
584 %*********************************************************
587 getRnStats :: [RenamedHsDecl] -> RnMG SDoc
588 getRnStats imported_decls
589 = getIfacesRn `thenRn` \ ifaces ->
591 n_mods = length [() | (_, _, Just _) <- eltsFM (iImpModInfo ifaces)]
593 decls_read = [decl | (_, avail, True, (_,decl)) <- nameEnvElts (iDecls ifaces),
594 -- Data, newtype, and class decls are in the decls_fm
595 -- under multiple names; the tycon/class, and each
596 -- constructor/class op too.
597 -- The 'True' selects just the 'main' decl
598 not (isLocallyDefined (availName avail))
601 (cd_rd, dd_rd, nd_rd, sd_rd, vd_rd, _) = count_decls decls_read
602 (cd_sp, dd_sp, nd_sp, sd_sp, vd_sp, id_sp) = count_decls imported_decls
604 unslurped_insts = iInsts ifaces
605 inst_decls_unslurped = length (bagToList unslurped_insts)
606 inst_decls_read = id_sp + inst_decls_unslurped
609 [int n_mods <+> text "interfaces read",
610 hsep [ int cd_sp, text "class decls imported, out of",
611 int cd_rd, text "read"],
612 hsep [ int dd_sp, text "data decls imported, out of",
613 int dd_rd, text "read"],
614 hsep [ int nd_sp, text "newtype decls imported, out of",
615 int nd_rd, text "read"],
616 hsep [int sd_sp, text "type synonym decls imported, out of",
617 int sd_rd, text "read"],
618 hsep [int vd_sp, text "value signatures imported, out of",
619 int vd_rd, text "read"],
620 hsep [int id_sp, text "instance decls imported, out of",
621 int inst_decls_read, text "read"],
622 text "cls dcls slurp" <+> fsep (map (ppr . tyClDeclName)
623 [d | TyClD d <- imported_decls, isClassDecl d]),
624 text "cls dcls read" <+> fsep (map (ppr . tyClDeclName)
625 [d | TyClD d <- decls_read, isClassDecl d])]
627 returnRn (hcat [text "Renamer stats: ", stats])
637 tycl_decls = [d | TyClD d <- decls]
638 (class_decls, data_decls, newtype_decls, syn_decls) = countTyClDecls tycl_decls
640 val_decls = length [() | SigD _ <- decls]
641 inst_decls = length [() | InstD _ <- decls]