Skip to content

wildApprox clobbers HKTypeLambdas representing kinds #6238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
milessabin opened this issue Apr 4, 2019 · 0 comments
Closed

wildApprox clobbers HKTypeLambdas representing kinds #6238

milessabin opened this issue Apr 4, 2019 · 0 comments
Assignees
Labels
area:implicits related to implicits area:typer

Comments

@milessabin
Copy link
Contributor

milessabin commented Apr 4, 2019

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.

@milessabin milessabin added area:typer area:implicits related to implicits labels Apr 4, 2019
@milessabin milessabin self-assigned this Apr 4, 2019
odersky added a commit to dotty-staging/dotty that referenced this issue Apr 6, 2019
Replacing a higher-kinded bound by a wildcard changes its kind.
We need to keep the bound intact in this case but recursively
approximate its contents.
smarter pushed a commit to dotty-staging/dotty that referenced this issue Apr 6, 2019
I'm not entirely sure why this fixes the issue but the previous behavior
seems dubious to me: what's the meaning of applying a WildcardType
argument to a type lambda ? By contrast, applying a TypeBounds has a
well-defined behavior (`appliedTo` will call `TypeApplication#Reducer` to
get rid of the type lambda).
smarter added a commit to dotty-staging/dotty that referenced this issue Apr 6, 2019
I'm not entirely sure why this fixes the issue but the previous behavior
seems dubious to me: what's the meaning of applying a WildcardType
argument to a type lambda ? By contrast, applying a TypeBounds has a
well-defined behavior (`appliedTo` will call `TypeApplication#Reducer` to
get rid of the type lambda).
smarter added a commit to dotty-staging/dotty that referenced this issue Apr 6, 2019
I'm not entirely sure why this fixes the issue but the previous behavior
seems dubious to me: what's the meaning of applying a WildcardType
argument to a type lambda ? By contrast, applying a TypeBounds has a
well-defined behavior (`appliedTo` will call `TypeApplication#Reducer` to
get rid of the type lambda).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:implicits related to implicits area:typer
Projects
None yet
Development

No branches or pull requests

1 participant