Opened 9 years ago

Closed 8 years ago

#5095 closed bug (fixed)

Incoherent instance for Prelude type class accepted without incoherent instances option

Reported by: brunosoliveira Owned by:
Priority: normal Milestone: 7.4.1
Component: Compiler (Type checker) Version: 7.0.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC accepts invalid program Test Case: typecheck/should_fail/T5095
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by igloo)

If we create a new module allowing overlapping instances, flexible instances and undecidable instances we can define a function that selects an incoherent instance for a type class defined in the Prelude. Example:

> {-# OPTIONS -XFlexibleInstances -XOverlappingInstances -XUndecidableInstances #-}

> module Test where

> instance Show a => Eq a where
>   x == y =  length (show x) == length (show y)
>
> f :: Show a => a -> a -> Bool
> f x y = x == y
>
> p = f (3 :: Int) 4

The instance selected here (tested with GHC 7.0 and 6.12) is the one in this module, even if the instance Eq Int from the Prelude is more specific. If we try to reproduce a similar example using a module other than the Prelude, an incoherent instances error is reported. I believe that, for consistency the same should happen here.

Change History (5)

comment:1 Changed 9 years ago by igloo

Description: modified (diff)

comment:2 Changed 9 years ago by igloo

Architecture: x86Unknown/Multiple
Component: CompilerCompiler (Type checker)
Milestone: 7.4.1
Operating System: MacOS XUnknown/Multiple

Thanks for the report

comment:3 Changed 8 years ago by simonpj@…

commit 9d251f5ec83be41fdc3a7f1104ea8968fa9e5ebe

Author: Simon Peyton Jones <simonpj@microsoft.com>
Date:   Wed Aug 3 16:22:06 2011 +0100

    Fix a grevious error in InstEnv: Trac #5095
    
    An claimed short-cut optimisation was actually an error.
    The optimisation was this: when looking up (C a b), where
    'a' and 'b' are type variables, we were returning [] immediately
    if the instance environment had no instances of form (C a b).
    Why? Because the thing being looked up definitely won't match
    (C Int Bool), say.
    
    BUT it will *unify* with (C Int Bool) and we care very much
    about things it might unify with.  If we neglect them we may
    silently allow incoherent instance selection, and that is
    exactly what happened in #5095.
    
    The fix is easy: remove the "optimisation".

 compiler/types/InstEnv.lhs |   45 ++++++++++++++++---------------------------
 1 files changed, 17 insertions(+), 28 deletions(-)

comment:4 Changed 8 years ago by simonpj

Status: newmerge
Test Case: typecheck/should_fail/T5095

Thanks for identifying this bug so precisely. Fixed!

Simon

comment:5 Changed 8 years ago by igloo

Resolution: fixed
Status: mergeclosed
Note: See TracTickets for help on using tickets.