Implement QuantifiedConstraints
authorSimon Peyton Jones <simonpj@microsoft.com>
Sat, 27 Jan 2018 14:32:34 +0000 (14:32 +0000)
committerBen Gamari <ben@smart-cactus.org>
Mon, 4 Jun 2018 18:24:08 +0000 (14:24 -0400)
commit7df589608abb178efd6499ee705ba4eebd0cf0d1
tree60754f196249df0a2f65a06383b78f5ba955723c
parent36091ec94e85d871b12b07e69c1589224d1dd7e2
Implement QuantifiedConstraints

We have wanted quantified constraints for ages and, as I hoped,
they proved remarkably simple to implement.   All the machinery was
already in place.

The main ticket is Trac #2893, but also relevant are
  #5927
  #8516
  #9123 (especially!  higher kinded roles)
  #14070
  #14317

The wiki page is
  https://ghc.haskell.org/trac/ghc/wiki/QuantifiedConstraints
which in turn contains a link to the GHC Proposal where the change
is specified.

Here is the relevant Note:

Note [Quantified constraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The -XQuantifiedConstraints extension allows type-class contexts like
this:

  data Rose f x = Rose x (f (Rose f x))

  instance (Eq a, forall b. Eq b => Eq (f b))
        => Eq (Rose f a)  where
    (Rose x1 rs1) == (Rose x2 rs2) = x1==x2 && rs1 >= rs2

Note the (forall b. Eq b => Eq (f b)) in the instance contexts.
This quantified constraint is needed to solve the
 [W] (Eq (f (Rose f x)))
constraint which arises form the (==) definition.

Here are the moving parts
  * Language extension {-# LANGUAGE QuantifiedConstraints #-}
    and add it to ghc-boot-th:GHC.LanguageExtensions.Type.Extension

  * A new form of evidence, EvDFun, that is used to discharge
    such wanted constraints

  * checkValidType gets some changes to accept forall-constraints
    only in the right places.

  * Type.PredTree gets a new constructor ForAllPred, and
    and classifyPredType analyses a PredType to decompose
    the new forall-constraints

  * Define a type TcRnTypes.QCInst, which holds a given
    quantified constraint in the inert set

  * TcSMonad.InertCans gets an extra field, inert_insts :: [QCInst],
    which holds all the Given forall-constraints.  In effect,
    such Given constraints are like local instance decls.

  * When trying to solve a class constraint, via
    TcInteract.matchInstEnv, use the InstEnv from inert_insts
    so that we include the local Given forall-constraints
    in the lookup.  (See TcSMonad.getInstEnvs.)

  * topReactionsStage calls doTopReactOther for CIrredCan and
    CTyEqCan, so they can try to react with any given
    quantified constraints (TcInteract.matchLocalInst)

  * TcCanonical.canForAll deals with solving a
    forall-constraint.  See
       Note [Solving a Wanted forall-constraint]
       Note [Solving a Wanted forall-constraint]

  * We augment the kick-out code to kick out an inert
    forall constraint if it can be rewritten by a new
    type equality; see TcSMonad.kick_out_rewritable

Some other related refactoring
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Move SCC on evidence bindings to post-desugaring, which fixed
  #14735, and is generally nicer anyway because we can use
  existing CoreSyn free-var functions.  (Quantified constraints
  made the free-vars of an ev-term a bit more complicated.)

* In LookupInstResult, replace GenInst with OneInst and NotSure,
  using the latter for multiple matches and/or one or more
  unifiers
44 files changed:
compiler/basicTypes/Id.hs
compiler/deSugar/DsBinds.hs
compiler/main/DynFlags.hs
compiler/specialise/Specialise.hs
compiler/typecheck/Inst.hs
compiler/typecheck/TcCanonical.hs
compiler/typecheck/TcErrors.hs
compiler/typecheck/TcEvTerm.hs
compiler/typecheck/TcEvidence.hs
compiler/typecheck/TcHsSyn.hs
compiler/typecheck/TcInstDcls.hs
compiler/typecheck/TcInteract.hs
compiler/typecheck/TcMType.hs
compiler/typecheck/TcPatSyn.hs
compiler/typecheck/TcPluginM.hs
compiler/typecheck/TcRnTypes.hs
compiler/typecheck/TcSMonad.hs
compiler/typecheck/TcSimplify.hs
compiler/typecheck/TcType.hs
compiler/typecheck/TcValidity.hs
compiler/types/Class.hs
compiler/types/InstEnv.hs
compiler/types/Kind.hs
compiler/types/Type.hs
docs/users_guide/glasgow_exts.rst
libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs
testsuite/tests/driver/T4437.hs
testsuite/tests/quantified-constraints/Makefile [new file with mode: 0644]
testsuite/tests/quantified-constraints/T14833.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T14835.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T14863.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T14961.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T2893.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T2893a.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T2893c.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T9123.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/T9123a.hs [new file with mode: 0644]
testsuite/tests/quantified-constraints/all.T [new file with mode: 0644]
testsuite/tests/rebindable/T5908.hs
testsuite/tests/typecheck/should_compile/T14735.hs [new file with mode: 0644]
testsuite/tests/typecheck/should_compile/all.T
testsuite/tests/typecheck/should_fail/T7019.stderr
testsuite/tests/typecheck/should_fail/T7019a.stderr
testsuite/tests/typecheck/should_fail/T9196.stderr