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