Skip to content

wildApprox clobbers HKTypeLambdas representing kinds #6238

Closed
@milessabin

Description

@milessabin

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions