Refactor the treatment of predicate types
authorSimon Peyton Jones <simonpj@microsoft.com>
Tue, 16 Oct 2018 11:38:16 +0000 (12:38 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Wed, 24 Oct 2018 15:38:55 +0000 (16:38 +0100)
commit0faf7fd3e6c652575af9993787f07cad86f452f6
tree029d5a626ac2677305151120cd4a0a4a144c6493
parent321bc1a644a9e4598a4af30d4aeae315f0ff487a
Refactor the treatment of predicate types

Trac #15648 showed that GHC was a bit confused about the
difference between the types for

* Predicates
* Coercions
* Evidence (in the typechecker constraint solver)

This patch cleans it up. See especially Type.hs
Note [Types for coercions, predicates, and evidence]

Particular changes

* Coercion types (a ~# b) and (a ~#R b) are not predicate types
  (so isPredTy reports False for them) and are not implicitly
  instantiated by the type checker.  This is a real change, but
  it consistently reflects that fact that (~#) and (~R#) really
  are different from predicates.

* isCoercionType is renamed to isCoVarType

* During type inference, simplifyInfer, we do /not/ want to infer
  a constraint (a ~# b), because that is no longer a predicate type.
  So we 'lift' it to (a ~ b). See TcType
  Note [Lift equality constaints when quantifying]

* During type inference for pattern synonyms, we need to 'lift'
  provided constraints of type (a ~# b) to (a ~ b).  See
  Note [Equality evidence in pattern synonyms] in PatSyn

* But what about (forall a. Eq a => a ~# b)? Is that a
  predicate type?  No -- it does not have kind Constraint.
  Is it an evidence type?  Perhaps, but awkwardly so.

  In the end I decided NOT to make it an evidence type,
  and to ensure the the type inference engine never
  meets it.  This made me /simplify/ the code in
  TcCanonical.makeSuperClasses; see TcCanonical
  Note [Equality superclasses in quantified constraints]

  Instead I moved the special treatment for primitive
  equality to TcInteract.doTopReactOther.  See TcInteract
  Note [Looking up primitive equalities in quantified constraints]

  Also see Note [Evidence for quantified constraints] in Type.

  All this means I can have
     isEvVarType ty = isCoVarType ty || isPredTy ty
  which is nice.

All in all, rather a lot of work for a small refactoring,
but I think it's a real improvement.
17 files changed:
compiler/basicTypes/Id.hs
compiler/coreSyn/CoreLint.hs
compiler/coreSyn/CoreOpt.hs
compiler/coreSyn/CoreUtils.hs
compiler/deSugar/DsBinds.hs
compiler/typecheck/ClsInst.hs
compiler/typecheck/TcCanonical.hs
compiler/typecheck/TcErrors.hs
compiler/typecheck/TcEvidence.hs
compiler/typecheck/TcInteract.hs
compiler/typecheck/TcPatSyn.hs
compiler/typecheck/TcType.hs
compiler/types/TyCoRep.hs
compiler/types/Type.hs
testsuite/tests/partial-sigs/should_compile/T15039c.stderr
testsuite/tests/partial-sigs/should_compile/T15039d.stderr
testsuite/tests/typecheck/should_fail/T13320.stderr