Skip to content

Improve error messages for leaking of this as constructor arguments #15363

Closed
@liufengyun

Description

@liufengyun

Minimized example

Given the following program

class A:
  // should report one error here
  val b = new B(this) // error
  val m = 10
  val n = 20

class B(a: A):
  val x = a.m
  val y = a.n

Output

Compile with -Ysafe-init, the compiler generates the following warnings:

-- Warning: tests/init/neg/leak-constr.scala:8:12 ------------------------------
8 |  val x = a.m
  |          ^^^
  |Access field on a value with an unknown initialization status. Calling trace:
  |-> class A:	[ leak-constr.scala:1 ]
  |   ^
  |-> val b = new B(this) // error	[ leak-constr.scala:3 ]
  |           ^^^^^^^^^^^
  |-> class B(a: A):	[ leak-constr.scala:7 ]
  |   ^
  |-> val x = a.m	[ leak-constr.scala:8 ]
  |           ^^^
-- Warning: tests/init/neg/leak-constr.scala:9:12 ------------------------------
9 |  val y = a.n
  |          ^^^
  |Access field on a value with an unknown initialization status. Calling trace:
  |-> class A:	[ leak-constr.scala:1 ]
  |   ^
  |-> val b = new B(this) // error	[ leak-constr.scala:3 ]
  |           ^^^^^^^^^^^
  |-> class B(a: A):	[ leak-constr.scala:7 ]
  |   ^
  |-> val y = a.n	[ leak-constr.scala:9 ]
  |           ^^^
2 warnings found

Expectation

The warnings are legit, however, there are two problems:

  • The leaking cause too many errors to be useful
  • The error does not point to the leaking site and is a little difficult to understand

Ideally, we should only report one error at the leaking site if the leaking is unsafe.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions