Description
wildApprox
's job is to "approximate occurrences of parameter types and uninstantiated typevars by wildcard types". Unfortunately it's a little over-enthusiastic and also eliminates the type parameters bound by HKTypeLambdas
used to represent kinds.
Implicit resolution is one of the main users of wildApprox
and this bug showed up as a consequence of the fix for #6058. In the following,
class Foo[T]
class Bar[F[_]]
object Bar {
implicit def barF[F[_]](implicit fooF: Foo[Bar[F]]): Bar[F] = null
}
class A[T]
object A {
implicit def fooA[F[_[_]]](implicit barB: F[B]): Foo[F[A]] = null
}
class B[T]
object B {
implicit def fooB[F[_[_]]]: Foo[F[B]] = null
}
implicitly[Bar[A]]
the divergence checker reports divergence (via barF
) when expanding Bar[B]
in the process of expanding Bar[A]
. It does this because even though Bar[A]
and Bar[B]
are not =:=
(which should block divergence) currently wildApprox(Bar[A])
and wildApprox(Bar[B])
are =:=
.
This happens because the types A
and B
in Bar[A]
and Bar[B]
are wrapped in HKTypeLambdas
at this point in typechecking, ie. these types are effectively represented as,
Bar[[T] => A[T]]
Bar[[T] => B[T]]
When wildApprox
is applied to them they're transformed into,
Bar[[T] => A[_]]
Bar[_ <: [_$1] => Any]
respectively, which =:=
then report as equal (this is also a bit fishy, but the wildApprox
transformation is clearly wrong).
This can be fixed (PR incoming) by modifying wildApprox
to leave alone TypeParamRefs
corresponding to HKTypeLambdas
which represent kinds.