
#9210: "overlapping instances" through FunctionalDependencies -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler (Type | Version: 7.8.2 checker) | Resolution: | Keywords: FunDeps Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by diatchki): The check for overlapping is done when GHC resolves instances. This is unrelated to this example. You can easily modify it, so that there are no overlapping instances: {{{ class Foo tag a b c | a b -> c instance Foo Int (x, a) x ((), a) instance Foo Bool (x, a) a (x, ()) }}} The check for the consistency of FDs ought to be done whenever instances exist in the same scope, and there are two ways in which this can happen: 1. they were declared in the same module, in which case GHC will try to check their consistency---as this example illustrates, we have a bug in the checking code, as the instances are not reported as inconsistent; 2. when instances are imported into the same module. In this case GHC doesn't try to validate the comparability of the instances at all, which leads to obviously inconsistent FDs (e.g., `F Int Int` in one module, `F Int Char` in another, and both are OK when imported in a third module). It also leads to the fairly well-known bug of incoherent instances where GHC will happily allow two different instances for the same type tp be used in different modules. As far as I can tell, the new behavior in 8 is how GHC uses FDs to perform improvements. Instead of just using one of the instances, it will now try to improve with all of the instances. As a result, if there are inconsistencies, it will try to improve in two different ways, and report a delayed error. The underlying bug of failing to detect the inconsistency of the instances is still present. The thing that we should be checking is: {{{ forall x1 a2 x2 a2. ( (x1,a1) ~ (x2,a2), x1 ~ a2 ) => ( ((), a1) ~ (x2, ()) ) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9210#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler