Refactor DeriveAnyClass's instance context inference
authorRyan Scott <ryan.gl.scott@gmail.com>
Fri, 10 Feb 2017 21:12:46 +0000 (16:12 -0500)
committerRyan Scott <ryan.gl.scott@gmail.com>
Fri, 10 Feb 2017 21:12:46 +0000 (16:12 -0500)
commit639e702b6129f501c539b158b982ed8489e3d09c
treeed0ba96b92410b8882731df256f543d30242b8d2
parente79ef75d9a224ab1eac1c237e686bcaef97b8e9c
Refactor DeriveAnyClass's instance context inference

Summary:
Currently, `DeriveAnyClass` has two glaring flaws:

* It only works on classes whose argument is of kind `*` or `* -> *` (#9821).
* The way it infers constraints makes no sense. It basically co-opts the
  algorithms used to infer contexts for `Eq` (for `*`-kinded arguments) or
  `Functor` (for `(* -> *)`-kinded arguments). This tends to produce overly
  constrained instances, which in extreme cases can lead to legitimate things
  failing to typecheck (#12594). Or even worse, it can trigger GHC panics
  (#12144 and #12423).

This completely reworks the way `DeriveAnyClass` infers constraints to fix
these two issues. It now uses the type signatures of the derived class's
methods to infer constraints (and to simplify them). A high-level description
of how this works is included in the GHC users' guide, and more technical notes
on what is going on can be found as comments (and a Note) in `TcDerivInfer`.

Fixes #9821, #12144, #12423, #12594.

Test Plan: ./validate

Reviewers: dfeuer, goldfire, simonpj, austin, bgamari

Subscribers: dfeuer, thomie

Differential Revision: https://phabricator.haskell.org/D2961
21 files changed:
compiler/typecheck/TcDeriv.hs
compiler/typecheck/TcDerivInfer.hs
compiler/typecheck/TcDerivUtils.hs
compiler/typecheck/TcSimplify.hs
compiler/typecheck/TcType.hs
docs/users_guide/8.2.1-notes.rst
docs/users_guide/glasgow_exts.rst
testsuite/tests/deriving/should_compile/T12144_1.hs [new file with mode: 0644]
testsuite/tests/deriving/should_compile/T12144_2.hs [new file with mode: 0644]
testsuite/tests/deriving/should_compile/T12423.hs [new file with mode: 0644]
testsuite/tests/deriving/should_compile/T12594.hs [new file with mode: 0644]
testsuite/tests/deriving/should_compile/T9968a.hs [moved from testsuite/tests/deriving/should_fail/T9968a.hs with 100% similarity]
testsuite/tests/deriving/should_compile/T9968a.stderr [new file with mode: 0644]
testsuite/tests/deriving/should_compile/all.T
testsuite/tests/deriving/should_fail/T10598_fail1.stderr
testsuite/tests/deriving/should_fail/T9968a.stderr [deleted file]
testsuite/tests/deriving/should_fail/all.T
testsuite/tests/deriving/should_fail/drvfail004.stderr
testsuite/tests/deriving/should_fail/drvfail012.stderr
testsuite/tests/typecheck/should_fail/tcfail046.stderr
testsuite/tests/typecheck/should_fail/tcfail169.stderr