Opened 8 years ago

Closed 8 years ago

#3457 closed bug (fixed)

Impossible to specify pragmas compatible with multiple ghc versions

Reported by: duncan Owned by:
Priority: normal Milestone: 7.0.1
Component: Driver Version: 6.10.4
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Generally we wish to encourage modules to specify the language options they need directly in the module rather than putting them all in the .cabal file. For one thing it allows a simple ghc --make to work.

The bytestring package works with ghc-6.4 through to 6.11. As far as I can see, it is impossible to specify the language options in a way that allows the package to build using ghc --make for a recent ghc version while at the same time building at all with an older ghc version.

Consider the module Data/ByteString.hs. If we use:

{-# LANGUAGE CPP, MagicHash, UnboxedTuples #-}

Then it works with ghc-6.8 --make and ghc-6.10 --make however now it cannot compile with ghc-6.6 because that version does not grok the MagicHash and UnboxedTuples language options.

We might think we could do:

{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 608
{-# LANGUAGE MagicHash, UnboxedTuples #-}
#endif

Of course we will not expect this to work with ghc-6.6 --make but it will at least work with Cabal, because we can set things up so that Cabal passes -fglasgow-exts.

However the above still will not work with ghc --make or even ghc -cpp --make because of the problem that ghc handles pragmas and CPP incorrectly (see #2800 and #2464). It holds onto the pragmas gathered before running cpp and assumes they will still be valid after the run of cpp, which of course is not true.

The solution would be that after ghc runs cpp, it looks to see what the pragmas are, just as if it were starting from a fresh .hs file.

In the mean time we cannot specify the language extensions in the .hs files and have it work. For bytestring we will just list the language extensions that we would specify if we could specify them.

{-# LANGUAGE CPP #-}
-- We cannot actually specify all the language pragmas, see ghc ticket #...
-- If we could, these are what they would be:
{- LANGUAGE MagicHash, UnboxedTuples -}

The way to test if the right ones are listed is to turn them back into pragmas and check ghc --make.

Change History (5)

comment:1 Changed 8 years ago by igloo

difficulty: Unknown
Milestone: 6.14.1

comment:2 Changed 8 years ago by duncan

difficulty: UnknownModerate (less than a day)
Type of failure: GHC rejects valid program

#3474 and #2464 are bugs with the same fix.

The core of the problem is this:

ghc --make reads the source file headers to chase imports. If it discovers the source file needs pre-processing, e.g.

{-# OPTIONS -F -pgmF ./preprocess.sh #-}

or

{-# LANGUAGE CPP #-}

then it runs the pre-processor.

However, this is where it makes the mistake. When it re-reads the source after-preprocessing it retains all the information about which pragmas etc were in effect from when it looked at the original source file prior to pre-processing and uses this when it reads the new source file. This does not take account of the fact that this info could be changed by the pre-processor.

If you run the pre-processor manually then of course ghc is forced to do the correct thing because then you do not give ghc the opportunity to remember any incorrect state (assuming the pre-processor strips out the pragam that instructs ghc to run the pre-processor!).

The fix is simply to start from a clean slate after pre-processing and process the new source file without any presumptions.

comment:3 Changed 8 years ago by duncan

Oops, I meant #3674.

comment:4 Changed 8 years ago by simonmar

See also #3844, which depends on this being fixed.

comment:5 Changed 8 years ago by simonmar

Resolution: fixed
Status: newclosed

Fixed:

Fri Jan 29 03:40:50 PST 2010  Simon Marlow <marlowsd@gmail.com>
  * Re-read pragmas after preprocessing (#2464, #3674, #3457)
Note: See TracTickets for help on using tickets.