<div dir="ltr">Thanks for the analysis, Alex, and for filing the bug, Angelos!<div><br></div><div>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.</div><div>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?</div><div><br></div><div>I do hope we can get the annotated type mirror from InstanceOfTree#getType(), even if the pattern variable has no live range.</div><div><br></div><div>Best,</div><div>cu, WMD.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Nov 27, 2023 at 11:53 AM Liam Miller-Cushon <<a href="mailto:cushon@google.com">cushon@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>I think the issue is that t<span style="color:rgb(0,0,0)">he 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.</span></div><div><div style="color:rgb(0,0,0)"><br></div><div style="color:rgb(0,0,0)">[1] <a href="https://github.com/openjdk/jdk/blob/6aa197667ad05bd93adf3afc7b06adbfb2b18a22/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java#L2115-L2125" target="_blank">https://github.com/openjdk/jdk/blob/6aa197667ad05bd93adf3afc7b06adbfb2b18a22/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java#L2115-L2125</a></div><div style="color:rgb(0,0,0)"><br></div><div><div style="color:rgb(0,0,0)">Consider this example, where type annotations are emitted for type patterns and locals, but not if they are unused:</div><div style="color:rgb(0,0,0)"><br></div>import java.lang.annotation.ElementType;<br>import java.lang.annotation.Retention;<br>import java.lang.annotation.RetentionPolicy;<br>import java.lang.annotation.Target;<br><br>public class InstanceOfPatternVariable {<br><br> public void doSomething(final Object x) {<br> if (x instanceof @TA(0) String z) {}<br> @TA(1)<br> String b;<br> if (x instanceof @TA(2) String c) {<br> System.err.println(c);<br> }<br> @TA(3)<br> String d = null;<br> System.err.println(d);<br> }<br><br> @Target(ElementType.TYPE_USE)<br> @Retention(RetentionPolicy.RUNTIME)<br> @interface TA {<br> int value();<br> }<br>}<br><br>Which results in:<br><br> RuntimeVisibleTypeAnnotations:<br> 0: #37(#38=I#39): LOCAL_VARIABLE, {start_pc=24, length=7, index=3}<br> InstanceOfPatternVariable$TA(<br> value=2<br> )<br> 1: #37(#38=I#40): LOCAL_VARIABLE, {start_pc=33, length=8, index=3}<br> InstanceOfPatternVariable$TA(<br> value=3<br> )</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Nov 22, 2023 at 12:49 PM Alex Buckley <<a href="mailto:alex.buckley@oracle.com" target="_blank">alex.buckley@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 11/22/2023 9:55 AM, Werner Dietl wrote:<br>
> if (x instanceof @TA Float) {<br>
> if (x instanceof @TA Boolean b) {<br>
> <br>
> @Target(ElementType.TYPE_USE)<br>
> @Retention(RetentionPolicy.RUNTIME)<br>
> @interface TA {}<br>
> <br>
> 1) When looking at the bytecode with `javap -v <br>
> InstanceOfPatternVariable.class` I only see one use of @TA:<br>
> <br>
> RuntimeVisibleTypeAnnotations:<br>
> 0: #19(): INSTANCEOF, offset=1<br>
> InstanceOfPatternVariable$TA<br>
> <br>
> The JSL 15.20.2 [1] says "An instanceof expression may perform either <br>
> type comparison or pattern matching."<br>
> The JVMS 4.7.20-B [2] talks about how type annotations on "instanceof <br>
> expressions" are stored.<br>
> It would therefore seem to me that both occurrences of TA should be <br>
> stored in the class file.<br>
<br>
(You mean both occurrences of the annotation `@TA`. The annotation <br>
interface `TA` is a distinct thing.)<br>
<br>
Yes, both occurrences of `@TA` should be stored. Let's "prove it" for <br>
the second occurrence.<br>
<br>
The type pattern `Boolean b` is defined (per 14.30.1) as a local <br>
variable declaration. The annotation `@TA` which syntactically appears <br>
as a modifier on that declaration is interpreted according to 9.7.4. How?<br>
<br>
The annotation interface `TA` is defined with TYPE_USE, which means (per <br>
9.6.4.1) that `TA` is applicable in type contexts. One of the type <br>
contexts (per 4.11) is: "The type in a local variable declaration in <br>
either a statement ... or a pattern". So, the following rule in 9.7.4 <br>
applies:<br>
<br>
```<br>
- If the annotation's interface is applicable in type contexts, and not <br>
in the declaration context corresponding to the declaration, then the <br>
annotation is deemed to apply only to the type which is closest to the <br>
annotation.<br>
```<br>
<br>
This means that the annotation `@TA` is a type annotation (applying to <br>
the use of the `Boolean` type within a local variable declaration) and <br>
not a declaration annotation on the overall local variable declaration <br>
`Boolean b`.<br>
<br>
Great -- type annotations integrate with type patterns in the JLS as you <br>
would expect. Consequently, `@TA` should appear in the RVTA attribute <br>
via a localvar_target item. Perhaps javac is emitting the item but javap <br>
is unable to render it.<br>
<br>
Alex<br>
</blockquote></div></div>
</blockquote></div><br clear="all"><div><br></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><a href="https://ece.uwaterloo.ca/~wdietl/" target="_blank">https://ece.uwaterloo.ca/~wdietl/</a></div>