Unexpected Instantiation in Scala 3 Bytecode for Inline Methods Handling ClassTag[E]

I’ve encountered a peculiar issue with Scala 3’s inline methods when dealing with ClassTag[E]. After compiling a Scala 3 program that involves inline methods, I noticed some unexpected instantiation in the decompiled bytecode that doesn’t seem to align with what I had written.

Here’s a simplified snippet of my Scala code using an inline method with ClassTag:

inline def defaultValue[E](implicit ct: ClassTag[E]): E = {
    inline ct match {
        case ct: ClassTag[Int] => 0
        case _ => null.asInstanceOf[E]
    }
}

@main
def main(): Unit = {
    val a: Int = defaultValue
    val b = a + 1
}

This is decompiled to Java Code below:

public void main() {
    ClassTag ct$proxy1 = .MODULE$.apply(Integer.TYPE);
    int a = 0;
    int b = a + 1;
}

After compiling the Scala code and decompiling the bytecode, I’ve found instances of instantiation that I didn’t anticipate. I’m trying to understand if this is a known issue with the Scala 3 compiler, or perhaps there is an aspect of the Scala 3 compiler’s behavior with inline methods and ClassTag that I’m not fully grasping.

Could this be a bug with the Scala 3 code generator, or is it a consequence of a feature that’s currently beyond my understanding? Any insights or explanations would be greatly appreciated.

You need to mark the classtag as inline too I think.

I think it’s normal the parameters to an inline method will instantiate in this case, cause not doing so would make parameter behavior much different from normal methods and that’s not the point of inline methods.
inline def defaultValue[E](using inline ct:ClassTag[E]): E =

By the way, you should erasedValue here instead of a classTag. You can use that to determine if E is an Int, and erasedValue is able to deal with more types than ClassTag.

1 Like

Thank you for pointing this out!