ADDITIONAL SYSTEM INFORMATION :
openjdk version "22.0.2" 2024-07-16
OpenJDK Runtime Environment Zulu22.32+15-CA (build 22.0.2+9)
OpenJDK 64-Bit Server VM Zulu22.32+15-CA (build 22.0.2+9, mixed mode, sharing)
Mac OS 14.5 (23F79)
A DESCRIPTION OF THE PROBLEM :
The following code fails to compile with an unexpected crash report. I wrote several comments in the code sample to show how I narrowed down the problem.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the code sample with "javac Test.java"
ACTUAL -
An exception has occurred in the compiler (22.0.2). Please file a bug against the Java compiler via the Java bug reporting page (https://bugreport.java.com) after checking the Bug Database (https://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
java.lang.NullPointerException: Cannot invoke "com.sun.tools.javac.code.Type.isErroneous()" because "record.type" is null
at jdk.compiler/com.sun.tools.javac.comp.Flow.makePatternDescription(Flow.java:3471)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.exhausts(Flow.java:780)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitSwitchExpression(Flow.java:762)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitYield(Flow.java:1205)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCYield.accept(JCTree.java:1677)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:58)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.visitCase(TreeScanner.java:183)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCase.accept(JCTree.java:1343)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.analyzeTree(Flow.java:1276)
at jdk.compiler/com.sun.tools.javac.comp.Flow.aliveAfter(Flow.java:284)
at jdk.compiler/com.sun.tools.javac.comp.Attr.handleSwitch(Attr.java:1858)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitSwitchExpression(Attr.java:1630)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.DeferredAttr.attribSpeculative(DeferredAttr.java:515)
at jdk.compiler/com.sun.tools.javac.comp.DeferredAttr.attribSpeculative(DeferredAttr.java:495)
at jdk.compiler/com.sun.tools.javac.comp.DeferredAttr.attribSpeculative(DeferredAttr.java:466)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.lambda$processArg$0(ArgumentAttr.java:221)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.processArg(ArgumentAttr.java:243)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.processArg(ArgumentAttr.java:220)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.visitSwitchExpression(ArgumentAttr.java:261)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.attribArg(ArgumentAttr.java:198)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:660)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribArgs(Attr.java:763)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitApply(Attr.java:2603)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1816)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitReturn(Attr.java:2476)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1728)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStat(Attr.java:736)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStats(Attr.java:755)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1440)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1092)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStat(Attr.java:736)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1229)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:916)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStat(Attr.java:736)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:5615)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribClass(Attr.java:5503)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribClass(Attr.java:5327)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attrib(Attr.java:5266)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1366)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:976)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:66)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:52)
---------- BEGIN SOURCE ----------
public class Test {
sealed interface I permits R, C {}
record R(String s) implements I {}
static final class C implements I {}
String method() {
I i1 = null;
I i2 = null;
// DOES COMPILE
// using the 'm' method, and a single switch
//return m(switch (i2) {
// case R(String s2) -> "";
// case C c -> "";
//});
// DOES COMPILE
// using nested switches but no 'm' method
//return switch (i1) {
// case R(String s1) -> switch (i2) {
// case R(String s2) -> "";
// case C c -> "";
// };
// case C c -> "";
//};
// DOESN'T COMPILE
// Using both 'm' method and nested switches
return m(switch (i1) {
case R(String s1) -> switch (i2) {
case R(String s2) -> ""; // It's related to this deconstructed record pattern. The compilation works with case R r -> ""
case C c -> "";
};
case C c -> "";
});
}
String m(int i) {
return "";
}
String m(String s) {
return "";
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As I mentionned in the code comments, the workaround is to not use record deconstruction pattern
FREQUENCY : always
openjdk version "22.0.2" 2024-07-16
OpenJDK Runtime Environment Zulu22.32+15-CA (build 22.0.2+9)
OpenJDK 64-Bit Server VM Zulu22.32+15-CA (build 22.0.2+9, mixed mode, sharing)
Mac OS 14.5 (23F79)
A DESCRIPTION OF THE PROBLEM :
The following code fails to compile with an unexpected crash report. I wrote several comments in the code sample to show how I narrowed down the problem.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the code sample with "javac Test.java"
ACTUAL -
An exception has occurred in the compiler (22.0.2). Please file a bug against the Java compiler via the Java bug reporting page (https://bugreport.java.com) after checking the Bug Database (https://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
java.lang.NullPointerException: Cannot invoke "com.sun.tools.javac.code.Type.isErroneous()" because "record.type" is null
at jdk.compiler/com.sun.tools.javac.comp.Flow.makePatternDescription(Flow.java:3471)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.exhausts(Flow.java:780)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitSwitchExpression(Flow.java:762)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitYield(Flow.java:1205)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCYield.accept(JCTree.java:1677)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:58)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.visitCase(TreeScanner.java:183)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCase.accept(JCTree.java:1343)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at jdk.compiler/com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at jdk.compiler/com.sun.tools.javac.comp.Flow$AliveAnalyzer.analyzeTree(Flow.java:1276)
at jdk.compiler/com.sun.tools.javac.comp.Flow.aliveAfter(Flow.java:284)
at jdk.compiler/com.sun.tools.javac.comp.Attr.handleSwitch(Attr.java:1858)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitSwitchExpression(Attr.java:1630)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.DeferredAttr.attribSpeculative(DeferredAttr.java:515)
at jdk.compiler/com.sun.tools.javac.comp.DeferredAttr.attribSpeculative(DeferredAttr.java:495)
at jdk.compiler/com.sun.tools.javac.comp.DeferredAttr.attribSpeculative(DeferredAttr.java:466)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.lambda$processArg$0(ArgumentAttr.java:221)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.processArg(ArgumentAttr.java:243)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.processArg(ArgumentAttr.java:220)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.visitSwitchExpression(ArgumentAttr.java:261)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
at jdk.compiler/com.sun.tools.javac.comp.ArgumentAttr.attribArg(ArgumentAttr.java:198)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:660)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribArgs(Attr.java:763)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitApply(Attr.java:2603)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1816)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitReturn(Attr.java:2476)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1728)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStat(Attr.java:736)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStats(Attr.java:755)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1440)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1092)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStat(Attr.java:736)
at jdk.compiler/com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1229)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:916)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribTree(Attr.java:662)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribStat(Attr.java:736)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:5615)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribClass(Attr.java:5503)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attribClass(Attr.java:5327)
at jdk.compiler/com.sun.tools.javac.comp.Attr.attrib(Attr.java:5266)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1366)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:976)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:66)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:52)
---------- BEGIN SOURCE ----------
public class Test {
sealed interface I permits R, C {}
record R(String s) implements I {}
static final class C implements I {}
String method() {
I i1 = null;
I i2 = null;
// DOES COMPILE
// using the 'm' method, and a single switch
//return m(switch (i2) {
// case R(String s2) -> "";
// case C c -> "";
//});
// DOES COMPILE
// using nested switches but no 'm' method
//return switch (i1) {
// case R(String s1) -> switch (i2) {
// case R(String s2) -> "";
// case C c -> "";
// };
// case C c -> "";
//};
// DOESN'T COMPILE
// Using both 'm' method and nested switches
return m(switch (i1) {
case R(String s1) -> switch (i2) {
case R(String s2) -> ""; // It's related to this deconstructed record pattern. The compilation works with case R r -> ""
case C c -> "";
};
case C c -> "";
});
}
String m(int i) {
return "";
}
String m(String s) {
return "";
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As I mentionned in the code comments, the workaround is to not use record deconstruction pattern
FREQUENCY : always
- links to
-
Review(master) openjdk/jdk/20990