Type use annotations on instanceof patterns
Liam Miller-Cushon
cushon at google.com
Mon Nov 27 15:43:07 UTC 2023
I think the issue is that the code to generate LOCAL_VARIABLE locations
here [1] only handles variables that have non-empty live ranges, so type
annotations on unused variables are never generated.
[1]
https://github.com/openjdk/jdk/blob/6aa197667ad05bd93adf3afc7b06adbfb2b18a22/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java#L2115-L2125
Consider this example, where type annotations are emitted for type patterns
and locals, but not if they are unused:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class InstanceOfPatternVariable {
public void doSomething(final Object x) {
if (x instanceof @TA(0) String z) {}
@TA(1)
String b;
if (x instanceof @TA(2) String c) {
System.err.println(c);
}
@TA(3)
String d = null;
System.err.println(d);
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TA {
int value();
}
}
Which results in:
RuntimeVisibleTypeAnnotations:
0: #37(#38=I#39): LOCAL_VARIABLE, {start_pc=24, length=7, index=3}
InstanceOfPatternVariable$TA(
value=2
)
1: #37(#38=I#40): LOCAL_VARIABLE, {start_pc=33, length=8, index=3}
InstanceOfPatternVariable$TA(
value=3
)
On Wed, Nov 22, 2023 at 12:49 PM Alex Buckley <alex.buckley at oracle.com>
wrote:
> On 11/22/2023 9:55 AM, Werner Dietl wrote:
> > if (x instanceof @TA Float) {
> > if (x instanceof @TA Boolean b) {
> >
> > @Target(ElementType.TYPE_USE)
> > @Retention(RetentionPolicy.RUNTIME)
> > @interface TA {}
> >
> > 1) When looking at the bytecode with `javap -v
> > InstanceOfPatternVariable.class` I only see one use of @TA:
> >
> > RuntimeVisibleTypeAnnotations:
> > 0: #19(): INSTANCEOF, offset=1
> > InstanceOfPatternVariable$TA
> >
> > The JSL 15.20.2 [1] says "An instanceof expression may perform either
> > type comparison or pattern matching."
> > The JVMS 4.7.20-B [2] talks about how type annotations on "instanceof
> > expressions" are stored.
> > It would therefore seem to me that both occurrences of TA should be
> > stored in the class file.
>
> (You mean both occurrences of the annotation `@TA`. The annotation
> interface `TA` is a distinct thing.)
>
> Yes, both occurrences of `@TA` should be stored. Let's "prove it" for
> the second occurrence.
>
> The type pattern `Boolean b` is defined (per 14.30.1) as a local
> variable declaration. The annotation `@TA` which syntactically appears
> as a modifier on that declaration is interpreted according to 9.7.4. How?
>
> The annotation interface `TA` is defined with TYPE_USE, which means (per
> 9.6.4.1) that `TA` is applicable in type contexts. One of the type
> contexts (per 4.11) is: "The type in a local variable declaration in
> either a statement ... or a pattern". So, the following rule in 9.7.4
> applies:
>
> ```
> - If the annotation's interface is applicable in type contexts, and not
> in the declaration context corresponding to the declaration, then the
> annotation is deemed to apply only to the type which is closest to the
> annotation.
> ```
>
> This means that the annotation `@TA` is a type annotation (applying to
> the use of the `Boolean` type within a local variable declaration) and
> not a declaration annotation on the overall local variable declaration
> `Boolean b`.
>
> Great -- type annotations integrate with type patterns in the JLS as you
> would expect. Consequently, `@TA` should appear in the RVTA attribute
> via a localvar_target item. Perhaps javac is emitting the item but javap
> is unable to render it.
>
> Alex
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20231127/9b503bbb/attachment-0001.htm>
More information about the compiler-dev
mailing list