liftCoMatch is sort of inverse to liftCoSubst. In particular, if
liftCoMatch vars ty co == Just s, then liftCoSubst s ty == co,
where == there means that the result of liftCoSubst has the same
type as the original co; but may be different under the hood.
That is, it matches a type against a coercion of the same
"shape", and returns a lifting substitution which could have been
used to produce the given coercion from the given type.
Note that this function is incomplete -- it might return Nothing
when there does indeed exist a possible lifting context.
This function is incomplete in that it doesn't respect the equality
in eqType. That is, it's possible that this will succeed for t1 and
fail for t2, even when t1 eqType t2. That's because it depends on
there being a very similar structure between the type and the coercion.
This incompleteness shouldn't be all that surprising, especially because
it depends on the structure of the coercion, which is a silly thing to do.
The lifting context produced doesn't have to be exacting in the roles
of the mappings. This is because any use of the lifting context will
also require a desired role. Thus, this algorithm prefers mapping to
nominal coercions where it can do so.