Skip to content

Commit 007eb46

Browse files
committed
Merge pull request scala-js#2150 from sjrd/reftype-not-subtype-of-type
Do not make ReferenceType extend Type anymore.
2 parents 9ec8245 + b2cbb09 commit 007eb46

File tree

7 files changed

+51
-16
lines changed

7 files changed

+51
-16
lines changed

ir/src/main/scala/org/scalajs/core/ir/Hashers.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,12 @@ object Hashers {
265265
case IsInstanceOf(expr, cls) =>
266266
mixTag(TagIsInstanceOf)
267267
mixTree(expr)
268-
mixType(cls)
268+
mixRefType(cls)
269269

270270
case AsInstanceOf(expr, cls) =>
271271
mixTag(TagAsInstanceOf)
272272
mixTree(expr)
273-
mixType(cls)
273+
mixRefType(cls)
274274

275275
case Unbox(expr, charCode) =>
276276
mixTag(TagUnbox)
@@ -416,7 +416,7 @@ object Hashers {
416416

417417
case ClassOf(cls) =>
418418
mixTag(TagClassOf)
419-
mixType(cls)
419+
mixRefType(cls)
420420

421421
case VarRef(ident) =>
422422
mixTag(TagVarRef)
@@ -443,6 +443,9 @@ object Hashers {
443443
def mixTrees(trees: List[Tree]): Unit =
444444
trees.foreach(mixTree)
445445

446+
def mixRefType(tpe: ReferenceType): Unit =
447+
mixType(tpe.asInstanceOf[Type])
448+
446449
def mixType(tpe: Type): Unit = tpe match {
447450
case AnyType => mixTag(TagAnyType)
448451
case NothingType => mixTag(TagNothingType)

ir/src/main/scala/org/scalajs/core/ir/Printers.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,13 +473,13 @@ object Printers {
473473
case IsInstanceOf(expr, cls) =>
474474
print(expr)
475475
print(".isInstanceOf[")
476-
print(cls)
476+
printRefType(cls)
477477
print(']')
478478

479479
case AsInstanceOf(expr, cls) =>
480480
print(expr)
481481
print(".asInstanceOf[")
482-
print(cls)
482+
printRefType(cls)
483483
print(']')
484484

485485
case Unbox(expr, charCode) =>
@@ -727,7 +727,7 @@ object Printers {
727727

728728
case ClassOf(cls) =>
729729
print("classOf[")
730-
print(cls)
730+
printRefType(cls)
731731
print(']')
732732

733733
// Specials
@@ -844,6 +844,9 @@ object Printers {
844844
}
845845
}
846846

847+
def printRefType(tpe: ReferenceType): Unit =
848+
print(tpe.asInstanceOf[Type])
849+
847850
def print(tpe: Type): Unit = tpe match {
848851
case AnyType => print("any")
849852
case NothingType => print("nothing")

ir/src/main/scala/org/scalajs/core/ir/Serializers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ object Serializers {
521521
}
522522

523523
def writeReferenceType(tpe: ReferenceType): Unit =
524-
writeType(tpe)
524+
writeType(tpe.asInstanceOf[Type])
525525

526526
def writePropertyName(name: PropertyName): Unit = {
527527
name match {

ir/src/main/scala/org/scalajs/core/ir/Trees.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ object Trees {
375375
val tpe = cls match {
376376
case ClassType(Definitions.RuntimeNullClass) => NullType
377377
case ClassType(Definitions.RuntimeNothingClass) => NothingType
378-
case _ => cls
378+
case _ => cls.asInstanceOf[Type]
379379
}
380380
}
381381

ir/src/main/scala/org/scalajs/core/ir/Types.scala

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,19 @@ import Trees._
1515

1616
object Types {
1717

18-
/** Type of an expression in the IR. */
18+
/** Type of an term (expression or statement) in the IR.
19+
*
20+
* There is a many-to-one relationship from [[ReferenceType]]s to types,
21+
* because:
22+
*
23+
* - `scala.Byte`, `scala.Short` and `scala.Int` collapse to [[IntType]]
24+
* - `java.lang.Object` and raw JS types all collapse to [[AnyType]]
25+
*
26+
* In fact, there are two `Type`s that do not have any real equivalent in
27+
* reference types: [[StringType]] and [[UndefType]], as they refer to the
28+
* non-null variants of `java.lang.String` and `scala.runtime.BoxedUnit`,
29+
* respectively.
30+
*/
1931
abstract sealed class Type {
2032
def show(): String = {
2133
val writer = new java.io.StringWriter
@@ -83,14 +95,29 @@ object Types {
8395
*/
8496
case object NullType extends Type
8597

86-
/** Reference types (allowed for classOf[], is/asInstanceOf[]). */
87-
sealed abstract class ReferenceType extends Type
98+
/** Reference types (allowed for classOf[], is/asInstanceOf[]).
99+
*
100+
* A `ReferenceType` has exactly the same level of precision as a JVM type.
101+
* There is a one-to-one relationship between a `ReferenceType` and an
102+
* instance of `java.lang.Class` at run-time. This means that:
103+
*
104+
* - All primitive types have their reference type (including `scala.Byte`
105+
* and `scala.Short`), and they are different from their boxed versions.
106+
* - Raw JS types are not erased to `any`
107+
* - Array types are like on the JVM
108+
*
109+
* A `ReferenceType` therefore uniquely identifies a `classOf[T]`. It is
110+
* also the reference types that are used in method signatures, and which
111+
* therefore dictate JVM/IR overloading.
112+
*/
113+
sealed trait ReferenceType
88114

89115
/** Class (or interface) type. */
90-
final case class ClassType(className: String) extends ReferenceType
116+
final case class ClassType(className: String) extends Type with ReferenceType
91117

92118
/** Array type. */
93-
final case class ArrayType(baseClassName: String, dimensions: Int) extends ReferenceType
119+
final case class ArrayType(baseClassName: String, dimensions: Int)
120+
extends Type with ReferenceType
94121

95122
object ArrayType {
96123
def apply(innerType: ReferenceType): ArrayType = innerType match {

tools/shared/src/main/scala/org/scalajs/core/tools/optimizer/IRChecker.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ class IRChecker(unit: LinkingUnit, logger: Logger) {
881881

882882
def refTypeToType(refType: ReferenceType)(implicit ctx: ErrorContext): Type = {
883883
refType match {
884-
case _: ArrayType => refType
884+
case arrayType: ArrayType => arrayType
885885
case ClassType(encodedName) => classNameToType(encodedName)
886886
}
887887
}

tools/shared/src/main/scala/org/scalajs/core/tools/optimizer/OptimizerCore.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ private[optimizer] abstract class OptimizerCore(
482482
trampoline {
483483
pretransformExpr(expr) { texpr =>
484484
val result = {
485-
if (isSubtype(texpr.tpe.base, tpe)) {
485+
// TODO This cast is suspicious
486+
if (isSubtype(texpr.tpe.base, tpe.asInstanceOf[Type])) {
486487
if (texpr.tpe.isNullable)
487488
BinaryOp(BinaryOp.!==, finishTransformExpr(texpr), Null())
488489
else
@@ -824,7 +825,8 @@ private[optimizer] abstract class OptimizerCore(
824825
case ClassType(ObjectClass) =>
825826
cont(texpr)
826827
case _ =>
827-
if (isSubtype(texpr.tpe.base, tpe)) {
828+
// TODO This cast is suspicious
829+
if (isSubtype(texpr.tpe.base, tpe.asInstanceOf[Type])) {
828830
cont(texpr)
829831
} else {
830832
cont(PreTransTree(

0 commit comments

Comments
 (0)