Skip to content

Extending specific kind of trait compiled by scala 3 leads to NoSuchMethodError #12184

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

Closed
bishabosha opened this issue Oct 8, 2020 · 6 comments

Comments

@bishabosha
Copy link
Member

bishabosha commented Oct 8, 2020

reproduction steps

using Dotty 0.27-0-RC1, compile

trait IOApp {
  val foo = 23
}
object IOApp {
  trait Simple extends IOApp
}

using Scala 2.13.4-bin-8891679, with IOApp on the class path, compile

object Foo extends IOApp.Simple {}

object Main extends App {
  println(Foo)
}

problem

when you run Main.main you get the runtime error:

(run-main-0) java.lang.NoSuchMethodError: example.IOApp$Simple.$init$(Lexample/IOApp$Simple;)V
java.lang.NoSuchMethodError: example.IOApp$Simple.$init$(Lexample/IOApp$Simple;)V
        at example.Foo$.<clinit>(Main.scala:3)
        at example.Main$.delayedEndpoint$example$Main$1(Main.scala:6)
        at example.Main$delayedInit$body.apply(Main.scala:5)
        at scala.Function0.apply$mcV$sp(Function0.scala:39)
        at scala.Function0.apply$mcV$sp$(Function0.scala:39)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
        at scala.App.$anonfun$main$1(App.scala:73)
        at scala.App.$anonfun$main$1$adapted(App.scala:73)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:553)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:551)
        at scala.collection.AbstractIterable.foreach(Iterable.scala:919)
        at scala.App.main(App.scala:73)
        at scala.App.main$(App.scala:71)
        at example.Main$.main(Main.scala:5)
        at example.Main.main(Main.scala)

this only happens if IOApp does something in its constructor.

When IOApp is instead compiled by Scala 2.13.3 there is no IOApp.Simple.$init$ method generated or called.

@bishabosha bishabosha changed the title Extending pure trait in side effecting trait compiled by scala 3 leads to NoSuchMethodError Extending specific kind of trait compiled by scala 3 leads to NoSuchMethodError Oct 8, 2020
@dwijnand
Copy link
Member

@bishabosha this isn't a blocker for 2.13.4, is it? (🤞)

@dwijnand dwijnand added this to the 2.13.4 milestone Oct 16, 2020
@bishabosha
Copy link
Member Author

bishabosha commented Oct 19, 2020

I'm not sure what the policy should be in this case. On the other hand, Dotty has its own issue where it does not generate the $init$ method that scala 2 emits so cats-effect scala 3 binary would be unusable -
scala/scala3#9970

essentially, this is showing that for the trait definition:

trait IOApp {
  protected val foo = 23

  def run(args: List[String]): Int

  final def main(args: Array[String]): Unit = {
    sys.exit(run(args.toList))
  }

}
object IOApp {
  trait Simple extends IOApp {
    def run: Unit

    final def run(args: List[String]): Int = {
      run
      0
    }
  }
}

on scala 2 both IOApp and IOApp.Simple generate trait initialiser methods, but on Scala 3 only IOApp generates one. Is this expected or a bug in scala 2?

@lrytz
Copy link
Member

lrytz commented Oct 19, 2020

If I remember correctly this is expected, with the goal to have more binary stability. But adding a field to a trait is not binary compatible anyway, so I'm not sure. Maybe @retronym remembers.

@dwijnand
Copy link
Member

dwijnand commented Oct 19, 2020

I see, thanks for the explanation, Jamie.

Whether it's a bug or not in Scala 2, we couldn't make scalac 2.13.4 suddenly stop emitting the trait initialiser method in IOApp.Simple as that would break that trait's downstream users. So in order for Scala 3 jars to be consumable Dotty needs to mirror Scala 2.13's choices. (edit: unless, of course, you can shim something at tasty reading time... but that would add complexity IMO)

So it's "notabug" IMO, but a Dotty issue.

@bishabosha
Copy link
Member Author

Yes I see now, this issue is nothing due to tasty reader, but dotty not matching the flags for Scala 2, - the IOApp.Simple should be a pure constructor in this case in tasty, but is not

@dwijnand
Copy link
Member

In addition (from @sjrd) Dotty needs to align for shared trait usage.

@dwijnand dwijnand removed this from the 2.13.4 milestone Oct 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants