Commit fe7e7e4a authored by Yuras's avatar Yuras Committed by Marge Bot
Browse files

Warn about unused packages

Reviewers: bgamari, simonpj

Reviewed By: simonpj

Subscribers: hvr, simonpj, mpickering, rwbarton, carter

GHC Trac Issues: #15838

Differential Revision: https://phabricator.haskell.org/D5285
parent e5d275f4
Pipeline #6927 passed with stages
in 328 minutes and 34 seconds
......@@ -911,6 +911,7 @@ data WarningFlag =
| Opt_WarnSpaceAfterBang
| Opt_WarnMissingDerivingStrategies -- Since 8.8
| Opt_WarnPrepositiveQualifiedModule -- Since TBD
| Opt_WarnUnusedPackages -- Since 8.10
deriving (Eq, Show, Enum)
data Language = Haskell98 | Haskell2010
......@@ -4110,7 +4111,8 @@ wWarningFlagsDeps = [
flagSpec "missing-space-after-bang" Opt_WarnSpaceAfterBang,
flagSpec "partial-fields" Opt_WarnPartialFields,
flagSpec "prepositive-qualified-module"
Opt_WarnPrepositiveQualifiedModule
Opt_WarnPrepositiveQualifiedModule,
flagSpec "unused-packages" Opt_WarnUnusedPackages
]
-- | These @-\<blah\>@ flags can all be reversed with @-no-\<blah\>@
......
......@@ -267,7 +267,75 @@ data LoadHowMuch
load :: GhcMonad m => LoadHowMuch -> m SuccessFlag
load how_much = do
mod_graph <- depanal [] False
load' how_much (Just batchMsg) mod_graph
success <- load' how_much (Just batchMsg) mod_graph
warnUnusedPackages
pure success
-- Note [Unused packages]
--
-- Cabal passes `--package-id` flag for each direct dependency. But GHC
-- loads them lazily, so when compilation is done, we have a list of all
-- actually loaded packages. All the packages, specified on command line,
-- but never loaded, are probably unused dependencies.
warnUnusedPackages :: GhcMonad m => m ()
warnUnusedPackages = do
hsc_env <- getSession
eps <- liftIO $ hscEPS hsc_env
let dflags = hsc_dflags hsc_env
pit = eps_PIT eps
let loadedPackages
= map (getPackageDetails dflags)
. nub . sort
. map moduleUnitId
. moduleEnvKeys
$ pit
requestedArgs = mapMaybe packageArg (packageFlags dflags)
unusedArgs
= filter (\arg -> not $ any (matching dflags arg) loadedPackages)
requestedArgs
let warn = makeIntoWarning
(Reason Opt_WarnUnusedPackages)
(mkPlainErrMsg dflags noSrcSpan msg)
msg = hang
( text "The following packages were specified "
<> text "via -package or -package-id flags, "
<> text "but were not needed for compilation: ")
4
(sep (map pprUnusedArg unusedArgs))
when (wopt Opt_WarnUnusedPackages dflags && not (null unusedArgs)) $
logWarnings (listToBag [warn])
where
packageArg (ExposePackage _ arg _) = Just arg
packageArg _ = Nothing
pprUnusedArg (PackageArg str) = text str
pprUnusedArg (UnitIdArg uid) = ppr uid
matchingStr :: String -> PackageConfig -> Bool
matchingStr str p
= str == sourcePackageIdString p
|| str == packageNameString p
matching :: DynFlags -> PackageArg -> PackageConfig -> Bool
matching _ (PackageArg str) p = matchingStr str p
matching dflags (UnitIdArg uid) p = uid == realUnitId dflags p
-- For wired-in packages, we have to unwire their id,
-- otherwise they won't match package flags
realUnitId :: DynFlags -> PackageConfig -> UnitId
realUnitId dflags
= unwireUnitId dflags
. DefiniteUnitId
. DefUnitId
. installedPackageConfigId
-- | Generalized version of 'load' which also supports a custom
-- 'Messager' (for reporting progress) and 'ModuleGraph' (generally
......
......@@ -102,6 +102,8 @@ Compiler
- The :ghc-flag:`-Wcompat` warning group now includes :ghc-flag:`-Wstar-is-type`.
- New :ghc-flag:`-Wunused-packages` warning reports unused packages.
- The :ghc-flag:`-fllvm-pass-vectors-in-regs` flag is now deprecated as vector
arguments are now passed in registers by default.
......
......@@ -1683,6 +1683,21 @@ of ``-W(no-)*``.
data Foo = Foo { f :: Int } | Bar
.. ghc-flag:: -Wunused-packages
:shortdesc: warn when package is requested on command line, but was never loaded.
:type: dynamic
:reverse: -Wno-unused-packages
:category:
:since: 8.8
The option :ghc-flag:`-Wunused-packages` warns about packages, specified on
command line via :ghc-flag:`-package` or :ghc-flag:`-package-id`, but were not
loaded during compication. Usually it means that you have an unused dependency.
You may want to enable this warning on a clean build or enable :ghc-flag:`-fforce-recomp`
in order to get reliable results.
If you're feeling really paranoid, the :ghc-flag:`-dcore-lint` option is a good choice.
It turns on heavyweight intra-pass sanity-checking within GHC. (It checks GHC's
sanity, not yours.)
module Main
where
main :: IO ()
main = return ()
[1 of 1] Compiling Main ( UnusedPackages.hs, UnusedPackages.o )
Linking UnusedPackages ...
<no location info>: warning: [-Wunused-packages]
The following packages were specified via -package or -package-id flags, but were not needed for compilation:
bytestring
......@@ -27,3 +27,5 @@ test('T16551', [extra_files(['T16551/'])], multimod_compile, ['T16551/A.hs T1655
test('StarBinder', normal, compile, [''])
test('Overflow', normal, compile, [''])
test('UnusedPackages', normal, multimod_compile, ['UnusedPackages.hs', '-package=bytestring -package=base -Wunused-packages'])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment