[GHC] #14419: Check kinds for ambiguity

GHC ghc-devs at haskell.org
Fri May 25 08:51:03 UTC 2018


#14419: Check kinds for ambiguity
-------------------------------------+-------------------------------------
        Reporter:  goldfire          |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:  TypeInType
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 * I agree that `checkValidTyCon` is a better place.  (It's outside "the
 knot".)

 * We should ''remove'' any `checkValidType` calls on the individual kind
 ascriptions.  No point in calling it on the `a` in `data T (x::a) = ...`.
 I have not looked into just where we'd remove it.

 Your point about the ambiguity check is very interesting.  At the term
 level, the ambiguity check models this:
 {{{
 f :: forall a. F a -> Int
 f = ...

 f2 :: forall a. F a -> Int
 f2 = f
 }}}
 It's very confusing if `f2` does not typecheck; after all, it has the same
 type as `f`.  The ambiguity check tests this.  At the call of `f` we
 instantiate its foralls (say `a :-> alpha`); and then unify with a
 skolemised version of `f2`'s type.  And thus we unify `F alpha ~ F a` and
 fail.

 Analogously, suppose we said (as you suggest)
 {{{
 type family F (x :: a)
 type family T2 (x :: a) :: F x -- Kind: forall a. forall (x :: a) -> F x
 }}}
 I've changed your `T2` to be a data type.  Occurrences of `T2` will look
 like `T2 {a} x`, where the `{a}` is invisible in the source language; it
 is implicitly instantiate.  But not that the `x` argument is fully
 explicit.

 Now
 type T3 :: forall a. forall (x::a) -> F x
 type T3 x = T2 x
 }}}
 (I know we don't have separate kind signatures yet, but we will!)  Notice
 that we must apply `T2` to its explicit args; the `forall (x::a) -> blah`
 behaves like an arrow not like an (implicitly-instantiated) forall from
 the point of view of ambiguity checking.

 Looking at `TcUnify.tc_sub_type_ds`, the culprit looks like the call to
 `topInstantiate`. It already comes in two variants:
 * `topInstantiate`: instantiate all outer foralls
 * `topInstantiateInferred`: instantiate all outer `Inferred` foralls

 But the former instantiates `Required` foralls, and '''I think it should
 never do so.'''

 NB: See `Note [TyVarBndrs, TyVarBinders, TyConBinders, and visibility]` in
 `TyCoRep` for a refresher on `Inferred/Specified/Required`.  (NB:
 `Required` binders never occur in the foralls of a term variable, so this
 change cannot affect the term level.)

 Richard, do you agree? Ryan, would you like to try that (a one-line change
 in `should_inst` in `Inst.top_instantiate`)?

 Richard, I must say that I find it hard to be sure where we should call
 `topInstantiate` and where `topInstantiateInferred`.  Some comments at the
 call sites would be very welcome.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14419#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list