Type use annotations on instanceof patterns
Werner Dietl
wdietl at gmail.com
Mon Nov 27 17:35:12 UTC 2023
Thanks for the analysis, Alex, and for filing the bug, Angelos!
Looking at Liam's additional example (thanks for looking into this!), it
now makes sense that the type annotations on the pattern variable did not
show up in my example.
It seems a bit surprising, given how the JVMS talks about all instanceof
expressions. Maybe there should be two entries, one for the instanceof
expression and one for the pattern variable?
I do hope we can get the annotated type mirror
from InstanceOfTree#getType(), even if the pattern variable has no live
range.
Best,
cu, WMD.
On Mon, Nov 27, 2023 at 11:53 AM Liam Miller-Cushon <cushon at google.com>
wrote:
> 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
>>
>
--
https://ece.uwaterloo.ca/~wdietl/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20231127/97472ca1/attachment-0001.htm>
More information about the compiler-dev
mailing list