+match_kind :: MatchEnv -> TvSubstEnv -> TyVar -> Type -> Maybe TvSubstEnv
+-- Match the kind of the template tyvar with the kind of Type
+-- Note [Matching kinds]
+match_kind menv subst tv ty
+ | isCoVar tv = do { let (ty1,ty2) = splitCoercionKind (tyVarKind tv)
+ (ty3,ty4) = coercionKind ty
+ ; subst1 <- match menv subst ty1 ty3
+ ; match menv subst1 ty2 ty4 }
+ | otherwise = if typeKind ty `isSubKind` tyVarKind tv
+ then Just subst
+ else Nothing
+
+-- Note [Matching kinds]
+-- ~~~~~~~~~~~~~~~~~~~~~
+-- For ordinary type variables, we don't want (m a) to match (n b)
+-- if say (a::*) and (b::*->*). This is just a yes/no issue.
+--
+-- For coercion kinds matters are more complicated. If we have a
+-- coercion template variable co::a~[b], where a,b are presumably also
+-- template type variables, then we must match co's kind against the
+-- kind of the actual argument, so as to give bindings to a,b.
+--
+-- In fact I have no example in mind that *requires* this kind-matching
+-- to instantiate template type variables, but it seems like the right
+-- thing to do. C.f. Note [Matching variable types] in Rules.lhs
+
+--------------