
#8851: Standalone deriving and GND behave differently -------------------------------------------------+------------------------- Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: 7.8.1 Component: Compiler (Type checker) | Version: Resolution: | 7.8.1-rc1 Operating System: Unknown/Multiple | Keywords: Type of failure: None/Unknown | Architecture: Test Case: | Unknown/Multiple deriving/should_compile/T8851 | Difficulty: Blocking: | Unknown | Blocked By: | Related Tickets: -------------------------------------------------+------------------------- Comment (by simonpj): I've reflected on this some more. First, standalone deriving has always been more aggressive than a deriving clause: * A deriving clause makes conservative checks that should ensure that the generated boilerplate code never fails to type check. * Standalone deriving makes weaker checks (enough to ensure that the boilerplate code can be generated in the first place), but then generates the code and risks that it might not typecheck. The reason for this is that it's too hard to predict exactly what will succeed; see #3102 for the origin of this change. The only down-side of the standalone-deriving story is that the error message may refer to (generated boilerplate) code that you didn't write. You could also argue that it's confusing to conflate (a) standalone vs attached-to-decl, with (b) conservative vs aggressive. Well, yes. After all, as you'll see from the description of this ticket, it confused even me and I wrote the implementation! Second, a deriving clause is not given the context of the instance declaration, so it has to infer it: {{{ data T a = T1 [a] | T2 (Tree a) deriving( Ord ) generates instance ( ??? ) => Ord (T a) where ... }}} We have to infer the `???`. It does this by generating (in this example) an `Ord` constraint for each constructor argument (in this case `(Ord [a], Ord (Tree a))`) and simplifying. But what we want for this `Coercible` case is not to ''infer'' a context, but rather to ''check'' that certain wanted constraints can be deduced from other given constraints, and to do so method-by-method. There is no code path to do this right now. Bottom line: we can always make the (necessarily-conservative) deriving- clause checks more permissive, but doing so adds code and complexity. I'm inclined instead to declare this case to be an example of where you must use a standalone-deriving clause. In short I propose no action. I'll update the user manual (which does mention this point) be more explicit. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8851#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler