[GHC] #8851: Standalone deriving and GND behave differently

GHC ghc-devs at haskell.org
Mon Mar 10 08:56:11 UTC 2014


#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


More information about the ghc-tickets mailing list