George
George

Reputation: 17

Scala : Generic abstract type ignored for isInstanceOf

Can someone explain why the output of this code is true true, instead of true false.

I would also like to know how I could achieve a output that is true false using def apply(in:Any). I've tried parameterised types too, and still i get true true instead of true false.

 object TestClass extends App {

  val xTrue = TypeXObject(TypeX("s"))
  val xFalse = TypeXObject(TypeY(1))
 }

 case class TypeX(string:String)

 case class TypeY(int:Int)

 object TypeXObject extends HasAbstractType{override type T = TypeX}

 object TypeYObject extends HasAbstractType{override type T = TypeY}

 abstract class HasAbstractType {
   type T
   def apply(in:Any):Any = {
     println(in.isInstanceOf[T])
     in
   }
 }

Answer:

issues.scala-lang.org/browse/SI-5042 - With article and the attached article i found that I can get the true false with manifest[T1].erasure.isInstance(t1) and manifest[T1].erasure.isInstance(t2).

Upvotes: 1

Views: 2824

Answers (1)

Leif Wickland
Leif Wickland

Reputation: 3724

When I compile your code I get the following compiler message:

[warn] there were 1 unchecked warnings; re-run with -unchecked for details
[warn] one warning found

To pass -unchecked to the compiler, I create a build.sbt containing:

scalacOptions ++= Seq("-unchecked", "-deprecated") // (I threw in deprecated for good measure)

Then when I compile, I get this enlightening warning:

[warn] /home/lwickland/f/f.scala:18: abstract type HasAbstractType.this.T in type HasAbstractType.this.T is unchecked since it is eliminated by erasure
[warn]     println(in.isInstanceOf[T])

And at that point, I have to refer you to an excellent explanation of type erasure and how to get around it.

Upvotes: 7

Related Questions