
#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