[project @ 2004-05-25 08:09:37 by simonpj]
authorsimonpj <unknown>
Tue, 25 May 2004 08:09:42 +0000 (08:09 +0000)
committersimonpj <unknown>
Tue, 25 May 2004 08:09:42 +0000 (08:09 +0000)
-----------------------------------------------
Improve location info on unused-import warnings
-----------------------------------------------

Improving the location involves plumbing the location of the import a bit
more assiduously -- hence change to imp_mods in TcRnTypes

ghc/compiler/deSugar/Desugar.lhs
ghc/compiler/iface/MkIface.lhs
ghc/compiler/rename/RnEnv.lhs
ghc/compiler/rename/RnNames.lhs
ghc/compiler/typecheck/TcRnTypes.lhs

index 5f8192e..e2fe1f3 100644 (file)
@@ -112,7 +112,7 @@ deSugar hsc_env
                mg_exports  = exports,
                mg_deps     = deps,
                mg_usages   = usages,
-               mg_dir_imps = [m | (m,_) <- moduleEnvElts (imp_mods imports)],
+               mg_dir_imps = [m | (m,_,_) <- moduleEnvElts (imp_mods imports)],
                mg_rdr_env  = rdr_env,
                mg_fix_env  = fix_env,
                mg_deprecs  = deprecs,
index 1d77a03..224617e 100644 (file)
@@ -702,8 +702,8 @@ mk_usage_info pit hpt dir_imp_mods dep_mods proto_used_names
        -- ToDo: do we need to sort into canonical order?
 
     import_all mod = case lookupModuleEnv dir_imp_mods mod of
-                       Just (_,imp_all) -> isNothing imp_all
-                       Nothing          -> False
+                       Just (_,imp_all,_) -> isNothing imp_all
+                       Nothing            -> False
     
     -- We want to create a Usage for a home module if 
     -- a) we used something from; has something in used_names
index 1185fe5..dfd2fda 100644 (file)
@@ -54,7 +54,7 @@ import Module         ( Module, ModuleName, moduleName, mkHomeModule )
 import PrelNames       ( mkUnboundName, rOOT_MAIN_Name, iNTERACTIVE )
 import UniqSupply
 import BasicTypes      ( IPName, mapIPName )
