Skip to content
Snippets Groups Projects
Commit 525898a9 authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

[project @ 2000-07-06 16:31:45 by simonpj]

* Improve the warning "M is imported but nothing from it is used"
  In particular, don't warn if some instances from it are imported.

  It's pretty much impossible to do the Right Thing always.
  A comment in Rename.lhs says
	-- NOTE: Consider
	--	      module This
	--		import M ()
	--
	--	 The import M() is not *necessarily* redundant, even if
	-- 	 we suck in no instance decls from M (e.g. it contains
	--	 no instance decls, or This contains no code).  It may be
	--	 that we import M solely to ensure that M's orphan instance
	--	 decls (or those in its imports) are visible to people who
	--	 import This.  Sigh.
	--	 There's really no good way to detect this, so the error message
	--	 in RnEnv.warnUnusedModules is weakened instead

* Minor comment changes to RnIfaces.lhs

* Use NameEnv instead of UFM in TcEnv (tidy up only)
parent 89cefac8
No related merge requests found
...@@ -26,7 +26,8 @@ import RnIfaces ( getImportedInstDecls, importDecl, mkImportExportInfo, getInte ...@@ -26,7 +26,8 @@ import RnIfaces ( getImportedInstDecls, importDecl, mkImportExportInfo, getInte
getImportedRules, loadHomeInterface, getSlurped, removeContext, getImportedRules, loadHomeInterface, getSlurped, removeContext,
loadBuiltinRules, getDeferredDecls, ImportDeclResult(..) loadBuiltinRules, getDeferredDecls, ImportDeclResult(..)
) )
import RnEnv ( availName, availsToNameSet, unitAvailEnv, availEnvElts, plusAvailEnv, import RnEnv ( availName, availsToNameSet,
emptyAvailEnv, unitAvailEnv, availEnvElts, plusAvailEnv,
warnUnusedImports, warnUnusedLocalBinds, warnUnusedModules, warnUnusedImports, warnUnusedLocalBinds, warnUnusedModules,
lookupImplicitOccsRn, pprAvail, unknownNameErr, lookupImplicitOccsRn, pprAvail, unknownNameErr,
FreeVars, plusFVs, plusFV, unitFV, emptyFVs, isEmptyFVs, addOneFV FreeVars, plusFVs, plusFV, unitFV, emptyFVs, isEmptyFVs, addOneFV
...@@ -54,7 +55,9 @@ import Type ( namesOfType, funTyCon ) ...@@ -54,7 +55,9 @@ import Type ( namesOfType, funTyCon )
import ErrUtils ( printErrorsAndWarnings, dumpIfSet, ghcExit ) import ErrUtils ( printErrorsAndWarnings, dumpIfSet, ghcExit )
import BasicTypes ( Version, initialVersion ) import BasicTypes ( Version, initialVersion )
import Bag ( isEmptyBag, bagToList ) import Bag ( isEmptyBag, bagToList )
import FiniteMap ( FiniteMap, eltsFM, fmToList, emptyFM, lookupFM, addToFM_C ) import FiniteMap ( FiniteMap, eltsFM, fmToList, emptyFM, lookupFM,
addToFM_C, elemFM, addToFM
)
import UniqSupply ( UniqSupply ) import UniqSupply ( UniqSupply )
import UniqFM ( lookupUFM ) import UniqFM ( lookupUFM )
import SrcLoc ( noSrcLoc ) import SrcLoc ( noSrcLoc )
...@@ -192,7 +195,8 @@ rename this_mod@(HsModule mod_name vers exports imports local_decls mod_deprec l ...@@ -192,7 +195,8 @@ rename this_mod@(HsModule mod_name vers exports imports local_decls mod_deprec l
-- REPORT UNUSED NAMES, AND DEBUG DUMP -- REPORT UNUSED NAMES, AND DEBUG DUMP
reportUnusedNames mod_name direct_import_mods reportUnusedNames mod_name direct_import_mods
gbl_env global_avail_env gbl_env global_avail_env
export_avails source_fvs `thenRn_` export_avails source_fvs
rn_imp_decls `thenRn_`
returnRn (Just result, dump_action) } returnRn (Just result, dump_action) }
where where
...@@ -654,10 +658,12 @@ rnDeprecs gbl_env mod_deprec decls ...@@ -654,10 +658,12 @@ rnDeprecs gbl_env mod_deprec decls
\begin{code} \begin{code}
reportUnusedNames :: ModuleName -> [ModuleName] reportUnusedNames :: ModuleName -> [ModuleName]
-> GlobalRdrEnv -> AvailEnv -> GlobalRdrEnv -> AvailEnv
-> Avails -> NameSet -> RnMG () -> Avails -> NameSet -> [RenamedHsDecl]
-> RnMG ()
reportUnusedNames mod_name direct_import_mods reportUnusedNames mod_name direct_import_mods
gbl_env avail_env gbl_env avail_env
export_avails mentioned_names export_avails mentioned_names
imported_decls
= let = let
used_names = mentioned_names `unionNameSets` availsToNameSet export_avails used_names = mentioned_names `unionNameSets` availsToNameSet export_avails
...@@ -682,7 +688,8 @@ reportUnusedNames mod_name direct_import_mods ...@@ -682,7 +688,8 @@ reportUnusedNames mod_name direct_import_mods
= case lookupNameEnv avail_env sub_name of = case lookupNameEnv avail_env sub_name of
Just avail -> avail Just avail -> avail
Nothing -> WARN( isUserImportedName sub_name, Nothing -> WARN( isUserImportedName sub_name,
text "reportUnusedName: not in avail_env" <+> ppr sub_name ) text "reportUnusedName: not in avail_env" <+>
ppr sub_name )
Avail sub_name Avail sub_name
, case parent_avail of { AvailTC _ _ -> True; other -> False } , case parent_avail of { AvailTC _ _ -> True; other -> False }
...@@ -702,12 +709,35 @@ reportUnusedNames mod_name direct_import_mods ...@@ -702,12 +709,35 @@ reportUnusedNames mod_name direct_import_mods
not (isLocallyDefined n), not (isLocallyDefined n),
Just txt <- [lookupNameEnv deprec_env n] ] Just txt <- [lookupNameEnv deprec_env n] ]
-- inst_mods are directly-imported modules that
-- contain instance decl(s) that the renamer decided to suck in
-- It's not necessarily redundant to import such modules.
-- NOTE: import M () is not necessarily redundant, even if
-- we suck in no instance decls from M (e.g. it contains
-- no instance decls). It may be that we import M solely to
-- ensure that M's orphan instance decls (or those in its imports)
-- are visible to people who import this module. Sigh. There's
-- really no good way to detect this, so the error message is weakened
inst_mods = [m | InstD (InstDecl _ _ _ dfun _) <- imported_decls,
let m = moduleName (nameModule dfun),
m `elem` direct_import_mods
]
minimal_imports :: FiniteMap ModuleName AvailEnv minimal_imports :: FiniteMap ModuleName AvailEnv
minimal_imports = foldNameSet add emptyFM really_used_names minimal_imports0 = emptyFM
add n acc = case maybeUserImportedFrom n of minimal_imports1 = foldNameSet add_name minimal_imports0 really_used_names
Nothing -> acc minimal_imports = foldr add_inst_mod minimal_imports1 inst_mods
Just m -> addToFM_C plusAvailEnv acc (moduleName m)
(unitAvailEnv (mk_avail n)) add_name n acc = case maybeUserImportedFrom n of
Nothing -> acc
Just m -> addToFM_C plusAvailEnv acc (moduleName m)
(unitAvailEnv (mk_avail n))
add_inst_mod m acc
| m `elemFM` acc = acc -- We import something already
| otherwise = addToFM acc m emptyAvailEnv
-- Add an empty collection of imports for a module
-- from which we have sucked only instance decls
mk_avail n = case lookupNameEnv avail_env n of mk_avail n = case lookupNameEnv avail_env n of
Just (AvailTC m _) | n==m -> AvailTC n [n] Just (AvailTC m _) | n==m -> AvailTC n [n]
| otherwise -> AvailTC m [n,m] | otherwise -> AvailTC m [n,m]
......
...@@ -763,8 +763,10 @@ warnUnusedModules mods ...@@ -763,8 +763,10 @@ warnUnusedModules mods
| not opt_WarnUnusedImports = returnRn () | not opt_WarnUnusedImports = returnRn ()
| otherwise = mapRn_ (addWarnRn . unused_mod) mods | otherwise = mapRn_ (addWarnRn . unused_mod) mods
where where
unused_mod m = ptext SLIT("Module") <+> quotes (pprModuleName m) <+> unused_mod m = vcat [ptext SLIT("Module") <+> quotes (pprModuleName m) <+>
text "is imported, but nothing from it is used" text "is imported, but nothing from it is used",
parens (ptext SLIT("except perhaps to re-export instances visible in") <+>
quotes (pprModuleName m))]
warnUnusedLocalBinds, warnUnusedImports, warnUnusedMatches :: [Name] -> RnM d () warnUnusedLocalBinds, warnUnusedImports, warnUnusedMatches :: [Name] -> RnM d ()
warnUnusedImports names warnUnusedImports names
......
...@@ -364,9 +364,9 @@ loadFixDecl mod_name sig@(FixitySig rdr_name fixity loc) ...@@ -364,9 +364,9 @@ loadFixDecl mod_name sig@(FixitySig rdr_name fixity loc)
----------------------------------------------------- -----------------------------------------------------
loadInstDecl :: Module loadInstDecl :: Module
-> Bag GatedDecl -> IfaceInsts
-> RdrNameInstDecl -> RdrNameInstDecl
-> RnM d (Bag GatedDecl) -> RnM d IfaceInsts
loadInstDecl mod insts decl@(InstDecl inst_ty binds uprags dfun_name src_loc) loadInstDecl mod insts decl@(InstDecl inst_ty binds uprags dfun_name src_loc)
= =
-- Find out what type constructors and classes are "gates" for the -- Find out what type constructors and classes are "gates" for the
......
...@@ -314,21 +314,19 @@ data Ifaces = Ifaces { ...@@ -314,21 +314,19 @@ data Ifaces = Ifaces {
-- This is used to generate the "usage" information for this module. -- This is used to generate the "usage" information for this module.
-- Subset of the previous field. -- Subset of the previous field.
iInsts :: Bag GatedDecl, iInsts :: IfaceInsts,
-- The as-yet un-slurped instance decls; this bag is depleted when we -- The as-yet un-slurped instance decls; this bag is depleted when we
-- slurp an instance decl so that we don't slurp the same one twice. -- slurp an instance decl so that we don't slurp the same one twice.
-- Each is 'gated' by the names that must be available before -- Each is 'gated' by the names that must be available before
-- this instance decl is needed. -- this instance decl is needed.
iRules :: IfaceRules, iRules :: IfaceRules,
-- Similar to instance decls, except that we track the version number of the -- Similar to instance decls, only for rules
-- rules we import from each module
-- [We keep just one rule-version number for each module]
-- The Bool is True if we import any rules at all from that module
iDeprecs :: DeprecationEnv iDeprecs :: DeprecationEnv
} }
type IfaceInsts = Bag GatedDecl
type IfaceRules = Bag GatedDecl type IfaceRules = Bag GatedDecl
type GatedDecl = (NameSet, (Module, RdrNameHsDecl)) type GatedDecl = (NameSet, (Module, RdrNameHsDecl))
......
...@@ -61,7 +61,9 @@ import BasicTypes ( Arity ) ...@@ -61,7 +61,9 @@ import BasicTypes ( Arity )
import IdInfo ( vanillaIdInfo ) import IdInfo ( vanillaIdInfo )
import Name ( Name, OccName, nameOccName, getSrcLoc, import Name ( Name, OccName, nameOccName, getSrcLoc,
maybeWiredInTyConName, maybeWiredInIdName, isLocallyDefined, maybeWiredInTyConName, maybeWiredInIdName, isLocallyDefined,
NamedThing(..) NamedThing(..),
NameEnv, emptyNameEnv, addToNameEnv,
extendNameEnv, lookupNameEnv, nameEnvElts
) )
import Unique ( pprUnique10, Unique, Uniquable(..) ) import Unique ( pprUnique10, Unique, Uniquable(..) )
import FiniteMap ( lookupFM, addToFM ) import FiniteMap ( lookupFM, addToFM )
...@@ -147,14 +149,12 @@ data TcEnv = TcEnv ...@@ -147,14 +149,12 @@ data TcEnv = TcEnv
-- ...why mutable? see notes with tcGetGlobalTyVars -- ...why mutable? see notes with tcGetGlobalTyVars
-- Includes the in-scope tyvars -- Includes the in-scope tyvars
type NameEnv val = UniqFM val -- Keyed by Names
type UsageEnv = NameEnv UVar type UsageEnv = NameEnv UVar
type TypeEnv = NameEnv (TcKind, TcTyThing) type TypeEnv = NameEnv (TcKind, TcTyThing)
type ValueEnv = NameEnv Id type ValueEnv = NameEnv Id
valueEnvIds :: ValueEnv -> [Id] valueEnvIds :: ValueEnv -> [Id]
valueEnvIds ve = eltsUFM ve valueEnvIds ve = nameEnvElts ve
data TcTyThing = ATyVar TcTyVar -- Mutable only so that the kind can be mutable data TcTyThing = ATyVar TcTyVar -- Mutable only so that the kind can be mutable
-- if the kind is mutable, the tyvar must be so that -- if the kind is mutable, the tyvar must be so that
...@@ -165,11 +165,11 @@ data TcTyThing = ATyVar TcTyVar -- Mutable only so that the kind can be mutable ...@@ -165,11 +165,11 @@ data TcTyThing = ATyVar TcTyVar -- Mutable only so that the kind can be mutable
initEnv :: TcRef TcTyVarSet -> TcEnv initEnv :: TcRef TcTyVarSet -> TcEnv
initEnv mut = TcEnv emptyUFM emptyUFM emptyUFM (emptyVarSet, mut) initEnv mut = TcEnv emptyNameEnv emptyNameEnv emptyNameEnv (emptyVarSet, mut)
getEnvClasses (TcEnv _ te _ _) = [cl | (_, AClass cl _) <- eltsUFM te] getEnvClasses (TcEnv _ te _ _) = [cl | (_, AClass cl _) <- nameEnvElts te]
getEnvTyCons (TcEnv _ te _ _) = catMaybes (map get_tc (eltsUFM te)) getEnvTyCons (TcEnv _ te _ _) = catMaybes (map get_tc (nameEnvElts te))
where where
get_tc (_, ADataTyCon tc) = Just tc get_tc (_, ADataTyCon tc) = Just tc
get_tc (_, ASynTyCon tc _) = Just tc get_tc (_, ASynTyCon tc _) = Just tc
...@@ -193,7 +193,7 @@ Extending the usage environment. ...@@ -193,7 +193,7 @@ Extending the usage environment.
tcExtendUVarEnv :: Name -> UVar -> TcM s r -> TcM s r tcExtendUVarEnv :: Name -> UVar -> TcM s r -> TcM s r
tcExtendUVarEnv uv_name uv scope tcExtendUVarEnv uv_name uv scope
= tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) -> = tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) ->
tcSetEnv (TcEnv (addToUFM ue uv_name uv) te ve gtvs) scope tcSetEnv (TcEnv (addToNameEnv ue uv_name uv) te ve gtvs) scope
\end{code} \end{code}
Looking up in the environments. Looking up in the environments.
...@@ -202,7 +202,7 @@ Looking up in the environments. ...@@ -202,7 +202,7 @@ Looking up in the environments.
tcLookupUVar :: Name -> NF_TcM s UVar tcLookupUVar :: Name -> NF_TcM s UVar
tcLookupUVar uv_name tcLookupUVar uv_name
= tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) -> = tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) ->
case lookupUFM ue uv_name of case lookupNameEnv ue uv_name of
Just uv -> returnNF_Tc uv Just uv -> returnNF_Tc uv
Nothing -> failWithTc (uvNameOutOfScope uv_name) Nothing -> failWithTc (uvNameOutOfScope uv_name)
\end{code} \end{code}
...@@ -221,7 +221,7 @@ tcExtendTyVarEnv tyvars scope ...@@ -221,7 +221,7 @@ tcExtendTyVarEnv tyvars scope
extend_list = [ (getName tv, (kindToTcKind (tyVarKind tv), ATyVar tv)) extend_list = [ (getName tv, (kindToTcKind (tyVarKind tv), ATyVar tv))
| tv <- tyvars | tv <- tyvars
] ]
te' = addListToUFM te extend_list te' = extendNameEnv te extend_list
new_tv_set = mkVarSet tyvars new_tv_set = mkVarSet tyvars
in_scope_tvs' = in_scope_tvs `unionVarSet` new_tv_set in_scope_tvs' = in_scope_tvs `unionVarSet` new_tv_set
in in
...@@ -244,7 +244,7 @@ tcExtendTyVarEnvForMeths :: [TyVar] -> [TcTyVar] -> TcM s r -> TcM s r ...@@ -244,7 +244,7 @@ tcExtendTyVarEnvForMeths :: [TyVar] -> [TcTyVar] -> TcM s r -> TcM s r
tcExtendTyVarEnvForMeths sig_tyvars inst_tyvars thing_inside tcExtendTyVarEnvForMeths sig_tyvars inst_tyvars thing_inside
= tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) -> = tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) ->
let let
te' = addListToUFM te stuff te' = extendNameEnv te stuff
in in
tcSetEnv (TcEnv ue te' ve gtvs) thing_inside tcSetEnv (TcEnv ue te' ve gtvs) thing_inside
where where
...@@ -297,7 +297,7 @@ tcExtendTypeEnv bindings scope ...@@ -297,7 +297,7 @@ tcExtendTypeEnv bindings scope
-- Not for tyvars; use tcExtendTyVarEnv -- Not for tyvars; use tcExtendTyVarEnv
tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) -> tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) ->
let let
te' = addListToUFM te bindings te' = extendNameEnv te bindings
in in
tcSetEnv (TcEnv ue te' ve gtvs) scope tcSetEnv (TcEnv ue te' ve gtvs) scope
\end{code} \end{code}
...@@ -309,7 +309,7 @@ Looking up in the environments. ...@@ -309,7 +309,7 @@ Looking up in the environments.
tcLookupTy :: Name -> NF_TcM s (TcKind, TcTyThing) tcLookupTy :: Name -> NF_TcM s (TcKind, TcTyThing)
tcLookupTy name tcLookupTy name
= tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) -> = tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) ->
case lookupUFM te name of { case lookupNameEnv te name of {
Just thing -> returnNF_Tc thing ; Just thing -> returnNF_Tc thing ;
Nothing -> Nothing ->
...@@ -368,7 +368,7 @@ tcExtendLocalValEnv names_w_ids scope ...@@ -368,7 +368,7 @@ tcExtendLocalValEnv names_w_ids scope
= tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve (in_scope_tvs,gtvs)) -> = tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve (in_scope_tvs,gtvs)) ->
tcReadMutVar gtvs `thenNF_Tc` \ global_tvs -> tcReadMutVar gtvs `thenNF_Tc` \ global_tvs ->
let let
ve' = addListToUFM ve names_w_ids ve' = extendNameEnv ve names_w_ids
extra_global_tyvars = tyVarsOfTypes (map (idType . snd) names_w_ids) extra_global_tyvars = tyVarsOfTypes (map (idType . snd) names_w_ids)
in in
tc_extend_gtvs gtvs extra_global_tyvars `thenNF_Tc` \ gtvs' -> tc_extend_gtvs gtvs extra_global_tyvars `thenNF_Tc` \ gtvs' ->
...@@ -391,7 +391,7 @@ tcLookupValueMaybe name ...@@ -391,7 +391,7 @@ tcLookupValueMaybe name
= case maybeWiredInIdName name of = case maybeWiredInIdName name of
Just id -> returnNF_Tc (Just id) Just id -> returnNF_Tc (Just id)
Nothing -> tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) -> Nothing -> tcGetEnv `thenNF_Tc` \ (TcEnv ue te ve gtvs) ->
returnNF_Tc (lookupUFM ve name) returnNF_Tc (lookupNameEnv ve name)
tcLookupValueByKey :: Unique -> NF_TcM s Id -- Panics if not found tcLookupValueByKey :: Unique -> NF_TcM s Id -- Panics if not found
tcLookupValueByKey key tcLookupValueByKey key
...@@ -424,7 +424,7 @@ explicitLookupValue :: ValueEnv -> Name -> Maybe Id ...@@ -424,7 +424,7 @@ explicitLookupValue :: ValueEnv -> Name -> Maybe Id
explicitLookupValue ve name explicitLookupValue ve name
= case maybeWiredInIdName name of = case maybeWiredInIdName name of
Just id -> Just id Just id -> Just id
Nothing -> lookupUFM ve name Nothing -> lookupNameEnv ve name
-- Extract the IdInfo from an IfaceSig imported from an interface file -- Extract the IdInfo from an IfaceSig imported from an interface file
tcAddImportedIdInfo :: ValueEnv -> Id -> Id tcAddImportedIdInfo :: ValueEnv -> Id -> Id
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment