Type inferece problem for case class with type member

57 Views Asked by At

Consider the following example:

sealed trait Kind

case object B extends Kind
case object C extends Kind

sealed trait Test {
  type K <: Kind
  val kind: K
}

object Test {
  type Aux[KK <: Kind] = Test { type K = KK }
}

sealed trait Suite{
  type K <: Kind
  val kind: K
  val tests: List[Test.Aux[K]]
}

def runSuite(suite: Suite): Unit = {
  suite.kind match {
    case _: B.type =>
      val tests: List[Test.Aux[B.type]] = suite.tests
      //
    case _: C.type =>
      val tests: List[Test.Aux[C.type]] = suite.tests
      //
  }
}

It looks naturally, but it doesn't compile:

Error:(47, 51) type mismatch;
 found   : List[Test.Aux[suite.K]]
    (which expands to)  List[Test{type K = suite.K}]
 required: List[Test.Aux[B.type]]
    (which expands to)  List[Test{type K = B.type}]
        val tests: List[Test.Aux[B.type]] = suite.tests
Error:(50, 51) type mismatch;
 found   : List[Test.Aux[suite.K]]
    (which expands to)  List[Test{type K = suite.K}]
 required: List[Test.Aux[C.type]]
    (which expands to)  List[Test{type K = C.type}]
        val tests: List[Test.Aux[C.type]] = suite.tests

I replaced it with asInstanceOf workaround:

def runSuite(suite: Suite): Unit = {
  suite.kind match {
    case _: B.type =>
      val tests: List[Test.Aux[B.type]] = suite.tests.asInstanceOf[List[Test.Aux[B.type]]]
      //
    case _: C.type =>
      val tests: List[Test.Aux[C.type]] = suite.tests.asInstanceOf[List[Test.Aux[C.type]]]
      //
  }
}

And it compiles fine. Is the asInstanceOf safe here and it's just another problem of Scala 2 type member semantics or there is another reason behind it?

0

There are 0 best solutions below