Skip to content

Scala 2 Regression: Upper bound of a higher-kinded type variable is not included into implicit search scope #13986

Closed
@neko-kai

Description

@neko-kai

Compiler version

3.1.2-RC1-bin-20211118-2b37257-NIGHTLY

Minimized code

Scastie: https://scastie.scala-lang.org/mBqRVwrfQpqZeLBUKzf8xQ

package example

sealed trait Xa[T]
sealed trait Mu[T] extends Xa[T]
object Xa {
  implicit def convertMu[X[x] <: Xa[x], A, B](implicit t: X[A]): X[B] = t.asInstanceOf[X[B]]
}
object Mu {
  implicit def mu: Mu[Int] = new Mu[Int] {}
}

object App extends App {
  def constrain(a: Mu[Long]): Unit = println(a)
  constrain(Xa.convertMu)
}

Output

no implicit argument of type X[A] was found for parameter t of method convertMu in object Xa

where:    A is a type variable
          X is a type variable with constraint <: example.Mu


The following import might fix the problem:

  import example.Mu.mu

Expectation

Expected to work, as in Scala 2: https://scastie.scala-lang.org/MesjnzXeRCSarfLr7HCGHA
This seems to affect only higher-kinded types, I could not reproduce it with a non-parameterized implicit with a roughly similar setup - https://scastie.scala-lang.org/XW8Yy4CXQmSXgslU0Wktew

  • NOTE 1: Specifying just the type Mu explicitly, e.g. using partial application below will get rid of the error:

    def convertMuPartial[X[x] <: Xa[x]]: [A, B] => X[A] ?=> () => X[B] = {
      [A, B] => (t: X[A]) ?=> () => Xa.convertMu[X, A, B](t)
    }
    constrain(convertMuPartial[Mu]())

    The implicit scope gets lost only when the searchable becomes a type parameter at some point in the search.

  • NOTE 2: The searched-for type is determined correctly and applying the suggestion to import example.Mu.mu will get rid of the error. However, this import should not be required because Mu companion object should be included in implicit scope, brought in by constraint on X <: example.Mu.

In addition, varying the above setup slightly produces an assertion failure compiler crash: #13987

This error currently blocks me from porting Izumi BIO to Scala 3, where a similar implicit is used https://github.com/7mind/izumi/blob/develop/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/Root.scala#L120

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions