[GHC] #9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied

#9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied -------------------------+------------------------------------------------- Reporter: | Owner: danilo2 | Status: new Type: bug | Milestone: Priority: | Version: 7.8.2 normal | Operating System: Unknown/Multiple Component: | Type of failure: Incorrect warning at Compiler | compile-time Keywords: | Test Case: Architecture: | Blocking: Unknown/Multiple | Difficulty: | Unknown | Blocked By: | Related Tickets: | -------------------------+------------------------------------------------- Hello! The problem is not a bug related to proper code execution, but it affects the development in such way, we can treat it as a bug. Lets think about such simple code (it can be further simplified of course): {{{#!haskell {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-} data UnsafeBase base err val = Value val | Error err | Other (base val) deriving (Show, Eq) class MagicMerge m1 m2 | m1 -> m2 where magicMerge :: m1 a -> m2 a instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where magicMerge ma = case ma of Value a -> Value a Error e -> Error e Other o -> o instance MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where magicMerge (ma :: UnsafeBase (UnsafeBase base err1) err2 a) = case ma of Value a -> Value a Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) Other o -> case o of Value a -> Other $ magicMerge (Value a :: UnsafeBase base err2 a) Error e -> Error e Other o' -> Other $ magicMerge (Other o' :: UnsafeBase base err2 a) main = print "help me world!" }}} When trying to compile it using GHC-7.8, we get following error message: {{{#!haskell Illegal instance declaration for ‘MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’ The liberal coverage condition fails in class ‘MagicMerge’ for functional dependency: ‘m1 -> m2’ Reason: lhs type ‘UnsafeBase (UnsafeBase base err1) err2’ does not determine rhs type ‘UnsafeBase dstBase err1’ In the instance declaration for ‘MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’ }}} Which is of course right, but it is completely unhelpfull! When we run the same program against GHC-7.6, we get another message: {{{#!haskell No instance for (MagicMerge (UnsafeBase base err2) dstBase) arising from a use of `magicMerge' Possible fix: add an instance declaration for (MagicMerge (UnsafeBase base err2) dstBase) In the second argument of `($)', namely `magicMerge (Error e :: UnsafeBase base err2 a)' In the expression: Other $ magicMerge (Error e :: UnsafeBase base err2 a) In a case alternative: Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) }}} And it contains a very helpfull information about inferred types. The information is very helpfull, especialy with more complex instances. What is VERY IMPORTANT, when we use the inferred type, the code starts working in both, GHC-7.8 and GHC-7.6. Right now I have to use both versions of GHC to be able to develop my instances faster. So If we add the inferred by GHC-7.6 premise: {{{#!haskell {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-} data UnsafeBase base err val = Value val | Error err | Other (base val) deriving (Show, Eq) class MagicMerge m1 m2 | m1 -> m2 where magicMerge :: m1 a -> m2 a instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where magicMerge ma = case ma of Value a -> Value a Error e -> Error e Other o -> o instance (MagicMerge (UnsafeBase base err2) dstBase) => MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where magicMerge (ma :: UnsafeBase (UnsafeBase base err1) err2 a) = case ma of Value a -> Value a Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) Other o -> case o of Value a -> Other $ magicMerge (Value a :: UnsafeBase base err2 a) Error e -> Error e Other o' -> Other $ magicMerge (Other o' :: UnsafeBase base err2 a) main = print "help me world!" }}} The code compiles and works ok in both GHC-7.6 and GHC-7.8. In such cases, GHC-7.8 should inform about lacking premises. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9267 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied -------------------------------------------------+------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect warning at | Unknown/Multiple compile-time | Difficulty: Test Case: | Unknown Blocking: | Blocked By: | Related Tickets: -------------------------------------------------+------------------------- Description changed by danilo2: Old description:
Hello! The problem is not a bug related to proper code execution, but it affects the development in such way, we can treat it as a bug.
Lets think about such simple code (it can be further simplified of course):
{{{#!haskell {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-}
data UnsafeBase base err val = Value val | Error err | Other (base val) deriving (Show, Eq)
class MagicMerge m1 m2 | m1 -> m2 where magicMerge :: m1 a -> m2 a
instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where magicMerge ma = case ma of Value a -> Value a Error e -> Error e Other o -> o
instance MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where magicMerge (ma :: UnsafeBase (UnsafeBase base err1) err2 a) = case ma of Value a -> Value a Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) Other o -> case o of Value a -> Other $ magicMerge (Value a :: UnsafeBase base err2 a) Error e -> Error e Other o' -> Other $ magicMerge (Other o' :: UnsafeBase base err2 a)
main = print "help me world!" }}}
When trying to compile it using GHC-7.8, we get following error message:
{{{#!haskell Illegal instance declaration for ‘MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’ The liberal coverage condition fails in class ‘MagicMerge’ for functional dependency: ‘m1 -> m2’ Reason: lhs type ‘UnsafeBase (UnsafeBase base err1) err2’ does not determine rhs type ‘UnsafeBase dstBase err1’ In the instance declaration for ‘MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’ }}}
Which is of course right, but it is completely unhelpfull! When we run the same program against GHC-7.6, we get another message:
{{{#!haskell No instance for (MagicMerge (UnsafeBase base err2) dstBase) arising from a use of `magicMerge' Possible fix: add an instance declaration for (MagicMerge (UnsafeBase base err2) dstBase) In the second argument of `($)', namely `magicMerge (Error e :: UnsafeBase base err2 a)' In the expression: Other $ magicMerge (Error e :: UnsafeBase base err2 a) In a case alternative: Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) }}}
And it contains a very helpfull information about inferred types. The information is very helpfull, especialy with more complex instances.
What is VERY IMPORTANT, when we use the inferred type, the code starts working in both, GHC-7.8 and GHC-7.6. Right now I have to use both versions of GHC to be able to develop my instances faster.
So If we add the inferred by GHC-7.6 premise:
{{{#!haskell {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-}
data UnsafeBase base err val = Value val | Error err | Other (base val) deriving (Show, Eq)
class MagicMerge m1 m2 | m1 -> m2 where magicMerge :: m1 a -> m2 a
instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where magicMerge ma = case ma of Value a -> Value a Error e -> Error e Other o -> o
instance (MagicMerge (UnsafeBase base err2) dstBase) => MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where magicMerge (ma :: UnsafeBase (UnsafeBase base err1) err2 a) = case ma of Value a -> Value a Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) Other o -> case o of Value a -> Other $ magicMerge (Value a :: UnsafeBase base err2 a) Error e -> Error e Other o' -> Other $ magicMerge (Other o' :: UnsafeBase base err2 a)
main = print "help me world!" }}}
The code compiles and works ok in both GHC-7.6 and GHC-7.8. In such cases, GHC-7.8 should inform about lacking premises.
New description: Hello! The problem is not a bug related to proper code execution, but it affects the development in such way, we can treat it as a bug. Lets think about such simple code (it can be further simplified of course): {{{#!haskell {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-} data UnsafeBase base err val = Value val | Error err | Other (base val) deriving (Show, Eq) class MagicMerge m1 m2 | m1 -> m2 where magicMerge :: m1 a -> m2 a instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where magicMerge ma = case ma of Value a -> Value a Error e -> Error e Other o -> o instance MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where magicMerge (ma :: UnsafeBase (UnsafeBase base err1) err2 a) = case ma of Value a -> Value a Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) Other o -> case o of Value a -> Other $ magicMerge (Value a :: UnsafeBase base err2 a) Error e -> Error e Other o' -> Other $ magicMerge (Other o' :: UnsafeBase base err2 a) main = print "help me world!" }}} When trying to compile it using GHC-7.8, we get following error message: {{{#!haskell Illegal instance declaration for ‘MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’ The liberal coverage condition fails in class ‘MagicMerge’ for functional dependency: ‘m1 -> m2’ Reason: lhs type ‘UnsafeBase (UnsafeBase base err1) err2’ does not determine rhs type ‘UnsafeBase dstBase err1’ In the instance declaration for ‘MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1)’ }}} Which is of course right, but is completely unhelpfull! When we run the same program against GHC-7.6, we get another message: {{{#!haskell No instance for (MagicMerge (UnsafeBase base err2) dstBase) arising from a use of `magicMerge' Possible fix: add an instance declaration for (MagicMerge (UnsafeBase base err2) dstBase) In the second argument of `($)', namely `magicMerge (Error e :: UnsafeBase base err2 a)' In the expression: Other $ magicMerge (Error e :: UnsafeBase base err2 a) In a case alternative: Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) }}} And it contains a very helpfull information about inferred types. The information is very usefull, especialy when developing more complex instances. It is VERY IMPORTANT to notice, that when we use the inferred context, the code compiles in both, GHC-7.8 and GHC-7.6! Right now I have to use both versions of GHC side by side, to be able to develop my instances faster. So If we add the context inferred by GHC-7.6: {{{#!haskell {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-} data UnsafeBase base err val = Value val | Error err | Other (base val) deriving (Show, Eq) class MagicMerge m1 m2 | m1 -> m2 where magicMerge :: m1 a -> m2 a instance MagicMerge (UnsafeBase (UnsafeBase base err) err) (UnsafeBase base err) where magicMerge ma = case ma of Value a -> Value a Error e -> Error e Other o -> o instance (MagicMerge (UnsafeBase base err2) dstBase) => MagicMerge (UnsafeBase (UnsafeBase base err1) err2) (UnsafeBase dstBase err1) where magicMerge (ma :: UnsafeBase (UnsafeBase base err1) err2 a) = case ma of Value a -> Value a Error e -> Other $ magicMerge (Error e :: UnsafeBase base err2 a) Other o -> case o of Value a -> Other $ magicMerge (Value a :: UnsafeBase base err2 a) Error e -> Error e Other o' -> Other $ magicMerge (Other o' :: UnsafeBase base err2 a) main = print "help me world!" }}} The code compiles and works ok in both GHC-7.6 and GHC-7.8. In such cases, GHC-7.8 should inform about lacking premises. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9267#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied -------------------------------------------------+------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect warning at | Unknown/Multiple compile-time | Difficulty: Test Case: | Unknown Blocking: | Blocked By: | Related Tickets: -------------------------------------------------+------------------------- Changes (by danilo2): * priority: normal => high -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9267#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: 7.10.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Differential Revisions: | Operating System: Unknown/Multiple Architecture: | Type of failure: Incorrect Unknown/Multiple | warning at compile-time Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | -------------------------------------+------------------------------------- Comment (by simonpj): Interesting example. See all the discussion on #8634. The interesting thing here is that (using the vocabulary of #8634) * The initial error message might suggest `-XDysFunctionalDepenencies` * Adding `-XDysFunctionalDependencies` would yield the error in GHC 7.6 * Adding the suggested context to the instance declaration would remove the need for `-XDysFunctionalDependencies` again! If we implement the `DYSFUNCTIONAL` thing on a per-instance basis, as #8634 suggests, we should also warn when it is used but is not necessary. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9267#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: 7.10.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Differential Revisions: | Operating System: Unknown/Multiple Architecture: | Type of failure: Incorrect Unknown/Multiple | warning at compile-time Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | -------------------------------------+------------------------------------- Comment (by danilo2): @simonpj: This is exactly what I'm doing right now. If I migh suggest one thing - maybe it would be better to just report to the user 2 separate errors at once? One about not met liberal coverage condition and the second analogous to the one known from ghc-7.6? This just saves a lot of time with adding and removing flags :) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9267#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect | Unknown/Multiple warning at compile-time | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by thoughtpolice): * milestone: 7.10.1 => 7.12.1 Comment: Moving to 7.12, as this doesn't look like it will be fixed in the 7.10 timeframe. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9267#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9267: Lack of type information in GHC error messages when the liberage coverage condition is unsatisfied -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect | Unknown/Multiple warning at compile-time | Test Case: Blocked By: | Blocking: Related Tickets: #8634 | Differential Revisions: -------------------------------------+------------------------------------- Changes (by thomie): * priority: high => normal * related: => #8634 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9267#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC