Fix for Bug 430296 - [1.8] broken code triggers stack overflow in
CaptureBinding18.isCompatibleWith
Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index ae7d4a3..45f3117 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -2868,4 +2868,40 @@
"----------\n",
null, true, customOptions);
}
+public void testBug430296() {
+ runNegativeTest(
+ new String[] {
+ "AnnotationCollector.java",
+ "import java.lang.annotation.*;\n" +
+ "import java.util.*;\n" +
+ "import java.util.function.*;\n" +
+ "import java.util.stream.*;\n" +
+ "\n" +
+ "public abstract class AnnotationCollector {\n" +
+ " \n" +
+ " Map<String, Person> test2(Stream<Person> persons) {\n" +
+ " return persons.collect(Collectors.toMap((Person p) -> p.getLastName(),\n" +
+ " Function::identity,\n" +
+ " (p1, p2) -> p1));\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "class Person {\n" +
+ " String getLastName() { return \"\"; }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in AnnotationCollector.java (at line 9)\n" +
+ " return persons.collect(Collectors.toMap((Person p) -> p.getLastName(),\n" +
+ " Function::identity,\n" +
+ " (p1, p2) -> p1));\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Type mismatch: cannot convert from Map<String,Object> to Map<String,Person>\n" +
+ "----------\n" +
+ "2. ERROR in AnnotationCollector.java (at line 10)\n" +
+ " Function::identity,\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "The type Function does not define identity(Person) that is applicable here\n" +
+ "----------\n");
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
index 3e31d70..cc698a9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
@@ -124,13 +124,20 @@
}
public boolean isCompatibleWith(TypeBinding otherType, Scope captureScope) {
- if (this.upperBounds != null) {
- for (int i = 0; i < this.upperBounds.length; i++) {
- if (this.upperBounds[i].isCompatibleWith(otherType, captureScope))
- return true;
+ if (this.inRecursiveFunction)
+ return true;
+ this.inRecursiveFunction = true;
+ try {
+ if (this.upperBounds != null) {
+ for (int i = 0; i < this.upperBounds.length; i++) {
+ if (this.upperBounds[i].isCompatibleWith(otherType, captureScope))
+ return true;
+ }
}
+ return super.isCompatibleWith(otherType, captureScope);
+ } finally {
+ this.inRecursiveFunction = false;
}
- return super.isCompatibleWith(otherType, captureScope);
}
public TypeBinding findSuperTypeOriginatingFrom(TypeBinding otherType) {