Surprised that TYPE_USE annotations are accepted on `var` lambda parameters
Chris Povirk
cpovirk at google.com
Tue Oct 11 19:17:31 UTC 2022
Hi,
I was surprised to find that the following code is accepted by javac (as
recently as jdk-20-ea+16):
import static java.lang.annotation.ElementType.TYPE_USE;
import java.lang.annotation.Target;
class X {
C c = (@Anno var o) -> {};
interface C {
void c(Object o);
}
@Target(TYPE_USE)
@interface Anno {}
}
Since type-use annotations are rejected on var local variables, I would
have expected them to be rejected on var lambda parameters, too.
As further support, I found that https://openjdk.org/jeps/323 specifically
refers to the "uniformity" it produces between "local variables and lambda
formals." Yes, the JEP gives an example of using a @NonNull annotation on a
var lambda parameter. But the JEP also uses the annotation on a var local
variable, so I think we're meant to conclude that it's a declaration
annotation.
I didn't find a clear statement either way in my browsing of the JLS. On
the one hand, JLS 9.7.4 specifically forbids using type-use annotations
with var only for local variables:
"If the annotation appears before a void method declaration or a local
variable declaration that uses var (§14.4), then there is no closest type."
On the other hand, I don't think any of the JLS rules for finding the
"closest type" would apply in the case of a var lambda parameter.
For what it's worth, I haven't found any usages of type-use annotations on
var lambda parameters in Google's codebase, with one exception: I found a
javac test that uses a TYPE_USE+PARAMETER+LOCAL_VARIABLE annotation and
verifies that it doesn't appear as a type-use annotation in the output.
(Note that that's contrary to what happens with type-use annotations on
*non*-var lambda parameters, which are copied to the generated synthetic
method
<https://mail.openjdk.org/pipermail/compiler-dev/2015-December/009866.html>
.)
https://github.com/openjdk/jdk/blob/d362e16924913207b67b5650ad4cafb6ab019cb1/test/langtools/tools/javac/annotations/typeAnnotations/VariablesDeclaredWithVarTest.java#L76
Based on all that, my best guess is that type-use annotations probably
"shouldn't" be accepted on var lambda parameters. I think that would be
fine with us, too: The question came up as part of JSpecify nullness
discussions, and the main point of discussion has been my surprise that the
annotations are accepted today.
Thanks,
Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20221011/86e4ed8a/attachment.htm>
More information about the compiler-dev
mailing list