infelicitous (incorrect?) ordering of flags passed to GHC

Brent Yorgey byorgey at
Thu Jan 7 15:18:09 EST 2010

Hi all,

In trying to update xmonad to build without warnings under GHC 6.12.1,
I spent a while struggling to turn off some particular warnings with
apparently no effect.  Eventually I boiled it down to the following,
which seems like a problem---or at least, an infelicity---with Cabal.
Suppose we have the following Foo.hs file:

  module Foo where

  x :: IO Int
  x = return 5

  f :: IO Int
  f = do x
         return 3

This compiles fine with no warnings by default; under ghc -Wall it
compiles but generates a warning that 'x' returns an Int which is not
bound in f's do-block.  This is as it should be.  Now consider the
following .cabal file (the important bits are at the end):

  Name:                cabal-flags
  Version:             0.1
  License:             BSD3
  License-file:        LICENSE
  Stability:           Experimental
  Category:            Development
  Build-type:          Simple
  Cabal-version:       >=1.2

    Exposed-modules:     Foo
    build-depends:       base >= 4

    ghc-options:         -Wall
    if impl(ghc >= 6.12.1)
      ghc-options:       -fno-warn-unused-do-bind

According to
(see the subsection "Meaning of field values when using
conditionals"), inner items (in this case the
-fno-warn-unused-do-bind) are appended to outer items (here, -Wall) so
I would expect the arguments -Wall -fno-warn-unused-do-bind to be
passed to ghc-6.12.1.  However, let's see what happens:

     [byorgey at LVN513-12:~/tmp/cabal-flags]$ cabal clean && cabal configure && cabal build -v2
     Resolving dependencies...
     Configuring cabal-flags-0.1...
     Creating dist/build (and its parents)
     Creating dist/build/autogen (and its parents)
     Preprocessing library cabal-flags-0.1...
     Building cabal-flags-0.1...
     Building library...
     Creating dist/build (and its parents)
***  /home1/b/byorgey/local/bin/ghc --make -package-name cabal-flags-0.1 -hide-all-packages -fbuilding-cabal-package -i -idist/build -i. -idist/build/autogen -Idist/build/autogen -Idist/build -optP-include -optPdist/build/autogen/cabal_macros.h -odir dist/build -hidir dist/build -stubdir dist/build -package-id base- -O -fno-warn-unused-do-bind -Wall Foo
     [1 of 1] Compiling Foo              ( Foo.hs, dist/build/Foo.o )
         Warning: A do-notation statement discarded a result of type Int.
                  Suppress this warning by saying "_ <- x",
                  or by using the flag -fno-warn-unused-do-bind
     /usr/bin/ar -r dist/build/libHScabal-flags-0.1.a dist/build/Foo.o
     /usr/bin/ar: creating dist/build/libHScabal-flags-0.1.a
     /usr/bin/ld -x -r -o dist/build/HScabal-flags-0.1.o dist/build/Foo.o
     /home1/b/byorgey/local/bin/ghc --abi-hash -package-name cabal-flags-0.1 -hide-all-packages -fbuilding-cabal-package -i -idist/build -i. -idist/build/autogen -Idist/build/autogen -Idist/build -optP-include -optPdist/build/autogen/cabal_macros.h -odir dist/build -hidir dist/build -stubdir dist/build -package-id base- -O -fno-warn-unused-do-bind -Wall Foo
     Registering cabal-flags-0.1...
     /home1/b/byorgey/local/bin/ghc-pkg update - --package-conf=dist/package.conf.inplace

As you can see in the line marked ***, the flags are passed in the
order -fno-warn-unused-do-bind -Wall.  The problem is that GHC
interprets these flags in left-right order, so if -Wall comes second
the -fno-warn-unused-do-bind has no effect; and indeed, the warning in
question is generated as you can see.

Any ideas?  Why does this happen?  How hard would it be to fix?  And
are there any workarounds in the meantime?  Also, I'm happy to file a
ticket on the bug tracker for this.


More information about the cabal-devel mailing list