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) {