Opened 4 years ago

Last modified 4 years ago

#10526 new bug

Overlapping instances, incoherence, and optimisation

Reported by: simonpj Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.10.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by simonpj)

Segei Meshveliani reports that his docon library has rather unexpected behaviour with GHC 7.10. See his email.

The effect is that his test module Main has different runtime behaviour when compiling with and without -O. This sounds pretty bad.

The reason is this:

  • He has overlapping instances for a class, say
    • instance ... => C (T a), call it (A)
    • instance C (T Int), call it (B)
    The actual situation is more complicated of course
  • The instances are defined in different modules.
  • In one module Spec
    • instance (B) is not visible
    • there is a function f :: C a => a -> a
    • f is called at type T Int.

So GHC specialises f, to f_spec :: T Int -> T Int, and exports a RULE

RULE "SPEC" f = f_spec :: T Int -> T Int 

The idea is that any other module that calls f at type T Int can simply re-use the specialised (and presumably much faster) version of f. But note that since (B) is not visible, so GHC finds a solution using (A), and embodies that in f_spec.

  • In another module, Use, which can see (B) and Spec, we call f at type T Int. In the absence of the cross-module specialisation rule, or without -O, GHC would solve the constraint C (T Int), this time using (B). But because of the rule, with -O, it re-uses f_spec. Result: different runtime behaviour.

There is a more detailed discussion on this thread.

Change History (2)

comment:1 Changed 4 years ago by simonpj

Description: modified (diff)

comment:2 Changed 4 years ago by simonpj

Description: modified (diff)
Note: See TracTickets for help on using tickets.