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