-Wunused-local-binds doesn't work for expressions in GHCi
If you compile this file with -Wunused-local-binds
:
main = let x = () in return ()
It will produce a warning, as expected:
$ ghc-9.2.2 Foo.hs -fforce-recomp -Wunused-local-binds
[1 of 1] Compiling Main ( Foo.hs, Foo.o )
Foo.hs:1:12: warning: [-Wunused-local-binds]
Defined but not used: ‘x’
|
1 | main = let x = () in return ()
| ^
Linking Foo ...
If you type the same expression into GHCi, however, it produces no warnings!
$ ghci-9.2.2
GHCi, version 9.2.2: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rscott/.ghci
λ> :set -Wunused-local-binds
λ> let x = () in return ()
λ>
This seems like a discrepancy. Further investigation reveals that GHCi in fact deliberately disables -Wunused-local-binds
:
-- Turn off -fwarn-unused-local-binds when running a statement, to hide
-- warnings about the implicit bindings we introduce.
let ic = hsc_IC hsc_env -- use the interactive dflags
idflags' = ic_dflags ic `wopt_unset` Opt_WarnUnusedLocalBinds
hsc_env' = mkInteractiveHscEnv (hsc_env{ hsc_IC = ic{ ic_dflags = idflags' }})
This code was introduced 14 years ago in 86bec429. I don't find the stated reason to be convincing, however. Rather than disabling -Wunused-local-binds
entirely, which suppresses useful warnings, we should instead find a way to make the implicit bindings that GHCi introduces not trigger -Wunused-local-binds
warnings.