Skip to content

text has different runtime behavior between GHC 8.6.5 and 8.8.1

If you compile the following file:

module Main (main) where

import qualified Data.Char as C
import           Data.Char (isLetter, isLower)
import           Data.Maybe (mapMaybe)
import qualified Data.Text as T
import           Data.Text (Text)

main :: IO ()
main = print $ t_toTitle_1stNotLower
             $ T.pack "\4309" -- ვ

-- Taken from the text test suite
-- https://github.com/haskell/text/blob/44ec2cee65e5326ed943370e424f60d4ae6206d1/tests/Tests/Properties.hs#L388-L396
t_toTitle_1stNotLower :: Text -> Bool
t_toTitle_1stNotLower = and . notLow . T.toTitle . T.filter stable
    where notLow = mapMaybe (fmap (not . isLower) . (T.find isLetter)) . T.words
          -- Surprise! The Spanish/Portuguese ordinal indicators changed
          -- from category Ll (letter, lowercase) to Lo (letter, other)
          -- in Unicode 7.0
          -- Oh, and there exist lowercase-only letters (see previous test)
          stable c = if isLower c
                     then C.toUpper c /= c
                     else c /= '\170' && c /= '\186'

Then you'll get different runtime results depending on which version of GHC you use. Here is the answer with GHC 8.6.5:

$ /opt/ghc/8.6.5/bin/ghc Bug.hs -fforce-recomp -v0 && ./Bug                                        
True

And here is the answer with GHC 8.8.1, 8.10.1-alpha2, and HEAD:

$ /opt/ghc/8.8.1/bin/ghc Bug.hs -fforce-recomp -v0 && ./Bug                                        
False

This discrepancy manifests itself regardless of what GHC optimization level is used.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information