Thanks for raising the issue @cluelessjoe .
The short answer: we have an attack for exactly the problem you mentioned, and we are working on a compiler plugin implementation to make it available.
With our solution, the compiler will report an error when bar
is used:
object ForwardReferenceGotcha {
val foo = Foo(bar) // error
val bar = Bar()
case class Bar(i: Int = 0)
case class Foo(bar: Bar)
def main(args: Array[String]): Unit = {
println(foo)
}
}
It handles inheritance:
abstract class AbstractFile {
def name: String
val extension: String = Path.extension(name) // error
}
class RemoteFile(url: String) extends AbstractFile {
val localFile: String = url.hashCode + ".tmp"
def name: String = localFile
}
and linearization:
trait TA {
val x = "world"
}
trait TB {
def x: String
val m = "hello" + x
}
class Foo extends TA with TB // OK
class Bar extends TB with TA // error
and inner classes:
object Trees {
class ValDef { counter += 1 } // error
class EmptyValDef extends ValDef
val theEmptyValDef = new EmptyValDef // error
private var counter = 0
}
and functions:
abstract class Parent {
val f: () => String = () => this.message
def message: String
}
class Child extends Parent {
val a = f() // error
val b = "hello"
def message: String = b
}
class Foo {
val even: Int => Boolean = (n: Int) => n == 0 || odd(n - 1)
val flag1: Int = even(3) // error
val odd: Int => Boolean = (n: Int) => n == 1 || even(n - 1)
val flag2: Boolean = odd(6)
}
For all the features above, no annotation is required. However, to support leaking of this
, an annotation like @cold
is required:
class Parent { val child = new Child(this) }
class Child(parent: Parent @cold) {
println(parent.child) // error
}
The analysis will reject some anti-patterns of initializaiton, e.g., assigning this
to an already initialized object. However, it will only report warnings in such cases (it reports errors only if it’s certain that an uninitialized field is used), so we hope it will not create big usability or migration problems.
We are happy to hear more your thoughts on the problem.