With GHC HEAD, this gives the same error as the original program. But if you add this one definition to this file:

test1::Chartest1=(const 'p')`ext1Q`(\T->'q')$(T::T())

Then it typechecks without issue on GHC HEAD! This is pretty bizarre, considering that the error was originally reported in dataCast1T, and we managed to make the error go away without making a single change to dataCast1T.

FWIW, this program also compiles without issue on GHC 8.0.2 (with and without test1).

I now think I know what's going on here, but unsure the best way to fix it. Interestingly, the problem has nothing to do with Typeable or TypeInType. Indeed it's amazing we've never hit this problem before.

We have

[G] c1 :: k1[tau] ~ j1[tau]

in an implication. Both k1 and j1 are filled in at this point: k1 := Type and j1 := k2[sk]. This constraint is then passed through solveSimpleGivens, where it is canonicalized. can_eq_nc' flattens both sides, following both k1 and j1 to find Type. can_eq_nc' then calls rewriteEqEvidence which creates a new

[G] c2 :: Type ~ k2[sk]

Of course, GHC produces evidence for c2: c2 = g1 ; c1 ; g2, where g1 and g2 are the coercions that come from flattening k1 and j1.

The problem is that these coercions, g1 and g2 are both reflexive, as they arise simply from zonking. See the line of code ​here. When c2 is stitched together from g1, c1, and g2, the calls to mkTcTransCo notice that some of the arguments are Refl, and so ignores the reflexive arguments. The end result is that c2 = c1. And then, when c2 gets put in the inert set, its kind still mentions unzonked variables. (Even though the associated ctPred is just fine.)

What to do? Here are some ideas:

Stop mkTcTransCo (but not mkTransCo) from optimizing this case.

Add a zonk somewhere (addInertEq? seems better than rewriteEqEvidence) to fix this problem.

Add a new coercion form ZonkCo that relates an unzonked tyvar to its contents. This way, we can have the invariant that, whenever (ty', co) <- flatten ty, we have co :: ty' ~ ty. (Right now, that final equality is true only modulo zonking. But the new ZonkCo would allow it to be true without needing to zonk.) In fully-typechecked Core, ZonkCo would zonk to become reflexive, and so Core would have no ZonkCos.

Add a new castTcCoercion function that stitches three coercions together using transitivity; this castTcCoercion would cleverly not optimize the Refl away.

I favor (1) but am worried about performance implications. (3) is probably the most principled, but it seems like a sledgehammer to tap in a nail. (4) is a middle ground, but I'm worried that what's happening here (a coercion returned from the flattener having an unzonked kind) happens elsewhere where we wouldn't use castTcCoercion.

What are your thoughts?

(NB: The patch linked to here does not have any of these fixes. I posted that patch some time ago but never added the link from this ticket.)

I'm sorry, but I still don't get it. Why don't we fix the bug that makes the Note untrue? I do not understand why it's bad for an evidence term (which the constraint solver never looks at) to be Refl, if it relates two types that are equal after zonking.

Your diagnosis concludes

And then, when c2 gets put in the inert set, its kind still mentions unzonked variables.

Fix #13333 by fixing the covar's type in ctEvCoercion
The change is noted in Note [Given in ctEvCoercion]. This patch
also adds a bit more commentary to TcFlatten, documenting some
key invariants of the flattening algorithm. While in the area,
I also removed some stale commentary from TcCanonical.