Skip to content

Commit

Permalink
Align erasure of Array[Nothing] and Array[Null] with Scala 2 (#22517
Browse files Browse the repository at this point in the history
)

Closes #22515
  • Loading branch information
hamzaremmal authored Feb 5, 2025
2 parents a3dde8b + f77b1f9 commit 0ea05aa
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
20 changes: 11 additions & 9 deletions compiler/src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ object TypeErasure {
val sym = t.symbol
// Only a few classes have both primitives and references as subclasses.
if (sym eq defn.AnyClass) || (sym eq defn.AnyValClass) || (sym eq defn.MatchableClass) || (sym eq defn.SingletonClass)
|| isScala2 && !(t.derivesFrom(defn.ObjectClass) || t.isNullType) then
|| isScala2 && !(t.derivesFrom(defn.ObjectClass) || t.isNullType | t.isNothingType) then
NoSymbol
// We only need to check for primitives because derived value classes in arrays are always boxed.
else if sym.isPrimitiveValueClass then
Expand Down Expand Up @@ -596,8 +596,8 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
* will be returned.
*
* In all other situations, |T| will be computed as follow:
* - For a refined type scala.Array+[T]:
* - if T is Nothing or Null, []Object
* - For a refined type scala.Array[T]:
* - {Scala 2} if T is Nothing or Null, []Object
* - otherwise, if T <: Object, []|T|
* - otherwise, if T is a type parameter coming from Java, []Object
* - otherwise, Object
Expand Down Expand Up @@ -781,12 +781,14 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst

private def eraseArray(tp: Type)(using Context) = {
val defn.ArrayOf(elemtp) = tp: @unchecked
if (isGenericArrayElement(elemtp, isScala2 = sourceLanguage.isScala2)) defn.ObjectType
else
try
val eElem = erasureFn(sourceLanguage, semiEraseVCs = false, isConstructor, isSymbol, inSigName)(elemtp)
if eElem.isInstanceOf[WildcardType] then WildcardType
else JavaArrayType(eElem)
if isGenericArrayElement(elemtp, isScala2 = sourceLanguage.isScala2) then
defn.ObjectType
else if sourceLanguage.isScala2 && (elemtp.hiBound.isNullType || elemtp.hiBound.isNothingType) then
JavaArrayType(defn.ObjectType)
else
try erasureFn(sourceLanguage, semiEraseVCs = false, isConstructor, isSymbol, inSigName)(elemtp) match
case _: WildcardType => WildcardType
case elem => JavaArrayType(elem)
catch case ex: Throwable =>
handleRecursive("erase array type", tp.show, ex)
}
Expand Down
2 changes: 2 additions & 0 deletions sbt-test/scala2-compat/erasure/build.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ThisBuild / fork := true

lazy val scala2Lib = project.in(file("scala2Lib"))
.settings(
scalaVersion := sys.props("plugin.scala2Version")
Expand Down
6 changes: 6 additions & 0 deletions sbt-test/scala2-compat/erasure/dottyApp/Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,10 @@ class Z {
def objectARRAY_88(x: Array[Any]): Unit = {}
def objectARRAY_89(x: Array[AnyRef]): Unit = {}
def objectARRAY_90(x: Array[AnyVal]): Unit = {}

def nothing$ARRAY_91(x: Array[Nothing]): Unit = {}
def null$ARRAY_92(x: Array[Null]): Unit = {}
def nothing$ARRAY_93(x: Array[_ <: Nothing]): Unit = {}
def null$ARRAY_94(x: Array[_ <: Null]): Unit = {}

}
8 changes: 6 additions & 2 deletions sbt-test/scala2-compat/erasure/dottyApp/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ object Main {
z.c_40(dummy)
z.c_41(dummy)
z.c_42(dummy)
z.b_43(dummy)
//z.b_43(dummy)
z.c_44(dummy)
z.c_45(dummy)
z.b_46(dummy)
//z.b_46(dummy)
z.c_47(dummy)
// z.a_48(dummy)
// z.c_49(dummy)
Expand Down Expand Up @@ -101,6 +101,10 @@ object Main {
z.objectARRAY_88(dummy)
z.objectARRAY_89(dummy)
z.objectARRAY_90(dummy)
z.objectARRAY_91(dummy)
z.objectARRAY_92(dummy)
z.objectARRAY_93(dummy)
z.objectARRAY_94(dummy)

val methods = classOf[scala2Lib.Z].getDeclaredMethods.toList ++ classOf[dottyApp.Z].getDeclaredMethods.toList
methods.foreach { m =>
Expand Down
6 changes: 6 additions & 0 deletions sbt-test/scala2-compat/erasure/scala2Lib/Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,10 @@ class Z {
def objectARRAY_88(x: Array[Any]): Unit = {}
def objectARRAY_89(x: Array[AnyRef]): Unit = {}
def objectARRAY_90(x: Array[AnyVal]): Unit = {}

def objectARRAY_91(x: Array[Nothing]): Unit = {}
def objectARRAY_92(x: Array[Null]): Unit = {}
def objectARRAY_93(x: Array[_ <: Nothing]): Unit = {}
def objectARRAY_94(x: Array[_ <: Null]): Unit = {}

}

0 comments on commit 0ea05aa

Please sign in to comment.