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

Jan Lahoda jlahoda at openjdk.org
Thu Feb 12 08:50:23 UTC 2026


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 since JDK 20
                              ^
/tmp/JDK-8371683/TA.java:13: error: annotation interface not applicable to this kind of declaration
        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
                                     ^
/tmp/JDK-8371683/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)
4 errors


The last error is still the original one, it is not easy to get rid of it in the current way of handling `var`s, but should go away if we can improve `var` handling (https://bugs.openjdk.org/browse/JDK-8268850).

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

Commit messages:
 - Updating header years.
 - Fixing parsing with flags.
 - Cleanup.
 - Fixing parsing.
 - Adding source-level restriction.
 - 8371683: TYPE_USE annotation on var lambda parameter should be rejected

Changes: https://git.openjdk.org/jdk/pull/29687/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=29687&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8371683
  Stats: 115 lines in 10 files changed: 98 ins; 0 del; 17 mod
  Patch: https://git.openjdk.org/jdk/pull/29687.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/29687/head:pull/29687

PR: https://git.openjdk.org/jdk/pull/29687


More information about the compiler-dev mailing list