scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.88k stars 1.06k forks source link

Wrong "isInstanceOf[Array[?]]" #12071

Closed flomebul closed 3 years ago

flomebul commented 3 years ago

Compiler version

scala-3.0.0-RC2

Minimized code

scala> 1.isInstanceOf[Array[?]]
1 |1.isInstanceOf[Array[?]]
  |^^^^^^^^^^^^^^^^^^^^^^^^
  |cannot test if value of type Int is a reference of class Object

scala> 1.asInstanceOf[Array[?]]
val res0: Array[?] = 1

scala> (1: Any).isInstanceOf[Array[?]]
val res1: Boolean = true

scala> (1: Any).asInstanceOf[Array[?]]
val res2: Array[?] = 1

Expectation

SethTisue commented 3 years ago
scala> (1: Any).isInstanceOf[Array[?]]
val res1: Boolean = true

yes, that's a regression since Scala 2; it should return false. good catch!

the others are not bugs. isInstanceOf should never raise an exception, and asInstanceOf is a promise to the compiler that you know what you're doing. that asInstanceOf bypasses compile-time error checking (though it does insert a runtime cast to the erased type) is exactly why it exists

SethTisue commented 3 years ago

note that autoboxing isn't the culprit here, and Any isn't the culprit either, nor is Integer:

scala> Integer.valueOf(1).isInstanceOf[Array[?]]
val res4: Boolean = true

scala> (new AnyRef).isInstanceOf[Array[?]]
val res5: Boolean = true
Jasper-M commented 3 years ago

The erasure of Array[?] is Object in Scala 2 and 3, so I guess Scala 2 does something special for arrays.

sjrd commented 3 years ago

This is what it does: https://github.com/scala/scala/blob/b372fb329327cb73bf61c7ccaa162ec8c635b23f/src/library/scala/runtime/ScalaRunTime.scala#L30

SethTisue commented 3 years ago

Guillaume's PR: #12103