-import SrcLoc          ( srcSpanStart, Located(..), eqLocated, unLoc,
+import SrcLoc          ( SrcSpan, srcSpanStart, Located(..), eqLocated, unLoc,
                          srcLocSpan )
 import Outputable
 import ListSetOps      ( removeDups )
@@ -658,12 +658,13 @@ mapFvRn f xs = mappM f xs `thenM` \ stuff ->
 %************************************************************************
 
 \begin{code}
-warnUnusedModules :: [ModuleName] -> RnM ()
+warnUnusedModules :: [(ModuleName,SrcSpan)] -> RnM ()
 warnUnusedModules mods
-  = ifOptM Opt_WarnUnusedImports (mappM_ (addWarn . unused_mod) mods)
+  = ifOptM Opt_WarnUnusedImports (mappM_ bleat mods)
   where
-    unused_mod m = vcat [ptext SLIT("Module") <+> quotes (ppr m) <+> 
-                          text "is imported, but nothing from it is used",
+    bleat (mod,loc) = addSrcSpan loc $ addWarn (mk_warn mod)
+    mk_warn m = vcat [ptext SLIT("Module") <+> quotes (ppr m) <+> 
+                        text "is imported, but nothing from it is used",
                         parens (ptext SLIT("except perhaps instances visible in") <+>
                                   quotes (ppr m))]
 
index 1604915..f3fe011 100644 (file)
@@ -50,7 +50,7 @@ import RdrName                ( RdrName, rdrNameOcc, setRdrNameSpace,
 import Outputable
 import Maybes          ( isJust, isNothing, catMaybes, mapCatMaybes, seqMaybe )
 import SrcLoc          ( noSrcLoc, Located(..), mkGeneralSrcSpan,
-                         unLoc, noLoc, srcLocSpan )
+                         unLoc, noLoc, srcLocSpan, SrcSpan )
 import BasicTypes      ( DeprecTxt )
 import ListSetOps      ( removeDups )
 import Util            ( sortLt, notNull, isSingleton )
@@ -228,7 +228,7 @@ importsFromImportDecl this_mod
        imports   = ImportAvails { 
                        imp_qual     = unitModuleEnvByName qual_mod_name avail_env,
                        imp_env      = avail_env,
-                       imp_mods     = unitModuleEnv imp_mod (imp_mod, import_all),
+                       imp_mods     = unitModuleEnv imp_mod (imp_mod, import_all, loc),
                        imp_orphs    = orphans,
                        imp_dep_mods = mkModDeps dependent_mods,
                        imp_dep_pkgs = dependent_pkgs }
@@ -852,8 +852,7 @@ reportUnusedNames gbl_env
        -- We've carefully preserved the provenance so that we can
        -- construct minimal imports that import the name by (one of)
        -- the same route(s) as the programmer originally did.
-    add_name (GRE {gre_name = n, 
-                  gre_prov = Imported imp_specs _}) acc 
+    add_name (GRE {gre_name = n, gre_prov = Imported imp_specs _}) acc 
        = addToFM_C plusAvailEnv acc (is_mod (head imp_specs))
                    (unitAvailEnv (mk_avail n (nameParent_maybe n)))
     add_name other acc 
@@ -864,38 +863,35 @@ reportUnusedNames gbl_env
     mk_avail n Nothing | isTcOcc (nameOccName n) = AvailTC n [n]
                       | otherwise               = Avail n
     
-    add_inst_mod m acc 
-      | m `elemFM` acc = acc   -- We import something already
-      | otherwise      = addToFM acc m emptyAvailEnv
+    add_inst_mod (mod,_,_) acc 
+      | mod_name `elemFM` acc = acc    -- We import something already
+      | otherwise             = addToFM acc mod_name emptyAvailEnv
+      where
+       mod_name = moduleName mod
        -- Add an empty collection of imports for a module
        -- from which we have sucked only instance decls
    
     imports = tcg_imports gbl_env
 
-    direct_import_mods :: [ModuleName]
-    direct_import_mods = map (moduleName . fst) 
-                            (moduleEnvElts (imp_mods imports))
-
-    hasEmptyImpList :: ModuleName -> Bool
-    hasEmptyImpList m = 
-       case lookupModuleEnvByName (imp_mods imports) m of
-        Just (_,Just x) -> not x
-        _ -> False
+    direct_import_mods :: [(Module, Maybe Bool, SrcSpan)]
+       -- See the type of the imp_mods for this triple
+    direct_import_mods = moduleEnvElts (imp_mods imports)
 
     -- unused_imp_mods are the directly-imported modules 
     -- that are not mentioned in minimal_imports1
     -- [Note: not 'minimal_imports', because that includes directly-imported
     --       modules even if we use nothing from them; see notes above]
-    unused_imp_mods = [m | m <- direct_import_mods,
-                      isNothing (lookupFM minimal_imports1 m),
-                      m /= pRELUDE_Name,
-                      not (hasEmptyImpList m)]
-       -- hasEmptyImpList arranges not to complain about
+    unused_imp_mods = [(mod_name,loc) | (mod,imp,loc) <- direct_import_mods,
+                      let mod_name = moduleName mod,
+                      not (mod_name `elemFM` minimal_imports1),
+                      mod_name /= pRELUDE_Name,
+                      imp /= Just False]
+       -- The Just False part is not to complain about
        -- import M (), which is an idiom for importing
        -- instance declarations
     
     module_unused :: ModuleName -> Bool
-    module_unused mod = mod `elem` unused_imp_mods
+    module_unused mod = any (((==) mod) . fst) unused_imp_mods
 
 ---------------------
 warnDuplicateImports :: [GlobalRdrElt] -> RnM ()
index e5a8e1c..a915651 100644 (file)
@@ -443,7 +443,7 @@ data ImportAvails
                -- combine stuff coming from different (unqualified) 
                -- imports of the same module
 
-       imp_mods :: ModuleEnv (Module, Maybe Bool),
+       imp_mods :: ModuleEnv (Module, Maybe Bool, SrcSpan),
                -- Domain is all directly-imported modules
                -- Maybe value answers the question "is the import restricted?"
                --   Nothing    => unrestricted import (e.g., "import Foo")