Skip to content
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

Initialization order - calling apply method from val in case class companion object #9971

Closed
scabug opened this issue Oct 19, 2016 · 6 comments · Fixed by scala/scala#10560
Closed

Comments

@scabug
Copy link

scabug commented Oct 19, 2016

The following produces a stack-overflow:

object InitBug {
  def main(args: Array[String]): Unit = {
    object Foo {
      val bar = Foo()
    }
    case class Foo()
    
    Foo.bar
  }
}
@scabug
Copy link
Author

scabug commented Oct 19, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9971?orig=1
Reporter: @Sciss
Affected Versions: 2.11.8, 2.12.0-RC2
See #3772

@scabug
Copy link
Author

scabug commented Oct 19, 2016

@SethTisue said:
dotty gives

java.lang.NullPointerException
	at InitBug$Foo$2$.<init>(<console>:7)
	at InitBug$.Foo$lzyINIT1$1(<console>:8)
	at InitBug$.InitBug$main$$Foo$3(<console>:8)
	at InitBug$.main(<console>:11)
	at .<init>(<console>:6)
	at .<clinit>(<console>)
	at RequestResult$.<init>(<console>:3)
	at RequestResult$.<clinit>(<console>)
	at RequestResult$result(<console>)
	at sun.reflect.NativeMethodAccess...

@scabug
Copy link
Author

scabug commented Nov 12, 2016

@som-snytt said (edited on Nov 12, 2016 11:51:19 PM UTC):
The local object has lazy val semantics, so the example is the same as:

class C { def c: C = ??? }
lazy val c: C = c.c             // doesn't warn

but the bug is that Foo() is not rewritten to new Foo(). That optimization side-steps the issue.

I also missed the part where order of local companions matters. The "existing object" must come first textually. The spec says "if a companion object exists already," but it's not obvious to me if that phrase means, "before a companion was synthesized" or "textually before this case class definition was processed by the compiler." I think the former is surely preferable but the latter got voted into office.

@scabug scabug added this to the Backlog milestone Apr 7, 2017
@SethTisue
Copy link
Member

these days Dotty gives StackOverflowError

@SethTisue
Copy link
Member

SethTisue commented Jul 27, 2021

Scala 3 ticket is scala/scala3#13162. (And also, re-discussed recently on #12435, now closed as duplicate.)

@som-snytt
Copy link

There are suggestions on both scala and dotty tickets that the behavior is an implementation detail, but it is specified quite narrowly.

https://scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#object-definitions

Note that the "lazy val" paradigm is paradigmatic, and top-level objects are the deviation.

This commit only fixes the bug mentioned above and elsewhere. I was mistaken that order of the companions makes a difference, or that behavior has improved, or maybe I was commenting only on the specification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants