ADDITIONAL SYSTEM INFORMATION :
macOS Monterey 12.6.4
A DESCRIPTION OF THE PROBLEM :
Unexpected problems when combining record patterns and switch resulting in a java.lang.VerifyError: Bad type on operand stack
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create record
jshell> record MyPair<T1, T2>(T1 first, T2 second) {
...> }
2. Create Method
jshell> static void recordInferenceJdk19(MyPair<String, Integer> pair) {
...> switch (pair) {
...> case MyPair<String, Integer>(var text, var count) when text.contains("Michael") ->
...> System.out.println(text + " is " + count + " years old");
...> case MyPair<String, Integer>(var text, var count) when count > 5 && count < 10 ->
...> System.out.println("repeated " + text.repeat(count));
...> case MyPair<String, Integer>(var text, var count) -> System.out.println(text + count);
...> default -> System.out.println("PENG");
...> }
...> }
3. Call Method
jshell> recordInferenceJdk19(new MyPair<>("Michael", 52))
| Ausnahme java.lang.VerifyError: Bad type on operand stack
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The suitable case should be selected. Like with instanceof
When calling the method
* recordInferenceJdk19(new MyPair<>("Michael", 52))
=> case 1 should match
=> "Michael is 52 years old"
* recordInferenceJdk19(new MyPair<>("Mike", 7))
=> case 2 should match
=> "repeated MikeMikeMikeMikeMikeMikeMike"
-------------------------
INSTANCEOF-Version works well
jshell> static void recordInferenceJdk19io(MyPair<String, Integer> pair) {
...> if (pair instanceof MyPair<String, Integer>(var text, var count) && text.contains("Michael"))
...> System.out.println(text + " is " + count + " years old");
...> else if (pair instanceof MyPair<String, Integer>(var text, var count) && count > 5 && count < 10)
...> System.out.println("repeated " + text.repeat(count));
...> else if (pair instanceof MyPair<String, Integer>(var text, var count))
...> System.out.println(text + count);
...> else
...> System.out.println("PENG");
...> }
| Erstellt Methode recordInferenceJdk19io(MyPair<String, Integer>)
jshell> recordInferenceJdk19io(new MyPair<>("Mike", 7))
repeated MikeMikeMikeMikeMikeMikeMike
jshell> recordInferenceJdk19io(new MyPair<>("Michael", 52))
Michael is 52 years old
ACTUAL -
jshell> recordInferenceJdk19(new MyPair<>("Michael", 52))
| Ausnahme java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
REPL/$JShell$17B.recordInferenceJdk19(LREPL/$JShell$16$MyPair;)V @181: invokevirtual
Reason:
Type 'java/lang/String' (current frame, stack[2]) is not assignable to 'java/lang/Integer'
Current Frame:
bci: @181
flags: { }
locals: { 'REPL/$JShell$16$MyPair', 'REPL/$JShell$16$MyPair', integer, 'REPL/$JShell$16$MyPair', 'java/lang/String', top, 'java/lang/String', integer, 'java/lang/Integer', integer }
stack: { 'java/io/PrintStream', 'java/lang/String', 'java/lang/String' }
Bytecode:
0000000: 2a59 b800 0757 4c03 3d2b 1cba 000d 0000
0000010: ab00 0000 0000 00c8 0000 0001 0000 0000
0000020: 0000 0014 2b4e 2db6 0011 c000 173a 0603
0000030: 3607 1906 1507 ba00 1900 00ab 0000 008b
0000040: 0000 0002 ffff ffff 0000 008b 0000 0000
0000050: 0000 0019 1906 3a04 2db6 001a c000 1d3a
0000060: 0803 3609 1908 1509 ba00 1f00 00ab 0000
0000070: 0000 0041 0000 0002 ffff ffff 0000 0041
0000080: 0000 0000 0000 001b 1908 3a05 1904 1220
0000090: b600 229a 0009 0436 09a7 ffcb b200 2619
00000a0: 0419 05ba 002c 0000 b600 30a7 0035 b200
00000b0: 2619 0419 04b6 0036 b600 3aba 003e 0000
00000c0: b600 30a7 001d b200 2619 0519 06ba 0041
00000d0: 0000 b600 30a7 000b b200 2612 42b6 0030
00000e0: a700 114c bb00 4659 2bb6 0048 2bb7 004c
00000f0: bfb1
Exception Handler Table:
bci [39, 42] => handler: 227
bci [89, 92] => handler: 227
Stackmap Table:
append_frame(@9,Object[#18],Integer)
same_frame(@36)
full_frame(@50,{Object[#18],Object[#18],Integer,Object[#18],Top,Top,Object[#23],Integer},{})
same_frame(@84)
full_frame(@100,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Top,Object[#23],Integer,Object[#29],Integer},{})
same_frame(@136)
full_frame(@156,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Object[#29],Object[#23],Integer,Object[#29],Integer},{})
full_frame(@174,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Top,Object[#23],Integer,Object[#29],Integer},{})
full_frame(@198,{Object[#18],Object[#18],Integer,Object[#18],Top,Top,Object[#23],Integer},{})
full_frame(@216,{Object[#18],Object[#18],Integer},{})
chop_frame(@224,2)
same_locals_1_stack_item_frame(@227,Object[#68])
same_frame(@241)
| at (#15:1)
---------- BEGIN SOURCE ----------
record MyPair<T1, T2>(T1 first, T2 second) {}
static void recordInferenceJdk19(MyPair<String, Integer> pair) {
switch (pair) {
case MyPair<String, Integer>(var text, var count) when text.contains("Michael") ->
System.out.println(text + " is " + count + " years old");
case MyPair<String, Integer>(var text, var count) when count > 5 && count < 10 ->
System.out.println("repeated " + text.repeat(count));
case MyPair<String, Integer>(var text, var count) -> System.out.println(text + count);
default -> System.out.println("PENG");
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
jshell> static void recordInferenceJdk19io(MyPair<String, Integer> pair) {
...> if (pair instanceof MyPair<String, Integer>(var text, var count) && text.contains("Michael"))
...> System.out.println(text + " is " + count + "years old");
...> else if (pair instanceof MyPair<String, Integer>(var text, var count) && count > 5 && count < 10)
...> System.out.println("repeated " + text.repeat(count));
...> else if (pair instanceof MyPair<String, Integer>(var text, var count))
...> System.out.println(text + count);
...> else
...> System.out.println("PENG");
...> }
| Erstellt Methode recordInferenceJdk19io(MyPair<String, Integer>)
jshell> recordInferenceJdk19io(new MyPair<>("Mike", 7))
repeated MikeMikeMikeMikeMikeMikeMike
jshell> recordInferenceJdk19io(new MyPair<>("Michael", 52))
Michael is 52years old
macOS Monterey 12.6.4
A DESCRIPTION OF THE PROBLEM :
Unexpected problems when combining record patterns and switch resulting in a java.lang.VerifyError: Bad type on operand stack
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create record
jshell> record MyPair<T1, T2>(T1 first, T2 second) {
...> }
2. Create Method
jshell> static void recordInferenceJdk19(MyPair<String, Integer> pair) {
...> switch (pair) {
...> case MyPair<String, Integer>(var text, var count) when text.contains("Michael") ->
...> System.out.println(text + " is " + count + " years old");
...> case MyPair<String, Integer>(var text, var count) when count > 5 && count < 10 ->
...> System.out.println("repeated " + text.repeat(count));
...> case MyPair<String, Integer>(var text, var count) -> System.out.println(text + count);
...> default -> System.out.println("PENG");
...> }
...> }
3. Call Method
jshell> recordInferenceJdk19(new MyPair<>("Michael", 52))
| Ausnahme java.lang.VerifyError: Bad type on operand stack
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The suitable case should be selected. Like with instanceof
When calling the method
* recordInferenceJdk19(new MyPair<>("Michael", 52))
=> case 1 should match
=> "Michael is 52 years old"
* recordInferenceJdk19(new MyPair<>("Mike", 7))
=> case 2 should match
=> "repeated MikeMikeMikeMikeMikeMikeMike"
-------------------------
INSTANCEOF-Version works well
jshell> static void recordInferenceJdk19io(MyPair<String, Integer> pair) {
...> if (pair instanceof MyPair<String, Integer>(var text, var count) && text.contains("Michael"))
...> System.out.println(text + " is " + count + " years old");
...> else if (pair instanceof MyPair<String, Integer>(var text, var count) && count > 5 && count < 10)
...> System.out.println("repeated " + text.repeat(count));
...> else if (pair instanceof MyPair<String, Integer>(var text, var count))
...> System.out.println(text + count);
...> else
...> System.out.println("PENG");
...> }
| Erstellt Methode recordInferenceJdk19io(MyPair<String, Integer>)
jshell> recordInferenceJdk19io(new MyPair<>("Mike", 7))
repeated MikeMikeMikeMikeMikeMikeMike
jshell> recordInferenceJdk19io(new MyPair<>("Michael", 52))
Michael is 52 years old
ACTUAL -
jshell> recordInferenceJdk19(new MyPair<>("Michael", 52))
| Ausnahme java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
REPL/$JShell$17B.recordInferenceJdk19(LREPL/$JShell$16$MyPair;)V @181: invokevirtual
Reason:
Type 'java/lang/String' (current frame, stack[2]) is not assignable to 'java/lang/Integer'
Current Frame:
bci: @181
flags: { }
locals: { 'REPL/$JShell$16$MyPair', 'REPL/$JShell$16$MyPair', integer, 'REPL/$JShell$16$MyPair', 'java/lang/String', top, 'java/lang/String', integer, 'java/lang/Integer', integer }
stack: { 'java/io/PrintStream', 'java/lang/String', 'java/lang/String' }
Bytecode:
0000000: 2a59 b800 0757 4c03 3d2b 1cba 000d 0000
0000010: ab00 0000 0000 00c8 0000 0001 0000 0000
0000020: 0000 0014 2b4e 2db6 0011 c000 173a 0603
0000030: 3607 1906 1507 ba00 1900 00ab 0000 008b
0000040: 0000 0002 ffff ffff 0000 008b 0000 0000
0000050: 0000 0019 1906 3a04 2db6 001a c000 1d3a
0000060: 0803 3609 1908 1509 ba00 1f00 00ab 0000
0000070: 0000 0041 0000 0002 ffff ffff 0000 0041
0000080: 0000 0000 0000 001b 1908 3a05 1904 1220
0000090: b600 229a 0009 0436 09a7 ffcb b200 2619
00000a0: 0419 05ba 002c 0000 b600 30a7 0035 b200
00000b0: 2619 0419 04b6 0036 b600 3aba 003e 0000
00000c0: b600 30a7 001d b200 2619 0519 06ba 0041
00000d0: 0000 b600 30a7 000b b200 2612 42b6 0030
00000e0: a700 114c bb00 4659 2bb6 0048 2bb7 004c
00000f0: bfb1
Exception Handler Table:
bci [39, 42] => handler: 227
bci [89, 92] => handler: 227
Stackmap Table:
append_frame(@9,Object[#18],Integer)
same_frame(@36)
full_frame(@50,{Object[#18],Object[#18],Integer,Object[#18],Top,Top,Object[#23],Integer},{})
same_frame(@84)
full_frame(@100,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Top,Object[#23],Integer,Object[#29],Integer},{})
same_frame(@136)
full_frame(@156,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Object[#29],Object[#23],Integer,Object[#29],Integer},{})
full_frame(@174,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Top,Object[#23],Integer,Object[#29],Integer},{})
full_frame(@198,{Object[#18],Object[#18],Integer,Object[#18],Top,Top,Object[#23],Integer},{})
full_frame(@216,{Object[#18],Object[#18],Integer},{})
chop_frame(@224,2)
same_locals_1_stack_item_frame(@227,Object[#68])
same_frame(@241)
| at (#15:1)
---------- BEGIN SOURCE ----------
record MyPair<T1, T2>(T1 first, T2 second) {}
static void recordInferenceJdk19(MyPair<String, Integer> pair) {
switch (pair) {
case MyPair<String, Integer>(var text, var count) when text.contains("Michael") ->
System.out.println(text + " is " + count + " years old");
case MyPair<String, Integer>(var text, var count) when count > 5 && count < 10 ->
System.out.println("repeated " + text.repeat(count));
case MyPair<String, Integer>(var text, var count) -> System.out.println(text + count);
default -> System.out.println("PENG");
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
jshell> static void recordInferenceJdk19io(MyPair<String, Integer> pair) {
...> if (pair instanceof MyPair<String, Integer>(var text, var count) && text.contains("Michael"))
...> System.out.println(text + " is " + count + "years old");
...> else if (pair instanceof MyPair<String, Integer>(var text, var count) && count > 5 && count < 10)
...> System.out.println("repeated " + text.repeat(count));
...> else if (pair instanceof MyPair<String, Integer>(var text, var count))
...> System.out.println(text + count);
...> else
...> System.out.println("PENG");
...> }
| Erstellt Methode recordInferenceJdk19io(MyPair<String, Integer>)
jshell> recordInferenceJdk19io(new MyPair<>("Mike", 7))
repeated MikeMikeMikeMikeMikeMikeMike
jshell> recordInferenceJdk19io(new MyPair<>("Michael", 52))
Michael is 52years old