object Test {
def main(args: Array[String]): Unit = {
val f = new Foo
println(1)
println(f.foo)
println(2)
println(f.foo)
// TODO: Erase
// Currently not erasing fields for lazy vals
assert(f.getClass.getDeclaredFields.exists(_.getName.startsWith("foo")), "Field foo erased. Optimized accidentally?")
}
}
class Foo {
lazy val foo: Null = {
println("foo")
null
}
}
because
-- [E008] Member Not Found Error: tests/run/null-lazy-val.scala:13:49 ----------
13 | assert(f.getClass.getDeclaredFields.exists(_.getName.startsWith("foo")), "Field foo erased. Optimized accidentally?")
| ^^^^^^^^^
| value `getName` is not a member of java.lang.reflect.Field | Null
The argument type for the lambda is inferred to be Field|Null, when it should be Field|JavaNull.
So the implicit conversion is applied, but the argument type is incorrectly inferred. This is because annotations are dropped when subtyping constraints are added to the set of current constraints.
The current workaround is to say .nn.getName.startsWith. I discussed this with Ondrej and we're gonna let it be for now.
In particular, lots of tests need this to do e.g. getClass.getMethods.find.
So this could be alleviated by having more precise Java null conversion for methods in the Class class.
This doesn't typecheck
because
The argument type for the lambda is inferred to be Field|Null, when it should be Field|JavaNull.
After frontend
So the implicit conversion is applied, but the argument type is incorrectly inferred. This is because annotations are dropped when subtyping constraints are added to the set of current constraints.
The current workaround is to say
.nn.getName.startsWith
. I discussed this with Ondrej and we're gonna let it be for now.Opening this to track the status.