infelicitous (incorrect?) ordering of flags passed to GHC

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 Library 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 http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.ht... (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@LVN513-12:~/tmp/cabal-flags]$ cabal clean && cabal configure && cabal build -v2 cleaning... 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-4.2.0.0-b340bbd470b5859bcbb920aea62a12cf -O -fno-warn-unused-do-bind -Wall Foo [1 of 1] Compiling Foo ( Foo.hs, dist/build/Foo.o ) Foo.hs:7:7: 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 Linking... /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-4.2.0.0-b340bbd470b5859bcbb920aea62a12cf -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. -Brent

On Thu, 2010-01-07 at 15:18 -0500, Brent Yorgey wrote:
ghc-options: -Wall
if impl(ghc >= 6.12.1) ghc-options: -fno-warn-unused-do-bind
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:
ghc [..] -fno-warn-unused-do-bind -Wall Foo
Indeed, that's clearly wrong. The order should be the same as given in the .cabal file.
Any ideas? Why does this happen? How hard would it be to fix?
Where it gets reversed will need a little investigation. First point to check would be before and after finalisePackageDescription.
And are there any workarounds in the meantime?
Have you tried listing the fields in the other order?
Also, I'm happy to file a ticket on the bug tracker for this.
Thanks. Duncan

On Sun, Jan 10, 2010 at 06:27:51PM +0000, Duncan Coutts wrote:
On Thu, 2010-01-07 at 15:18 -0500, Brent Yorgey wrote:
ghc-options: -Wall
if impl(ghc >= 6.12.1) ghc-options: -fno-warn-unused-do-bind
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:
ghc [..] -fno-warn-unused-do-bind -Wall Foo
Indeed, that's clearly wrong. The order should be the same as given in the .cabal file.
Any ideas? Why does this happen? How hard would it be to fix?
Where it gets reversed will need a little investigation. First point to check would be before and after finalisePackageDescription.
OK, I might take a look.
And are there any workarounds in the meantime?
Have you tried listing the fields in the other order?
Yes, with the same result. So it's not as simple as something being backwards. I just had another idea for a possible workaround (even if this gets fixed I'd rather not rely on everyone building xmonad to have a sufficiently new version of cabal) which I will try once I get to school.
Also, I'm happy to file a ticket on the bug tracker for this.
Thanks.
Will do, I mailed first to see if people agreed this was a bug. -Brent

On Mon, Jan 11, 2010 at 10:15:51AM -0500, Brent Yorgey wrote:
On Sun, Jan 10, 2010 at 06:27:51PM +0000, Duncan Coutts wrote:
On Thu, 2010-01-07 at 15:18 -0500, Brent Yorgey wrote:
And are there any workarounds in the meantime?
Have you tried listing the fields in the other order?
Yes, with the same result. So it's not as simple as something being backwards. I just had another idea for a possible workaround (even if this gets fixed I'd rather not rely on everyone building xmonad to have a sufficiently new version of cabal) which I will try once I get to school.
Another data point: I found a workaround, which is to put if true ghc-options: -Wall if impl(ghc >= 6.12.1) ghc-options: -fno-warn-unused-do-bind This now works as expected, and switching the if-clauses switches the order of the flags passed to GHC. So the problem seems to be that flags from different "levels" are not being combined correctly. -Brent
participants (2)
-
Brent Yorgey
-
Duncan Coutts