Path-dependent types and "base types", which ones are checked?

When using path-dependent reflection types, I get a type mismatch error, although I have the corresponding "base types". What are these "non-base types" and why are they checked instead of "base types"?

In the code below, I want the method to compareaccept only subclasses of type A as arguments. The error is on the last line.

abstract class A(val a:Int) {
  type Impl <: A
  def compare(other:Impl) {
    if(a==other.a) println("equal") else println("diff")
  }
}
class B(a:Int) extends A(a) {type Impl = B}

object Test {
  def newInst(a: Int, className: String) = {
    val constr = Class.forName(className).getConstructors()(0)
    constr.newInstance(a.asInstanceOf[AnyRef]).asInstanceOf[A]
  }

  def main(args: Array[String]) {
    val b1 = newInst(4, "B")
    val b2 = newInst(5, "B")
    b1.compare(b2)   // type mismatch error here
  }
}

In the last line, I get this error:

error: type mismatch;
found   : b2.type (with underlying type A)
required: b1.Impl

Since type b2 is the same as type b1 (which is A), I expected this to not lead to an error. For some reason, these path-dependent types differ from the "base types" when using reflection. What for?

If I do not use reflection, it works:

val b1 = new B(4)
val b2 = new B(5)
b1.compare(b2)  // no errors

( ). newInst() "B", ? ? ?

, ( ) , .

+3
2

. b1 b2 A ( newInst). b1.compare(b2) b2 b1.Impl. , A, , . A, A, .

val b1 = new B(4)
val b2 = new B(5)
b1.compare(b2)  // no errors

B, B#Impl - B, typechecks.

+5

. " " , " ". newInst "className", Scala. "

" ". . . 5 - ; - Int. Int " ". (, , .)

, . : scala java .

def main(args: Array[String]) {
  val b1 = newInst(4, "B")
  val b2 = newInst(5, "B")
  b1.compare(b2.asInstanceOf[b1.Impl])
}
% scala Test
diff
+5

Source: https://habr.com/ru/post/1789610/


All Articles