RFR: 8332463: Byte conditional pattern case element dominates short constant case element
Aggelos Biboudis
abimpoudis at openjdk.org
Wed May 22 09:41:02 UTC 2024
On Mon, 20 May 2024 08:26:43 GMT, Aggelos Biboudis <abimpoudis at openjdk.org> wrote:
> It seems that the compiler introduced a rule that does not exist in the spec. The fix is simple, and it will fix the behaviour of JDK 23 according to the spec. For example the following is accepted by JDK 22 and needs to continue to be accepted by JDK 23:
>
>
> public static int test() {
> Byte i = (byte) 42;
> return switch (i) {
> case Byte ib -> 1;
> case (short) 0 -> 2; // OK - not dominated
> };
> }
>
>
> Similarly for primitive type patterns:
>
>
> public static int test() {
> Byte i = (byte) 42;
> return switch (i) {
> case Byte ib -> 1;
> case short s -> 2; // Also not dominated since there is no unconditionally exact conversion from short to Byte
> };
> }
>
> public static int test() {
> int i = 42;
> return switch (i) {
> case Integer ib -> 1;
> case byte ip -> 2; // Also not dominated since there is no unconditionally exact conversion from byte to Integer
> };
> }
While `byte` --> `Byte` is boxing indeed, `Byte` --> `Integer` is not a widening reference conversion. From the spec:
> A widening reference conversion exists from any reference type S to any reference type T, provided S is a subtype of T (§4.10).
and
> A class or interface is disjoint from another class or interface if it can be determined statically that they have no instances in common (other than the null value)
The two reference types in the second conversion are disjoint. Evident that you cannot even ask if a Byte is instanceof Integer.
jshell> Byte b = 42
b ==> 42
jshell> b instanceof Integer
| Error:
| incompatible types: java.lang.Byte cannot be converted to java.lang.Integer
| b instanceof Integer
| ^
What you are really asking is whether or not `Byte` can be converted to `Integer` since we know that both can be null and also all possible reference values of the first also belong to the domain of the second. So actually maybe null is the only problematic value (because it witnesses that both types are reference types)? Today we manage conversions by those tables in Chapter 5. With the arrival of valhalla we will need to think what place the conversion of Byte! to Integer! has. (a `Byte` will be a null-widened `Byte!`.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/19301#issuecomment-2124327985
More information about the compiler-dev
mailing list