+\begin{code}
+reportUnusedNames (RnEnv gbl_env _) avail_env (ExportEnv export_avails _) mentioned_names
+ | not (opt_WarnUnusedBinds || opt_WarnUnusedImports)
+ = returnRn ()
+
+ | otherwise
+ = let
+ used_names = mentioned_names `unionNameSets` availsToNameSet export_avails
+
+ -- Now, a use of C implies a use of T,
+ -- if C was brought into scope by T(..) or T(C)
+ really_used_names = used_names `unionNameSets`
+ mkNameSet [ availName avail
+ | sub_name <- nameSetToList used_names,
+ let avail = case lookupNameEnv avail_env sub_name of
+ Just avail -> avail
+ Nothing -> pprTrace "r.u.n" (ppr sub_name) $
+ Avail sub_name
+ ]
+
+ defined_names = mkNameSet (concat (rdrEnvElts gbl_env))
+ defined_but_not_used = defined_names `minusNameSet` really_used_names
+
+ -- Filter out the ones only defined implicitly or whose OccNames
+ -- start with an '_', which we won't report.
+ bad_guys = filter is_explicit (nameSetToList defined_but_not_used)
+ is_explicit n = case getNameProvenance n of
+ LocalDef _ _ -> True
+ NonLocalDef (UserImport _ _ explicit) _ _ -> explicit
+ other -> False
+
+ -- Now group by whether locally defined or imported;
+ -- one group is the locally-defined ones, one group per import module
+ groups = equivClasses cmp bad_guys
+ where
+ name1 `cmp` name2 = getNameProvenance name1 `cmph` getNameProvenance name2
+
+ cmph (LocalDef _ _) (NonLocalDef _ _ _) = LT
+ cmph (LocalDef _ _) (LocalDef _ _) = EQ
+ cmph (NonLocalDef (UserImport m1 _ _) _ _)
+ (NonLocalDef (UserImport m2 _ _) _ _)
+ = m1 `compare` m2
+ cmph (NonLocalDef _ _ _) (LocalDef _ _) = GT
+ -- In-scope NonLocalDefs must have UserImport info on them
+
+ -- ToDo: report somehow on T(..) things where no constructors
+ -- are imported
+ in
+ mapRn warnUnusedTopNames groups `thenRn_`
+ returnRn ()
+
+rnStats :: [RenamedHsDecl] -> RnMG ()
+rnStats all_decls
+ | opt_D_show_rn_trace ||
+ opt_D_show_rn_stats ||
+ opt_D_dump_rn
+ = getRnStats all_decls `thenRn` \ msg ->
+ ioToRnMG (printErrs msg) `thenRn_`
+ returnRn ()
+
+ | otherwise = returnRn ()