Skip to content

ClassCastException when omitting a by-name argument that has a default value in enum or superclass constructors #23213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
raquo opened this issue May 21, 2025 · 1 comment
Labels
area:enums itype:bug itype:soundness Soundness bug (it lets us compile code that crashes at runtime with a ClassCastException)

Comments

@raquo
Copy link
Contributor

raquo commented May 21, 2025

Compiler version

3.7.2-RC1-bin-20250519-d36e423-NIGHTLY, 3.7.0-RC1, 3.6.4, 3.3.5

Minimized code

  1. Enum variant:
enum Bar(
  first: => Int = 0,
  second: Option[String]
) {

  case B extends Bar(
    second = None
  )
}

Bar.B     // throws ClassCastException

Enum Scastie

  1. Super class variant:
class Bar(
  first: => Int = 0,
  second: Option[String]
)

object B extends Bar(
  second = None
)

B     // throws VerifyError or ClassCastException depending on environment

Class Scastie

Output

Runtime error when evaluating Bar.B:

Enum variant on scala-cli 3.7.2-...-NIGHTLY:

java.lang.ClassCastException: class java.lang.Integer cannot be cast to class scala.Function0 (java.lang.Integer is in module java.base of loader 'bootstrap'; scala.Function0 is in unnamed module of loader java.net.URLClassLoader @6ef81f31

Super class variant on scala**.js** 3.6.4:

Uncaught org.scalajs.linker.runtime.UndefinedBehaviorError: java.lang.ClassCastException: number(0) cannot be cast to scala.Function0
    at $throwClassCastException (internal-....js?t=1747788060853:51:9)
    at Module.$as_F0 (Function0.scala:38:7)
    at new $Example$B$ (Example.scala:...)

Super class variant on scala-cli 3.7.2-...-NIGHTLY and also on 3.6.4:

java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    rs$line$1$B$.<init>()V @10: invokespecial
  Reason:
    Type uninitializedThis (current frame, stack[3]) is not assignable to 'rs$line$1$B$'
  Current Frame:
    bci: @10
    flags: { flagThisUninit }
    locals: { uninitializedThis, 'scala/None$' }
    stack: { uninitializedThis, 'rs$line$1$', 'scala/None$', uninitializedThis }
  Bytecode:
    0000000: b200 164c 2ab2 001b 2b2a b700 1fb8 0025
    0000010: c000 27b6 002b 2bb7 002e b1

  ... 30 elided

Expectation

Should not throw, or at the very least, should not compile, if the code is illegal.

Details

  • For classes, bug seems to be specific to extends, e.g. val B = Bar(second = None) does not trigger the bug.
  • Requires by-name argument for the first argument (: =>). Making it by-value avoids the bug.
  • Requires a certain type for the second argument. Option, Either, and case classes trigger the bug. String, regular classes do not trigger the bug. Perhaps needs a Product to trigger the bug? Not sure.
@raquo raquo added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 21, 2025
@som-snytt
Copy link
Contributor

After erasure, the "superarg" function is confused about how to box the by-name int.

    {
      val second$1: None = None
      def first$1(): Int = Bar.$lessinit$greater$default$1()
      super(
        B.B$$superArg$1(second$1, Int.box(first$1()).asInstanceOf[Function0]),
        second$1)
    }
    private <static> def B$$superArg$1(second$1: None, first$1: Function0):
      Function0 = () => Int.unbox(first$1)

The finicky detail is because it must decide the default first is also a function of the second. It's like it consulted chatgpt.

@Gedochao Gedochao added itype:soundness Soundness bug (it lets us compile code that crashes at runtime with a ClassCastException) area:enums and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:enums itype:bug itype:soundness Soundness bug (it lets us compile code that crashes at runtime with a ClassCastException)
Projects
None yet
Development

No branches or pull requests

3 participants