RFR: 8371683: TYPE_USE annotation on var lambda parameter should be rejected
Vicente Romero
vromero at openjdk.org
Thu Feb 19 19:08:45 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...
src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java line 5445:
> 5443:
> 5444: protected JCVariableDecl implicitParameter() {
> 5445: JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER | Flags.LAMBDA_PARAMETER);
question shouldn't the new LAMBDA_PARAMETER flag be enough? as it seems to be more specific?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/29687#discussion_r2829659063
More information about the compiler-dev
mailing list