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

-Wsafe-init doesn't detect initialization order problems #22152

Open
kubukoz opened this issue Dec 5, 2024 · 5 comments
Open

-Wsafe-init doesn't detect initialization order problems #22152

kubukoz opened this issue Dec 5, 2024 · 5 comments

Comments

@kubukoz
Copy link
Contributor

kubukoz commented Dec 5, 2024

Compiler version

3.6.1, 3.6.4-RC1-bin-20241204-a67dbb0-NIGHTLY

Minimized code

case class Record(region: String, env: String)

object foo {

  val record = Record(region, env)

  val region = "oops"
  val env = "hello"

}

object Demo extends App { println(foo.record) }

compiled with -Wsafe-init

Output

Record(null,null)

Expectation

something similar to 2.13's behavior under -Xcheckinit:

scala-cli run . --scala 2.13 -Xcheckinit                                                                                                                                                   
Compiling project (Scala 2.13.15, JVM (21))
[warn] ./demo.scala:5:23
[warn] Reference to uninitialized value region
[warn]   val record = Record(region, env)
[warn]                       ^^^^^^
[warn] ./demo.scala:5:31
[warn] Reference to uninitialized value env
[warn]   val record = Record(region, env)
[warn]                               ^^^
Compiled project (Scala 2.13.15, JVM (21))
Exception in thread "main" java.lang.ExceptionInInitializerError
        at Demo$.delayedEndpoint$Demo$1(demo.scala:12)
        at Demo$delayedInit$body.apply(demo.scala:12)
        at scala.Function0.apply$mcV$sp(Function0.scala:42)
        at scala.Function0.apply$mcV$sp$(Function0.scala:42)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
        at scala.App.$anonfun$main$1(App.scala:98)
        at scala.App.$anonfun$main$1$adapted(App.scala:98)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:619)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:617)
        at scala.collection.AbstractIterable.foreach(Iterable.scala:935)
        at scala.App.main(App.scala:98)
        at scala.App.main$(App.scala:96)
        at Demo$.main(demo.scala:12)
        at Demo.main(demo.scala)
Caused by: scala.UninitializedFieldError: Uninitialized field: demo.scala: 7
        at foo$.region(demo.scala:7)
        at foo$.<clinit>(demo.scala:5)
        ... 14 more
@kubukoz kubukoz added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 5, 2024
@kubukoz
Copy link
Contributor Author

kubukoz commented Dec 5, 2024

apparently, even without -Xcheckinit you get a warning during compilation - I suppose that's more in line with what -Wsafe-init should do

@som-snytt
Copy link
Contributor

They keep the good stuff in the back.

➜  snips scalac -d ~/sandbox -Ysafe-init-global init-order.scala
-- Warning: init-order.scala:6:22 ----------------------------------------------
6 |  val record = Record(region, env)
  |                      ^^^^^^
  |               Access uninitialized field value region. Calling trace:
  |               ├── object foo {      [ init-order.scala:4 ]
  |               │   ^
  |               └── val record = Record(region, env)  [ init-order.scala:6 ]
  |                                       ^^^^^^
-- Warning: init-order.scala:6:30 ----------------------------------------------
6 |  val record = Record(region, env)
  |                              ^^^
  |               Access uninitialized field value env. Calling trace:
  |               ├── object foo {      [ init-order.scala:4 ]
  |               │   ^
  |               └── val record = Record(region, env)  [ init-order.scala:6 ]
  |                                               ^^^
2 warnings found

I don't actually know what the difference is, or what difference is intended, although I tried to follow the threads.

@olhotak
Copy link
Contributor

olhotak commented Dec 5, 2024

-Wsafe-init works only for classes, not global objects.

-Ysafe-init-global is for global objects, but it is still experimental and under development.

@kubukoz
Copy link
Contributor Author

kubukoz commented Dec 5, 2024

Good to know! I like the rendering of the trace, very cool :)

Shall we keep this open or is there another ticket that covers -Ysafe-init-global?

@Gedochao Gedochao added area:initialization and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 6, 2024
@Gedochao
Copy link
Contributor

Gedochao commented Dec 6, 2024

Shall we keep this open or is there another ticket that covers -Ysafe-init-global?

@kubukoz let's keep it, I don't think we track this anywhere else at this point.
I guess it's more of a feature request than a bug per se, too.

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

No branches or pull requests

4 participants