Bug 435767 - [1.8][inference] Problem in inferrence of type : The method
in the type is not applicable for the arguments (Object)
- negative regression test
- some optimizations found during debugging
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 2666314..3f59b14 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
@@ -3335,4 +3335,59 @@
"The method collect(Collector<? super Object,A,R>) in the type Stream<Object> is not applicable for the arguments (Collector<Map.Entry<String,String>,capture#1-of ?,Map<String,List<String>>>)\n" +
"----------\n");
}
+public void testBug435767() {
+ runNegativeTest(
+ new String[] {
+ "DummyClass.java",
+ "import java.util.*;\n" +
+ "import java.util.function.*;\n" +
+ "import java.util.stream.*;\n" +
+ "public class DummyClass {\n" +
+ "\n" +
+ " public void method() {\n" +
+ "\n" +
+ " // Cases where there is no error\n" +
+ " final Supplier<Set<String>> suppliers = this.memoize(() -> new HashSet<>());\n" +
+ "\n" +
+ " final Supplier<Map<Object, Object>> noMemoize = () -> suppliers.get().stream()\n" +
+ " .filter(path -> path.startsWith(\"\"))\n" +
+ " .collect(Collectors.toMap(path -> this.getKey(path), path -> this.getValue(path)));\n" +
+ "\n" +
+ " // Case where there is errors.\n" +
+ " final Supplier<Map<Object, Object>> memoize = this.memoize(() -> suppliers.get().stream()\n" +
+ " .filter(path -> path.startsWith(\"\"))\n" +
+ " .collect(Collectors.toMap(path -> this.getKey(path), path -> this.getValue(path))));\n" +
+ "\n" +
+ " // Error message are : Description\n" +
+ " // Resource Path Location Type\n" +
+ " // The method getKey(String) in the type DummyClass is not applicable for the arguments (Object) DummyClass.java line 23 Java Problem\n" +
+ " // The method getValue(String) in the type DummyClass is not applicable for the arguments (Object) DummyClass.java line 23 Java Problem\n" +
+ "\n" +
+ " }\n" +
+ "\n" +
+ " private <T> Supplier<T> memoize(final Supplier<T> delegate) {\n" +
+ " return delegate;\n" +
+ " }\n" +
+ "\n" +
+ " private Object getKey(final String path) {\n" +
+ " return path;\n" +
+ " }\n" +
+ "\n" +
+ " private Object getValue(final String path) {\n" +
+ " return path;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in DummyClass.java (at line 18)\n" +
+ " .collect(Collectors.toMap(path -> this.getKey(path), path -> this.getValue(path))));\n" +
+ " ^^^^^^\n" +
+ "The method getKey(String) in the type DummyClass is not applicable for the arguments (Object)\n" +
+ "----------\n" +
+ "2. ERROR in DummyClass.java (at line 18)\n" +
+ " .collect(Collectors.toMap(path -> this.getKey(path), path -> this.getValue(path))));\n" +
+ " ^^^^^^^^\n" +
+ "The method getValue(String) in the type DummyClass is not applicable for the arguments (Object)\n" +
+ "----------\n");
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
index 0171a8a..b39e57b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
@@ -330,22 +330,26 @@
public InferenceVariable[] addTypeVariableSubstitutions(TypeBinding[] typeVariables) {
int len2 = typeVariables.length;
InferenceVariable[] newVariables = new InferenceVariable[len2];
+ InferenceVariable[] toAdd = new InferenceVariable[len2];
+ int numToAdd = 0;
for (int i = 0; i < typeVariables.length; i++) {
if (typeVariables[i] instanceof InferenceVariable)
newVariables[i] = (InferenceVariable) typeVariables[i]; // prevent double substitution of an already-substituted inferenceVariable
else
- newVariables[i] = new InferenceVariable(typeVariables[i], this.variableCount++, this.currentInvocation, this.environment, this.object);
+ toAdd[numToAdd++] =
+ newVariables[i] = new InferenceVariable(typeVariables[i], this.variableCount++, this.currentInvocation, this.environment, this.object);
}
-
- int start = 0;
- if (this.inferenceVariables != null) {
- int len1 = this.inferenceVariables.length;
- System.arraycopy(this.inferenceVariables, 0, this.inferenceVariables = new InferenceVariable[len1+len2], 0, len1);
- start = len1;
- } else {
- this.inferenceVariables = new InferenceVariable[len2];
+ if (numToAdd > 0) {
+ int start = 0;
+ if (this.inferenceVariables != null) {
+ int len1 = this.inferenceVariables.length;
+ System.arraycopy(this.inferenceVariables, 0, this.inferenceVariables = new InferenceVariable[len1+numToAdd], 0, len1);
+ start = len1;
+ } else {
+ this.inferenceVariables = new InferenceVariable[numToAdd];
+ }
+ System.arraycopy(toAdd, 0, this.inferenceVariables, start, numToAdd);
}
- System.arraycopy(newVariables, 0, this.inferenceVariables, start, len2);
return newVariables;
}
@@ -413,7 +417,8 @@
}
InferenceVariable[] variablesArray = allInputs.toArray(new InferenceVariable[allInputs.size()]);
// ... is resolved
- this.currentBounds.incorporate(this);
+ if (!this.currentBounds.incorporate(this))
+ return null;
BoundSet solution = resolve(variablesArray);
// in rare cases resolving just one set of variables doesn't suffice,
// don't bother with finding the necessary superset, just resolve all: