diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index 7a6183feec6..cbff8310238 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -128,6 +128,7 @@ public static record SingletonBootstrap(String id, char[] selector, char[] signa LocalVariableBinding restartIndexLocal = null; /* package */ boolean isNonTraditional = false; + /* package */ boolean isPrimitiveSwitch = false; /* package */ List caseLabelElements = new ArrayList<>(0);//TODO: can we remove this? public List caseLabelElementTypes = new ArrayList<>(0); int constantIndex = 0; @@ -1114,7 +1115,6 @@ public void resolve(BlockScope upperScope) { try { boolean isEnumSwitch = false; boolean isStringSwitch = false; - boolean isPrimitiveSwitch = false; TypeBinding expressionType = this.expression.resolveType(upperScope); CompilerOptions compilerOptions = upperScope.compilerOptions(); boolean isEnhanced = checkAndSetEnhanced(upperScope, expressionType); @@ -1126,7 +1126,7 @@ public void resolve(BlockScope upperScope) { break checkType; } else if (expressionType.isBaseType()) { if (JavaFeature.PRIMITIVES_IN_PATTERNS.isSupported(compilerOptions)) { - isPrimitiveSwitch = true; + this.isPrimitiveSwitch = true; } if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, TypeBinding.INT)) break checkType; @@ -1151,7 +1151,7 @@ public void resolve(BlockScope upperScope) { break checkType; } if (!JavaFeature.PATTERN_MATCHING_IN_SWITCH.isSupported(compilerOptions) || (expressionType.isBaseType() && expressionType.id != T_null && expressionType.id != T_void)) { - if (!isPrimitiveSwitch) { // when isPrimitiveSwitch is set it is approved above + if (!this.isPrimitiveSwitch) { // when isPrimitiveSwitch is set it is approved above upperScope.problemReporter().incorrectSwitchType(this.expression, expressionType); expressionType = null; // fault-tolerance: ignore type mismatch from constants from hereon } @@ -1489,6 +1489,9 @@ private boolean needPatternDispatchCopy() { switch (eType.id) { case TypeIds.T_JavaLangLong, TypeIds.T_JavaLangFloat, TypeIds.T_JavaLangDouble: return true; + case TypeIds.T_long, TypeIds.T_double, TypeIds.T_float : + if (this.isPrimitiveSwitch) + return true; // note: if no patterns are present we optimize Boolean to use unboxing rather than indy typeSwitch } return !(eType.isPrimitiveOrBoxedPrimitiveType() || eType.isEnum() || eType.id == TypeIds.T_JavaLangString); // classic selectors diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java index 6fcfa962a65..0b883504de4 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java @@ -31,7 +31,7 @@ public class PrimitiveInPatternsTest extends AbstractRegressionTest9 { static { // TESTS_NUMBERS = new int [] { 1 }; // TESTS_RANGE = new int[] { 1, -1 }; -// TESTS_NAMES = new String[] { "test267" }; +// TESTS_NAMES = new String[] { "testIssue2928" }; } private String extraLibPath; public static Class testClass() { @@ -6782,6 +6782,90 @@ public static void main(String[] args) { }, "1"); } + public void testIssue2928_001() { + runConformTest(new String[] { + "X.java", + """ + public class X { + public static boolean foo(Double d) { + boolean b; + switch (d) { + case 1d -> b = true; + default -> b = false; + } + return b; + } + public static void main(String[] args) { + System.out.println(X.foo(1d)); + } + } + """ + }, + "true"); + } + + public void testIssue2928_002() { + runConformTest(new String[] { + "X.java", + """ + public class X { + public static boolean foo(double d) { + boolean b; + switch (d) { + case 1d -> b = true; + default -> b = false; + } + return b; + } + public static void main(String[] args) { + System.out.println(X.foo(1d)); + } + } + """ + }, + "true"); + } + public void testIssue2928_003() { + runConformTest(new String[] { + "X.java", + """ + public class X { + public static boolean foo(double d) { + boolean b; + switch (d) { + case 1d -> b = true; + default -> b = false; + } + return b; + } + public static void main(String[] args) { + System.out.println(X.foo(2d)); + } + } + """ + }, + "false"); + } + public void testIssue2928_004() { + runConformTest(new String[] { + "X.java", + """ + public class X { + public static boolean foo(double d) { + boolean b; + switch (d) { + default -> b = false; + } + return b; + } + public static void main(String[] args) { + System.out.println(X.foo(1d)); + } + } + """ + }, + "false"); + } public void testNonPrim001() { runConformTest(new String[] { "X.java",