Skip to content

Commit 82752b7

Browse files
committed
Keep classOf[Prim] as Constant until the back-end.
The translation of `classOf[Prim]` (e.g., `classOf[Int]`) to `BoxedPrimClass.TYPE` (e.g., `j.l.Integer.TYPE`) is specific to the JVM back-end, because the JVM bytecode does not have any instruction to load them. Other back-ends have appropriate opcodes and prefer to receive them as `Constant(Literal(primType))`, so that they don't have to reverse-engineer the `Select`s. Since that transformation is not harder to do in the back-end, we move it directly to the JVM codegen. The code is actually shorter there. This also helps to keep the trees a bit smaller across the phases after erasure.
1 parent 44f13ef commit 82752b7

File tree

3 files changed

+14
-17
lines changed

3 files changed

+14
-17
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,16 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
512512

513513
case ClazzTag =>
514514
val tp = toTypeKind(const.typeValue)
515-
// classOf[Int] is transformed to Integer.TYPE by ClassOf
516-
assert(!tp.isPrimitive, s"expected class type in classOf[T], found primitive type $tp")
517-
mnode.visitLdcInsn(tp.toASMType)
515+
if tp.isPrimitive then
516+
val boxedClass = boxedClassOfPrimitive(tp.asPrimitiveBType)
517+
mnode.visitFieldInsn(
518+
asm.Opcodes.GETSTATIC,
519+
boxedClass.internalName,
520+
"TYPE", // field name
521+
jlClassRef.descriptor
522+
)
523+
else
524+
mnode.visitLdcInsn(tp.toASMType)
518525

519526
case EnumTag =>
520527
val sym = const.symbolValue

compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface]](val bTyp
124124
lazy val jlStringBuilderRef : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.StringBuilder])
125125
lazy val jlStringBufferRef : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.StringBuffer])
126126
lazy val jlCharSequenceRef : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.CharSequence])
127+
lazy val jlClassRef : ClassBType = classBTypeFromSymbol(requiredClass[java.lang.Class[_]])
127128
lazy val ThrowableReference : ClassBType = classBTypeFromSymbol(defn.ThrowableClass)
128129
lazy val jlCloneableReference : ClassBType = classBTypeFromSymbol(defn.JavaCloneableClass) // java/lang/Cloneable
129130
lazy val jlNPEReference : ClassBType = classBTypeFromSymbol(defn.NullPointerExceptionClass) // java/lang/NullPointerException
@@ -248,6 +249,7 @@ final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: DottyBackendInterface
248249
def jlStringBuilderRef : ClassBType = _coreBTypes.jlStringBuilderRef
249250
def jlStringBufferRef : ClassBType = _coreBTypes.jlStringBufferRef
250251
def jlCharSequenceRef : ClassBType = _coreBTypes.jlCharSequenceRef
252+
def jlClassRef : ClassBType = _coreBTypes.jlClassRef
251253
def ThrowableReference : ClassBType = _coreBTypes.ThrowableReference
252254
def jlCloneableReference : ClassBType = _coreBTypes.jlCloneableReference
253255
def jlNPEReference : ClassBType = _coreBTypes.jlNPEReference

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,20 +1155,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11551155

11561156
/** A tree that corresponds to `Predef.classOf[$tp]` in source */
11571157
def clsOf(tp: Type)(using Context): Tree =
1158-
if ctx.erasedTypes then
1159-
def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_)
1160-
defn.scalaClassName(tp) match
1161-
case tpnme.Boolean => TYPE(defn.BoxedBooleanModule)
1162-
case tpnme.Byte => TYPE(defn.BoxedByteModule)
1163-
case tpnme.Short => TYPE(defn.BoxedShortModule)
1164-
case tpnme.Char => TYPE(defn.BoxedCharModule)
1165-
case tpnme.Int => TYPE(defn.BoxedIntModule)
1166-
case tpnme.Long => TYPE(defn.BoxedLongModule)
1167-
case tpnme.Float => TYPE(defn.BoxedFloatModule)
1168-
case tpnme.Double => TYPE(defn.BoxedDoubleModule)
1169-
case tpnme.Unit => TYPE(defn.BoxedUnitModule)
1170-
case _ =>
1171-
Literal(Constant(TypeErasure.erasure(tp)))
1158+
if ctx.erasedTypes && !tp.isRef(defn.UnitClass) then
1159+
Literal(Constant(TypeErasure.erasure(tp)))
11721160
else
11731161
Literal(Constant(tp))
11741162

0 commit comments

Comments
 (0)