[GHC] #15135: Overlapping typeclass instance selection depends on the optimisation level

GHC ghc-devs at haskell.org
Wed May 9 14:10:41 UTC 2018


#15135: Overlapping typeclass instance selection depends on the optimisation level
-------------------------------------+-------------------------------------
           Reporter:  nicuveo        |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:  8.6.1
          Component:  Compiler       |           Version:  8.4.2
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 A file A defines a typeclass, and gives an instance for all types a, and
 exports a function relying on said typeclass. A file B defines a data
 type, makes it a specific `OVERLAPPING` instance of that class, and uses
 the function defined in A. Which instance ends up being picked for B
 depends on the optimisation level those files are compiled with.

 **Minimal test case**

 //A.hs//
 {{{#!hs
 {-# LANGUAGE FlexibleInstances #-}
 {-# OPTIONS_GHC -fno-warn-simplifiable-class-constraints #-}

 module A where

 import           Data.Maybe

 class A a where
   someValue :: a -> Maybe Int

 instance A a where
   someValue = const Nothing

 getInt :: A a => a -> Int
 getInt x = fromMaybe 0 $ someValue x
 }}}

 //B.hs//
 {{{#!hs
 module B where

 import           A

 data B = B Int

 instance {-# OVERLAPPING #-} A B where
   someValue (B x) = Just x

 getBInt :: Int
 getBInt = getInt $ B 42
 }}}

 //Main.hs//
 {{{#!hs
 import           B

 main :: IO ()
 main = putStrLn $ "B: " ++ show getBInt
 }}}

 To reproduce:
 {{{
 $ ghc -O0 -fforce-recomp Main.hs && ./Main
 [1 of 3] Compiling A                ( A.hs, A.o )
 [2 of 3] Compiling B                ( B.hs, B.o )
 [3 of 3] Compiling Main             ( Main.hs, Main.o )
 Linking Main ...
 B: 42

 $ ghc -O2 -fforce-recomp Main.hs && ./Main
 [1 of 3] Compiling A                ( A.hs, A.o )
 [2 of 3] Compiling B                ( B.hs, B.o )
 [3 of 3] Compiling Main             ( Main.hs, Main.o )
 Linking Main ...
 B: 0
 }}}


 The fix introduced to fix ticket:14434 instructs the "short-cut solver" to
 not automatically choose a matching instance if it marked as `INCOHERENT`
 or `OVERLAPPABLE`, but in this case the instance is not marked in any way.
 This might be the source of the bug?

 Additionally, whatever the optimisation level, ghc emits a warning about
 the `A a =>` class constraint being simplifiable; but if it is removed,
 then the program prints "0" in both cases.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15135>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list