diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java index 49fb1ecfaff..77cb7cc0f05 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java @@ -381,11 +381,8 @@ private Constant resolveCasePattern(BlockScope scope, TypeBinding caseType, Type // The following code is copied from InstanceOfExpression#resolve() // But there are enough differences to warrant a copy if (!type.isReifiable()) { - if (expressionType != TypeBinding.NULL && !(e instanceof RecordPattern)) { - boolean isLegal = e.checkCastTypesCompatibility(scope, type, expressionType, e, false); - if (!isLegal || (e.bits & ASTNode.UnsafeCast) != 0) { - scope.problemReporter().unsafeCastInInstanceof(e, type, expressionType); - } + if (!e.isApplicable(switchExpressionType, scope, e)) { + return Constant.NotAConstant; } } else if (type.isValidBinding()) { // if not a valid binding, an error has already been reported for unresolved type diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/EitherOrMultiPattern.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/EitherOrMultiPattern.java index 9d4e81fe9b0..8ef74f12e1c 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/EitherOrMultiPattern.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/EitherOrMultiPattern.java @@ -54,6 +54,13 @@ public void setIsGuarded() { this.patterns[i].setIsGuarded(); } + @Override + public void setOuterExpressionType(TypeBinding expressionType) { + super.setOuterExpressionType(expressionType); + for (int i = 0; i < this.patternsCount; i++) + this.patterns[i].setOuterExpressionType(expressionType); + } + @Override public TypeBinding resolveType(BlockScope scope) { boolean hasError = false; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/GuardedPattern.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/GuardedPattern.java index a4317e9c066..47e6f2b846f 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/GuardedPattern.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/GuardedPattern.java @@ -76,6 +76,12 @@ public void setIsEitherOrPattern() { this.primaryPattern.setIsEitherOrPattern(); } + @Override + public void setOuterExpressionType(TypeBinding expressionType) { + super.setOuterExpressionType(expressionType); + this.primaryPattern.setOuterExpressionType(expressionType); + } + @Override public boolean coversType(TypeBinding type, Scope scope) { return isUnguarded() && this.primaryPattern.coversType(type, scope); @@ -130,7 +136,7 @@ public void traverse(ASTVisitor visitor, BlockScope scope) { } @Override - protected boolean isApplicable(TypeBinding other, BlockScope scope) { - return this.primaryPattern.isApplicable(other, scope); + protected boolean isApplicable(TypeBinding expressionType, BlockScope scope, ASTNode location) { + return this.primaryPattern.isApplicable(expressionType, scope, location); } } \ No newline at end of file diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java index fa23ce53502..1972bd87b09 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java @@ -277,6 +277,13 @@ public TypeBinding resolveType(BlockScope scope) { if (expressionType == null || checkedType == null) return null; + if (this.pattern != null) { + if (this.pattern.isApplicable(expressionType, scope, this)) { + checkForPrimitives(scope, checkedType, expressionType); + } + return this.resolvedType = TypeBinding.BOOLEAN; + } + if (!checkedType.isReifiable()) { CompilerOptions options = scope.compilerOptions(); // Report same as before for older compliances @@ -286,7 +293,7 @@ public TypeBinding resolveType(BlockScope scope) { if (expressionType != TypeBinding.NULL) { boolean isLegal = checkCastTypesCompatibility(scope, checkedType, expressionType, this.expression, true); if (!isLegal || (this.bits & ASTNode.UnsafeCast) != 0) { - scope.problemReporter().unsafeCastInInstanceof(this.expression, checkedType, expressionType); + scope.problemReporter().unsafeCastInTestingContext(this.expression, checkedType, expressionType); } else { checkRefForPrimitivesAndAddSecretVariable(scope, checkedType, expressionType); } @@ -294,17 +301,18 @@ public TypeBinding resolveType(BlockScope scope) { } } else if (checkedType.isValidBinding()) { // if not a valid binding, an error has already been reported for unresolved type - if ((expressionType != TypeBinding.NULL && expressionType.isBaseType()) // disallow autoboxing - || checkedType.isBaseType() - || !checkCastTypesCompatibility(scope, checkedType, expressionType, null, true)) { - checkForPrimitives(scope, checkedType, expressionType); - } + checkForPrimitives(scope, checkedType, expressionType); } return this.resolvedType = TypeBinding.BOOLEAN; } private void checkForPrimitives(BlockScope scope, TypeBinding checkedType, TypeBinding expressionType) { + boolean needToCheck = (expressionType != TypeBinding.NULL && expressionType.isBaseType()) // disallow autoboxing + || checkedType.isBaseType() + || !checkCastTypesCompatibility(scope, checkedType, expressionType, null, true); + if (!needToCheck) + return; PrimitiveConversionRoute route = Pattern.findPrimitiveConversionRoute(checkedType, expressionType, scope); this.testContextRecord = new TestContextRecord(checkedType, expressionType, route); 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 f07c01e55a3..15d3fdad800 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 @@ -139,25 +139,37 @@ public TypeReference getType() { } // 14.30.3 Properties of Patterns: A pattern p is said to be applicable at a type T if ... - protected boolean isApplicable(TypeBinding other, BlockScope scope) { - TypeBinding patternType = this.resolvedType; - if (patternType == null) // ill resolved pattern - return false; + protected boolean isApplicable(TypeBinding expressionType, BlockScope scope, ASTNode location) { + if (expressionType == TypeBinding.NULL) + return true; + TypeReference typeRef = getType(); + if (typeRef == null) + return true; // nothing to be checked for wildcard '_' + TypeBinding patternType = typeRef.resolvedType; + if (patternType == null || !patternType.isValidBinding() || !expressionType.isValidBinding()) + return false; // problem already reported + // 14.30.3 Properties of Patterns doesn't allow boxing nor unboxing, primitive widening/narrowing (< JLS23) - if (patternType.isBaseType() != other.isBaseType() && !JavaFeature.PRIMITIVES_IN_PATTERNS.isSupported(scope.compilerOptions())) { - scope.problemReporter().incompatiblePatternType(this, other, patternType); + if (patternType.isBaseType() != expressionType.isBaseType() && !JavaFeature.PRIMITIVES_IN_PATTERNS.isSupported(scope.compilerOptions())) { + scope.problemReporter().notCompatibleTypesError(location, expressionType, patternType); return false; } if (patternType.isBaseType()) { PrimitiveConversionRoute route = Pattern.findPrimitiveConversionRoute(this.resolvedType, this.outerExpressionType, scope); - if (!TypeBinding.equalsEquals(other, patternType) + if (!TypeBinding.equalsEquals(expressionType, patternType) && route == PrimitiveConversionRoute.NO_CONVERSION_ROUTE) { - scope.problemReporter().incompatiblePatternType(this, other, patternType); + scope.problemReporter().notCompatibleTypesError(location, expressionType, patternType); + return false; + } + } else { + if (!checkCastTypesCompatibility(scope, patternType, expressionType, null, true)) { + scope.problemReporter().notCompatibleTypesError(location, expressionType, patternType); + return false; + } + if ((this.bits & ASTNode.UnsafeCast) != 0) { + scope.problemReporter().unsafeCastInTestingContext(location, patternType, this.outerExpressionType); return false; } - } else if (!checkCastTypesCompatibility(scope, other, patternType, null, true)) { - scope.problemReporter().incompatiblePatternType(this, other, patternType); - return false; } return true; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/RecordPattern.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/RecordPattern.java index 1e64ee3e452..bc26d4f3489 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/RecordPattern.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/RecordPattern.java @@ -152,7 +152,7 @@ public TypeBinding resolveType(BlockScope scope) { } } TypeBinding componentType = componentBinding.type; - if (p1.isApplicable(componentType, scope)) { + if (p1.isApplicable(componentType, scope, p1)) { p1.isTotalTypeNode = p1.coversType(componentType, scope); MethodBinding[] methods = this.resolvedType.getMethods(componentBinding.name); if (methods != null && methods.length > 0) { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index d1ac75e2e53..4a749013d7b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -7303,7 +7303,7 @@ public void noSuchEnclosingInstance(TypeBinding targetType, ASTNode location, bo location.sourceStart, location instanceof LambdaExpression ? ((LambdaExpression)location).diagnosticsSourceEnd() : location.sourceEnd); } -public void notCompatibleTypesError(EqualExpression expression, TypeBinding leftType, TypeBinding rightType) { +public void notCompatibleTypesError(ASTNode location, TypeBinding leftType, TypeBinding rightType) { String leftName = new String(leftType.readableName()); String rightName = new String(rightType.readableName()); String leftShortName = new String(leftType.shortReadableName()); @@ -7312,28 +7312,18 @@ public void notCompatibleTypesError(EqualExpression expression, TypeBinding left leftShortName = leftName; rightShortName = rightName; } - this.handle( - IProblem.IncompatibleTypesInEqualityOperator, - new String[] {leftName, rightName }, - new String[] {leftShortName, rightShortName }, - expression.sourceStart, - expression.sourceEnd); -} -public void notCompatibleTypesError(Expression expression, TypeBinding leftType, TypeBinding rightType) { - String leftName = new String(leftType.readableName()); - String rightName = new String(rightType.readableName()); - String leftShortName = new String(leftType.shortReadableName()); - String rightShortName = new String(rightType.shortReadableName()); - if (leftShortName.equals(rightShortName)){ - leftShortName = leftName; - rightShortName = rightName; + int problemId = IProblem.IncompatibleTypesInEqualityOperator; + if (location instanceof Pattern p && p.getEnclosingPattern() instanceof RecordPattern) { + problemId = IProblem.PatternTypeMismatch; + } else if (location instanceof InstanceOfExpression) { + problemId = IProblem.IncompatibleTypesInConditionalOperator; } this.handle( - IProblem.IncompatibleTypesInConditionalOperator, + problemId, new String[] {leftName, rightName }, new String[] {leftShortName, rightShortName }, - expression.sourceStart, - expression.sourceEnd); + location.sourceStart, + location.sourceEnd); } public void notCompatibleTypesErrorInForeach(Expression expression, TypeBinding leftType, TypeBinding rightType) { String leftName = new String(leftType.readableName()); @@ -8538,21 +8528,21 @@ public void typeCastError(CastExpression expression, TypeBinding leftType, TypeB expression.sourceStart, expression.sourceEnd); } -public void unsafeCastInInstanceof(Expression expression, TypeBinding leftType, TypeBinding rightType) { - String leftName = new String(leftType.readableName()); - String rightName = new String(rightType.readableName()); - String leftShortName = new String(leftType.shortReadableName()); - String rightShortName = new String(rightType.shortReadableName()); - if (leftShortName.equals(rightShortName)){ - leftShortName = leftName; - rightShortName = rightName; +public void unsafeCastInTestingContext(ASTNode location, TypeBinding castType, TypeBinding expressionType) { + String castName = new String(castType.readableName()); + String exprName = new String(expressionType.readableName()); + String castShortName = new String(castType.shortReadableName()); + String exprShortName = new String(expressionType.shortReadableName()); + if (castShortName.equals(exprShortName)){ + castShortName = castName; + exprShortName = exprName; } this.handle( IProblem.UnsafeCast, - new String[] { rightName, leftName }, - new String[] { rightShortName, leftShortName }, - expression.sourceStart, - expression.sourceEnd); + new String[] { exprName, castName }, + new String[] { exprShortName, castShortName }, + location.sourceStart, + location.sourceEnd); } public void typeCollidesWithEnclosingType(TypeDeclaration typeDecl) { String[] arguments = new String[] {new String(typeDecl.name)}; @@ -12404,14 +12394,6 @@ public void recordPatternSignatureMismatch(TypeBinding type, ASTNode element) { element.sourceStart, element.sourceEnd); } -public void incompatiblePatternType(ASTNode element, TypeBinding type, TypeBinding expected) { - this.handle( - IProblem.PatternTypeMismatch, - new String[] {new String(type.readableName()), new String(expected.readableName())}, - new String[] {new String(type.shortReadableName()), new String(expected.readableName())}, - element.sourceStart, - element.sourceEnd); -} public void cannotInferRecordPatternTypes(RecordPattern pattern) { String arguments [] = new String [] { pattern.toString() }; this.handle( diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java index 201d0d2374c..2e1d5eeaaae 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java @@ -646,4 +646,28 @@ public static void gain(String[] args) { + "A pattern variable with the same name is already defined in the statement\n" + "----------\n"); } + + public void testGH3074() { + runNegativeTest( + new String[] { + "Example.java", + """ + class Example { + private void foo(String x) { + if (x instanceof Example es) { + + } + } + } + """ + }, + """ + ---------- + 1. ERROR in Example.java (at line 3) + if (x instanceof Example es) { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Incompatible conditional operand types String and Example + ---------- + """); + } } \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching16Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching16Test.java index 636be4638d0..b68104b0d76 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching16Test.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching16Test.java @@ -2401,7 +2401,7 @@ public void testBug562392c() { "----------\n" + "1. ERROR in X.java (at line 4)\n" + " if (obj instanceof T t) {\n" + - " ^^^\n" + + " ^^^^^^^^^^^^^^^^^^\n" + "Type Object cannot be safely cast to T\n" + "----------\n", "X.java:4: error: Object cannot be safely cast to T\n" + @@ -2460,7 +2460,7 @@ public void testBug562392e() { "----------\n" + "1. ERROR in X.java (at line 4)\n" + " if (obj instanceof X p) {\n" + - " ^^^\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + "Type X cannot be safely cast to X\n" + "----------\n", "", diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java index 418e0baef13..f8a9e4ca84e 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java @@ -2302,6 +2302,28 @@ int foo4(int myInt) { """); } + public void testIncompatiblePrimitiveInInstanceof() { + runNegativeTest(new String[] { + "X.java", + """ + public class X { + void foo() { + if (this instanceof int i) + return; + } + } + """ + }, + """ + ---------- + 1. ERROR in X.java (at line 3) + if (this instanceof int i) + ^^^^^^^^^^^^^^^^^^^^^ + Incompatible conditional operand types X and int + ---------- + """); + } + // test from spec public void _testSpec001() { runConformTest(new String[] { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordPatternTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordPatternTest.java index aa3198e6fa4..1d5c01ba787 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordPatternTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordPatternTest.java @@ -299,12 +299,12 @@ public void test007() { "1. ERROR in X.java (at line 3)\n" + " if (r instanceof Rectangle(ColoredPoint(Point(String o1, String o2), Color c),\n" + " ^^^^^^^^^\n" + - "Record component with type int is not compatible with type java.lang.String\n" + + "Record component with type int is not compatible with type String\n" + "----------\n" + "2. ERROR in X.java (at line 3)\n" + " if (r instanceof Rectangle(ColoredPoint(Point(String o1, String o2), Color c),\n" + " ^^^^^^^^^\n" + - "Record component with type int is not compatible with type java.lang.String\n" + + "Record component with type int is not compatible with type String\n" + "----------\n"); } // Test that pattern types that don't match record component's types are reported @@ -1558,7 +1558,7 @@ public void test47() { + "public class X {\n" + " static void printGenericBoxString1(Box objectBox) {\n" + " if (objectBox instanceof Box(String s)) {\n" - + " System.out.println(s); // this one should report an unsafe cast error\n" + + " System.out.println(s);\n" + " }\n" + " }\n" + " public static void main(String[] args) {}\n" @@ -1568,8 +1568,8 @@ public void test47() { "----------\n" + "1. ERROR in X.java (at line 4)\n" + " if (objectBox instanceof Box(String s)) {\n" + - " ^^^^^^^^^\n" + - "Type Box cannot be safely cast to Box\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Incompatible conditional operand types Box and Box\n" + "----------\n"); } public void test48() { @@ -1958,7 +1958,7 @@ public void testRecordPatternTypeInference_009() { "1. ERROR in X.java (at line 7)\n" + " if (p instanceof R(String a)) {\n" + " ^^^^^^^^\n" + - "Record component with type capture#2-of ? extends I is not compatible with type java.lang.String\n" + + "Record component with type capture#2-of ? extends I is not compatible with type String\n" + "----------\n"); } public void testRecordPatternTypeInference_010() { @@ -2505,7 +2505,7 @@ public void testIssue1224_4() { "2. ERROR in X.java (at line 6)\n" + " case Record(Object o, StringBuilder s) -> {break;}\n" + " ^^^^^^^^^^^^^^^\n" + - "Record component with type String is not compatible with type java.lang.StringBuilder\n" + + "Record component with type String is not compatible with type StringBuilder\n" + "----------\n"); } public void testIssue1224_5() { @@ -4401,7 +4401,7 @@ public static void main(String[] args) { "2. ERROR in X.java (at line 10)\n" + " if (o instanceof R2(Short d)) {\n" + " ^^^^^^^\n" + - "Record component with type short is not compatible with type java.lang.Short\n" + + "Record component with type short is not compatible with type Short\n" + "----------\n" + "3. ERROR in X.java (at line 13)\n" + " if (o instanceof R2(int d)) {\n" + @@ -4686,4 +4686,54 @@ static void foo(Object o) { "Syntax error on tokens, delete these tokens\n" + "----------\n"); } + + public void testIssue3066() { + runNegativeTest(new String[] { + "X.java", + """ + public record X(int x) { + public static void main(String[] args) { + Object o = new Object(); + switch (o) { + case X(int x): + default: + } + } + } + """ + }, + """ + ---------- + 1. ERROR in X.java (at line 5) + case X(int x): + ^^^^^^^^^^^^^^^^ + Type Object cannot be safely cast to X + ---------- + """); + } + + public void testIssue3066_notApplicable() { + runNegativeTest(new String[] { + "X.java", + """ + public record X(int x) { + public static void main(String[] args) { + java.io.Serializable o = ""; + switch (o) { + case X(int x): + default: + } + } + } + """ + }, + """ + ---------- + 1. ERROR in X.java (at line 5) + case X(int x): + ^^^^^^^^ + Type mismatch: cannot convert from Serializable to X + ---------- + """); + } } \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java index a802d08ba5e..fa5d2105530 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java @@ -2650,11 +2650,6 @@ public void testBug573921_7() { " case List s: \n" + " ^^^^^^^^^^^^^^\n" + "Type Object cannot be safely cast to List\n" + - "----------\n" + - "3. ERROR in X.java (at line 9)\n" + - " case List s: \n" + - " ^^^^^^^^^^^^^^\n" + - "This case label is dominated by one of the preceding case labels\n" + "----------\n"); } public void testBug573921_8() { @@ -7335,11 +7330,6 @@ case WrapperRec(ExhaustiveSwitch.Data data) when data.name.isEmpty() -> { } + " case WrapperRec(ExhaustiveSwitch.Data data) when data.name.isEmpty() -> { }\n" + " ^^^^^^^^^^^^^^^^\n" + "ExhaustiveSwitch cannot be resolved to a type\n" - + "----------\n" - + "4. ERROR in X.java (at line 12)\n" - + " case WrapperRec(ExhaustiveSwitch.Data data) when data.name.isEmpty() -> { }\n" - + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" - + "Record component with type Data is not compatible with type ExhaustiveSwitch.Data\n" + "----------\n"); } // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1955