Dotty: -Ycheck-init warning with Some(this)

Created on 15 Sep 2020  路  4Comments  路  Source: lampepfl/dotty

Minimized code

Dotty ver: 0.27.0-RC1

// compile with -source 3.1 -Ycheck-init
class X:
  val some = Some(this)

Output

[warn] -- Warning:
[warn] 4 |  val some = Some(this)
[warn]   |                  ^^^^
[warn]   |Promote the value under initialization to fully-initialized. Calling trace:
[warn]   | -> val some = Some(this)

Expectation

No warning

initialization bug

Most helpful comment

It's a micro-optimisation. Consider this example:

final case class Id(value: Long) {
  val some: Some[this.type] =
    Some(this)
}

It might look odd but sometimes I do this for real performance benefits when there's a very-hot loop (eg. graph traversal / calculation) and your application's logic is heavily affected by the presence or lack of a related node's ID. By storing Some(this) on all instances you can avoid allocations during that hot-spot logic. You might find yourself needing an average of, say, 10 instances of Option[Id] per node so avoiding those allocations adds up.

All 4 comments

Thanks for the report @japgolly .

Escape of this in the constructor (in this case Some.apply) is rare in practice. I am curious about the actual use case. Could you please elaborate? Thanks.

It's a micro-optimisation. Consider this example:

final case class Id(value: Long) {
  val some: Some[this.type] =
    Some(this)
}

It might look odd but sometimes I do this for real performance benefits when there's a very-hot loop (eg. graph traversal / calculation) and your application's logic is heavily affected by the presence or lack of a related node's ID. By storing Some(this) on all instances you can avoid allocations during that hot-spot logic. You might find yourself needing an average of, say, 10 instances of Option[Id] per node so avoiding those allocations adds up.

Oh and btw, if it makes a difference, the reason I used this.type instead of just Id is just habit in this case, but very important when there are existential types involved, and/or you're building up value-level proofs.

@japgolly Thanks for the detailed explanation. For now, you can use Some(this: @unchecked) to suppress the warning. In the future, we might enhance the checker with type checking to avoid the usage of @unchecked in such cases.

Was this page helpful?
0 / 5 - 0 ratings