title: Path-dependent types vs. "underlying types", which ones are checked?
body: <p>When using path-dependent types with reflection I am getting a type mismatch error even though I have matching "underlying types". What are these "non-underlying types" and why are they checked instead of the "underlying types"?</p>
  
  <p>In the code below, I want the <code>compare</code> method to accept only same-type subclasses of A as arguments. The error is on the last line.</p>
  
  <pre><code>abstract class A(val a:Int) {
    type Impl &lt;: 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
    }
  }
  </code></pre>
  
  <p>On the last line I get this error:</p>
  
  <pre><code>error: type mismatch;
  found   : b2.type (with underlying type A)
  required: b1.Impl
  </code></pre>
  
  <p>Since the type of b2 is the same as the type of b1 (which is A), I expected this to not generate an error. For some reason these path-dependent types are different than the "underlying types" when using reflection. Why? </p>
  
  <p>If I do not use reflection, it works:</p>
  
  <pre><code>val b1 = new B(4)
  val b2 = new B(5)
  b1.compare(b2)  // no errors
  </code></pre>
  
  <p>(I do need to use reflection in my case). Can <code>newInst()</code> return the object as class "B",  using reflection? Would this help? Is there type erasure when using abstract types?</p>
  
  <p>This is the only reference I found (<a href="http://scala-programming-language.1934581.n4.nabble.com/Confusing-type-error-found-X-required-X-td1934680.html" rel="nofollow">on this forum</a>) about the same error, but it may not be related.</p>