<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Hello Stephan,</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Thank you for your feedback and investigation!</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Let me recap.</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Currently (and correctly) the following two examples work as expected.</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
```java</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Short s = 42;</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
s instanceof int</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
// true, because s has static type Short followed by unboxing followed by w.p.c.</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Object o = s;</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
o instanceof int</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
// false, because o has static type Object followed by narrowing r.c.</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
// (to Integer, thus false) followed by unboxing</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
```</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
However, we realized that javac accepts the following two with</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
different runtime behavior. In the first case javac loses the static type of</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
`ls.get(0)`. This has the effect to "guide" the conversion checking not from</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
`Short` to `int` as expected, but from `Object` to `int`. In the second case</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
javac inserts a sharp cast in the selector type `(Short) ls.get(0)`.</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
```java</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
List<Short> ls = List.of((short) 42);</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
ls.get(0) instanceof int</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
// false, since what is executed is ((Object) ls.get(0)) instanceof int</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
switch(ls.get(0)) {</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
case int _ -> true;</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
default -> false;</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
}</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
// true, since what is executed is ((Short) ls.get(0))</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
```</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
(of course, if we would have `List<?>` both return `false`, as expected)</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
There are two requirements here. `instanceof` is the precondition of safe</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
casting and safe casting is described in Section 5.5. The second is that</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
`switch` and `instanceof` should expose the same behaviour.</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
As your example clearly demonstrates, javac fails to respect this second</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
requirement. We will address that in javac and add any required JLS</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
clarification as part of JEP 455 (Preview 2).</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="line-height: 18px; white-space: pre; font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Many many thanks!</div>
<div class="elementToProof" style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Helvetica Neue", sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> compiler-dev <compiler-dev-retn@openjdk.org> on behalf of Stephan Herrmann <stephan.herrmann@berlin.de><br>
<b>Sent:</b> 10 September 2024 14:40<br>
<b>To:</b> compiler-dev@openjdk.org <compiler-dev@openjdk.org><br>
<b>Subject:</b> Re: widen-unbox-widen vs JEP 455</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Has anyone found the time to check which outcome is intended according to JEP 455?<br>
<br>
Do I understand correctly, that the pattern 'int i' should always match at <br>
runtime in all cases of the below code?<br>
<br>
Alternatively, should we propose to drop the rules for widen-then-unbox <br>
conversions, because any real benefit of such conversion would require that <br>
'final' is dropped from any of the boxing classes?<br>
<br>
thanks,<br>
Stephan<br>
<br>
Am 01.09.24 um 10:44 schrieb Stephan Herrmann:<br>
> I just learned that reference widening followed by unboxing (followed by <br>
> primitive widening) is deemed a relevant conversion [1]. So I made sure that ecj
<br>
> can handle this in various situation, only to find out that this will make ecj <br>
> produce code that is behaviorally different from what javac emits.<br>
> <br>
> Here's my test code challenging this aspect of JEP 455:<br>
> //<br>
> <T extends Short> void typeVariableSingle(T single) {<br>
> int i1 = single;<br>
> System.out.print(i1);<br>
> if (single instanceof int i)<br>
> System.out.print(i);<br>
> else<br>
> System.out.print('-');<br>
> switch (single) {<br>
> case int i -> System.out.print(i);<br>
> default -> System.out.print('-');<br>
> }<br>
> System.out.println();<br>
> }<br>
> <T extends Short> void typeVariableList(List<T> list) {<br>
> int i1 = list.get(0);<br>
> System.out.print(i1);<br>
> if (list.get(0) instanceof int i)<br>
> System.out.print(i);<br>
> else<br>
> System.out.print('-');<br>
> switch (list.get(0)) {<br>
> case int i -> System.out.print(i);<br>
> default -> System.out.print('-');<br>
> }<br>
> System.out.println();<br>
> }<br>
> void wildcard(List<? extends Short> list) {<br>
> int i1 = list.get(0);<br>
> System.out.print(i1);<br>
> if (list.get(0) instanceof int i)<br>
> System.out.print(i);<br>
> else<br>
> System.out.print('-');<br>
> switch (list.get(0)) {<br>
> case int i -> System.out.print(i);<br>
> default -> System.out.print('-');<br>
> }<br>
> System.out.println();<br>
> }<br>
> void main() {<br>
> Short s = 1;<br>
> typeVariableSingle(s);<br>
> typeVariableList(Collections.singletonList(s));<br>
> wildcard(Collections.singletonList(s));<br>
> }<br>
> //<br>
> <br>
> compiled with ecj this gives<br>
> 111<br>
> 111<br>
> 111<br>
> <br>
> compiled with javac the program prints<br>
> 111<br>
> 1-1<br>
> 1-1<br>
> <br>
> Is this a simple bug in javac, or is there more to it?<br>
> thanks<br>
> Stephan<br>
> <br>
> [1] see answers to <br>
> <a href="https://mail.openjdk.org/pipermail/amber-spec-experts/2024-August/004204.html">
https://mail.openjdk.org/pipermail/amber-spec-experts/2024-August/004204.html</a><br>
<br>
</div>
</span></font></div>
</body>
</html>