RFR: 8371683: TYPE_USE annotation on var lambda parameter should be rejected

Kevin Bourrillion duke at openjdk.org
Wed Feb 25 15:50:19 UTC 2026


On Thu, 12 Feb 2026 08:42:09 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:

> Consider this code:
> 
> $ cat TA.java
> import java.lang.annotation.ElementType;
> import java.lang.annotation.Target;
> import java.util.List;
> import java.util.function.Consumer;
> 
> @Target(ElementType.TYPE_USE)
> @interface TA {
> }
> class T {
>     public static void t(List<T> l, Object o) {
>         for (@TA var v : l) {}                   //JLS 9.7.4.: @TA var v should be a compile-time error
>         Consumer<String> c = (@TA var v) -> {};  //JLS 9.7.4.: @TA var v should be a compile-time error since JDK 20
>         boolean b = o instanceof Box(@TA var v); //JLS 9.7.4.: @TA var v should be a compile-time error; compile-time error reported, but a wrong/weird one
>     }
> }
> record Box(T v) {}
> $ javac TA.java 
> TA.java:13: error: type annotation @TA is not expected here
>         boolean b = o instanceof Box(@TA var v); //JLS 9.7.4.: @TA var v should be a compile-time error; compile-time error reported, but a wrong/weird one
>                                          ^
>   (to annotate a qualified type, write unnamed package. at TA T)
> 1 error
> 
> 
> JLS 9.7.4 ("Where Annotations May Appear ") disallows all the type-annotated `var`s:
> - `for (@TA var v : l) {}` - the type annotation was disallowed since introduction of `var` in JDK 10
> - `(@TA var v) -> {}` - the type annotation was expressly disallowed in JDK 20 via https://bugs.openjdk.org/browse/JDK-8295807
> - `Box(@TA var v)` - the type annotation was disallowed since introduction of type-test patterns; an error is produced, but it is a wrong type of error.
> 
> The reason is that currently, the applicability check is second-guessing whether or not a given variable symbol is for a `var` variable, but in some cases this guess fails.
> 
> This PR fixes the problem by having an explicit flag marking symbols as representing a `var` variable, so that the check can be made reliably. For lambda parameters, the new behavior only applies to source level >= 20, and that (I think) sadly requires one more flag to determine lambda parameters. Luckily, flags for variables are not too scarce.
> 
> With this patch, the output for the above example is:
> 
> /tmp/JDK-8371683/TA.java:11: error: annotation interface not applicable to this kind of declaration
>         for (@TA var v : l) {}                   //JLS 9.7.4.: @TA var v should be a compile-time error
>              ^
> /tmp/JDK-8371683/TA.java:12: error: annotation interface not applicable to this kind of declaration
>         Consumer<String> c = (@TA var v) -> {};  //JLS 9.7.4.: @TA var v should be a compile-time error s...

Just a short note of thanks for fixing this. In JSpecify we found ourselves debating what `@Nullable` would mean in this position and wishing it was just illegal. So yeah - thanks!

-------------

PR Comment: https://git.openjdk.org/jdk/pull/29687#issuecomment-3960220786


More information about the compiler-dev mailing list