From 627fbad7e8a847dcf1613e5fc68742b451ce7cf5 Mon Sep 17 00:00:00 2001 From: Manoj Palat Date: Fri, 12 Jun 2026 14:41:29 +0530 Subject: [PATCH 1/2] Fixes the failure of A Short to byte variant of switch with primitives in patterns code in issue #4979 --- .../jdt/internal/compiler/ast/Pattern.java | 5 +-- .../regression/PrimitiveInPatternsTest.java | 36 ++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java index 33c640cf440..6026172b6c3 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java @@ -118,10 +118,11 @@ public boolean coversValue(Constant cst, BlockScope scope) { return false; if (!(this.resolvedType.unboxedType() instanceof BaseTypeBinding baseType)) return false; - if (!cst.isExactTestingConversion(baseType)) - return false; int constantTypeID = cst.typeID(); + // find route as well as flag preview PrimitiveConversionRoute route = findPrimitiveConversionRoute(baseType, TypeBinding.wellKnownBaseType(constantTypeID), scope); + if (cst.isExactTestingConversion(baseType)) + return true; // flagging a preview already taken care above - let's return. switch (route) { // JLS §5.7.2: case NARROWING_PRIMITVE_CONVERSION: 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 4372ed40d75..e60e4209de9 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 @@ -30,7 +30,7 @@ public class PrimitiveInPatternsTest extends AbstractRegressionTest9 { static { // TESTS_NUMBERS = new int [] { 1 }; // TESTS_RANGE = new int[] { 1, -1 }; -// TESTS_NAMES = new String[] { "testDominanceIssue4979_001" }; +// TESTS_NAMES = new String[] { "testDominanceIssue4979_002" }; } private String extraLibPath; public static Class testClass() { @@ -7648,4 +7648,38 @@ public int foo(Character c) { "----------\n"); } + public void testDominanceIssue4979_002() { + runNegativeTest(new String[] { + "X.java", + """ + public class X { + public int foo1(Short c) { + int result = 0; + switch (c) { + case Short c1 -> { + result = c1; + break; + } + case (byte) 0 -> { + result = 0; + break; + } + } + return result; + } + } + """ + }, + "----------\n" + + "1. WARNING in X.java (at line 5)\n" + + " case Short c1 -> {\n" + + " ^^^^^^^^\n" + + "You are using a preview language feature that may or may not be supported in a future release\n" + + "----------\n" + + "2. ERROR in X.java (at line 9)\n" + + " case (byte) 0 -> {\n" + + " ^^^^^^^^\n" + + "This case label is dominated by one of the preceding case labels\n" + + "----------\n"); + } } From 74c829eff28b4b927945ad6144f0153fe66c8251 Mon Sep 17 00:00:00 2001 From: Manoj Palat Date: Wed, 17 Jun 2026 11:54:05 +0530 Subject: [PATCH 2/2] switch dominance 4979 --- .../jdt/internal/compiler/ast/Pattern.java | 6 ++-- .../compiler/ast/SwitchStatement.java | 25 +++++++------- .../regression/PrimitiveInPatternsTest.java | 34 ++++++++++++++++++- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java index 6026172b6c3..40b235b3740 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Pattern.java @@ -94,7 +94,7 @@ public boolean coversType(TypeBinding type, Scope scope) { case BOXING_CONVERSION_AND_WIDENING_REFERENCE_CONVERSION: return true; case WIDENING_PRIMITIVE_CONVERSION: - return BaseTypeBinding.isExactWidening(this.resolvedType.id, type.id); + return BaseTypeBinding.isExactWidening(this.resolvedType.unboxedType().id, type.id); case WIDENING_AND_NARROWING_PRIMITIVE_CONVERSION: return false; // char->byte /* §14.11.1.1 "CE contains a type pattern with a primitive type P, @@ -120,9 +120,9 @@ public boolean coversValue(Constant cst, BlockScope scope) { return false; int constantTypeID = cst.typeID(); // find route as well as flag preview + if (!cst.isExactTestingConversion(baseType)) + return false; // flagging a preview already taken care above - let's return. PrimitiveConversionRoute route = findPrimitiveConversionRoute(baseType, TypeBinding.wellKnownBaseType(constantTypeID), scope); - if (cst.isExactTestingConversion(baseType)) - return true; // flagging a preview already taken care above - let's return. switch (route) { // JLS §5.7.2: case NARROWING_PRIMITVE_CONVERSION: 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 9a548a52910..ae4a7f1364a 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 @@ -314,9 +314,9 @@ private boolean duplicateConstant(LabelExpression current, LabelExpression prior return false; } - void gatherLabelExpression(LabelExpression labelExpression) { + void gatherLabelExpression(LabelExpression candidateLabelExpression) { // domination check - if (labelExpression.expression instanceof Pattern pattern) { + if (candidateLabelExpression.expression instanceof Pattern pattern) { if (this.defaultCase != null) { this.scope.problemReporter().patternDominatedByAnother(pattern); } else { @@ -328,20 +328,21 @@ void gatherLabelExpression(LabelExpression labelExpression) { } } } else { - if (labelExpression.expression instanceof NullLiteral) { + if (candidateLabelExpression.expression instanceof NullLiteral) { if (this.defaultCase != null) - this.scope.problemReporter().patternDominatedByAnother(labelExpression.expression); + this.scope.problemReporter().patternDominatedByAnother(candidateLabelExpression.expression); } else { - TypeBinding boxedType = labelExpression.type.isBaseType() ? this.scope.environment().computeBoxingType(labelExpression.type) : labelExpression.type; +// TypeBinding boxedType = labelExpression.type.isBaseType() ? this.scope.environment().computeBoxingType(labelExpression.type) : labelExpression.type; + TypeBinding candidateType = candidateLabelExpression.type; for (int i = 0; i < this.labelExpressionIndex; i++) { if (this.labelExpressions[i].expression instanceof Pattern priorPattern) { - if (priorPattern.coversType(boxedType, this.scope)) { - this.scope.problemReporter().patternDominatedByAnother(labelExpression.expression); + if (priorPattern.coversType(candidateType, this.scope)) { + this.scope.problemReporter().patternDominatedByAnother(candidateLabelExpression.expression); break; } - Constant cst = labelExpression.expression.constant; + Constant cst = candidateLabelExpression.expression.constant; if (cst != null && cst != Constant.NotAConstant && priorPattern.coversValue(cst, this.scope)) { - this.scope.problemReporter().patternDominatedByAnother(labelExpression.expression); + this.scope.problemReporter().patternDominatedByAnother(candidateLabelExpression.expression); break; } } @@ -349,13 +350,13 @@ void gatherLabelExpression(LabelExpression labelExpression) { } // duplicate constant check for (int i = 0; i < this.labelExpressionIndex; i++) { - if (duplicateConstant(labelExpression, this.labelExpressions[i])) { - this.scope.problemReporter().duplicateCase(labelExpression.expression); + if (duplicateConstant(candidateLabelExpression, this.labelExpressions[i])) { + this.scope.problemReporter().duplicateCase(candidateLabelExpression.expression); break; } } } - this.labelExpressions[this.labelExpressionIndex++] = labelExpression; + this.labelExpressions[this.labelExpressionIndex++] = candidateLabelExpression; } private void complainIfNotExhaustiveSwitch(BlockScope upperScope, TypeBinding selectorType, CompilerOptions compilerOptions) { 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 e60e4209de9..0651cbfe588 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 @@ -30,7 +30,7 @@ public class PrimitiveInPatternsTest extends AbstractRegressionTest9 { static { // TESTS_NUMBERS = new int [] { 1 }; // TESTS_RANGE = new int[] { 1, -1 }; -// TESTS_NAMES = new String[] { "testDominanceIssue4979_002" }; +// TESTS_NAMES = new String[] { "testDominanceIssue4979_002" }; } private String extraLibPath; public static Class testClass() { @@ -7682,4 +7682,36 @@ public int foo1(Short c) { "This case label is dominated by one of the preceding case labels\n" + "----------\n"); } + public void testDominanceIssue4979_003() { + runNegativeTest(new String[] { + "X.java", + """ + @SuppressWarnings("preview") + public class X { + void foo() { + int j = 1; + switch(j) { + case byte b -> + System.out.println("A byte"); + case 260 -> // not dominated + System.out.println("An int that can be represented as a byte exactly"); + default -> + System.out.println("Integer that cannot be represented as a float exactly"); + } + } + public static void main(String[] args) { + Zork(); + } + } + """ + }, + "----------\n" + + "1. ERROR in X.java (at line 15)\n" + + " Zork();\n" + + " ^^^^\n" + + "The method Zork() is undefined for the type X\n" + + "----------\n" + ); + } + }