Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2016-10-20 18:00:12 +0000
committerStephan Herrmann2016-10-20 21:13:19 +0000
commit2bdcd6f13b13ec00844affdb10db3ef2ded868da (patch)
tree244b2ccd1445ca93b73baa11c0395e2c5bdf6dbf
parent92a3e8d9e72ad7550c19af076fad5fed3497b8b7 (diff)
downloadeclipse.jdt.core-I20161024-1000.tar.gz
eclipse.jdt.core-I20161024-1000.tar.xz
eclipse.jdt.core-I20161024-1000.zip
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java56
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java97
4 files changed, 137 insertions, 22 deletions
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 c82d1c27b3..5b965903c4 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
@@ -7253,4 +7253,60 @@ public void testBug502568() {
"}\n"
});
}
+public void testBug499725() {
+ runConformTest(
+ new String[] {
+ "Try22.java",
+ "import java.rmi.RemoteException;\n" +
+ "import java.util.Arrays;\n" +
+ "import java.util.Collection;\n" +
+ "import java.util.Collections;\n" +
+ "import java.util.List;\n" +
+ "import java.util.function.Function;\n" +
+ "import java.util.stream.Collectors;\n" +
+ "\n" +
+ "\n" +
+ "public class Try22 {\n" +
+ " public static class RemoteExceptionWrapper {\n" +
+ " @FunctionalInterface\n" +
+ " public static interface FunctionRemote<T, R> {\n" +
+ " R apply(T t) throws RemoteException;\n" +
+ " }\n" +
+ " \n" +
+ " public static <T, R> Function<T, R> wrapFunction(FunctionRemote<T, R> f) {\n" +
+ " return x -> {\n" +
+ " try {\n" +
+ " return f.apply(x);\n" +
+ " }\n" +
+ " catch(RemoteException e) {\n" +
+ " throw new RuntimeException(e);\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ "\n" +
+ " private static class ThrowingThingy {\n" +
+ " public Collection<String> listStuff(String in) throws RemoteException {\n" +
+ " return Collections.emptyList();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " \n" +
+ " public static void main(String[] args) {\n" +
+ " List<String> stagedNodes = Arrays.asList(\"a\", \"b\", \"c\");\n" +
+ " ThrowingThingy remoteThing = new ThrowingThingy(); // simulation of a rmi remote, hence the exceptio\n" +
+ " \n" +
+ " List<String> resultingStuff = stagedNodes.stream()\n" +
+ " .flatMap(RemoteExceptionWrapper.wrapFunction(\n" +
+ " node -> remoteThing.listStuff(node) // HERE\n" +
+ " .stream()\n" +
+ " .map(sub -> node + \"/\" + sub)))\n" +
+ " .collect(Collectors.toList());\n" +
+ " \n" +
+ " System.out.println(resultingStuff);\n" +
+ " }\n" +
+ "}\n"
+ });
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index 799b42e193..75eb903342 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -8576,7 +8576,7 @@ public void test428177() {
"5. ERROR in X.java (at line 38)\n" +
" return stream.collect(Collectors.toList()); // NO ERROR\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Type mismatch: cannot convert from List<capture#18-of ? extends String> to Stream<String>\n" +
+ "Type mismatch: cannot convert from List<capture#19-of ? extends String> to Stream<String>\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=428795, - [1.8]Internal compiler error: java.lang.NullPointerException at org.eclipse.jdt.internal.compiler.ast.MessageSend.analyseCode
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
index 6432e23c1e..f903676f4c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
@@ -121,7 +121,7 @@ class ConstraintExpressionFormula extends ConstraintFormula {
inferInvocationApplicability(inferenceContext, method, argumentTypes, isDiamond, inferenceContext.inferenceKind);
// b2 has been lifted, inferring poly invocation type amounts to lifting b3.
}
- if (!inferPolyInvocationType(inferenceContext, invocation, this.right, method))
+ if (!inferenceContext.computeB3(invocation, this.right, method))
return FALSE;
return null; // already incorporated
} finally {
@@ -296,7 +296,7 @@ class ConstraintExpressionFormula extends ConstraintFormula {
InferenceContext18 innerContext = reference.getInferenceContext((ParameterizedMethodBinding) compileTimeDecl);
int innerInferenceKind = determineInferenceKind(compileTimeDecl, argumentTypes, innerContext);
inferInvocationApplicability(inferenceContext, original, argumentTypes, original.isConstructor()/*mimic a diamond?*/, innerInferenceKind);
- if (!inferPolyInvocationType(inferenceContext, reference, r, original))
+ if (!inferenceContext.computeB3(reference, r, original))
return FALSE;
return null; // already incorporated
} catch (InferenceFailureException e) {
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 0710d9b904..07851ae047 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
@@ -159,6 +159,10 @@ public class InferenceContext18 {
ReferenceBinding object; // java.lang.Object
public BoundSet b2;
private BoundSet b3;
+ /** Not per JLS: inbox for emulation of how javac passes type bounds from inner to outer */
+ private BoundSet innerInbox;
+ /** Not per JLS: signal when current is ready to directly merge all bounds from inner. */
+ private boolean directlyAcceptingInnerBounds = false;
// InferenceVariable interning:
private InferenceVariable[] internedVariables;
@@ -394,6 +398,19 @@ public class InferenceContext18 {
ConstraintExpressionFormula.inferInvocationApplicability(this, method, arguments, isDiamond, this.inferenceKind);
}
+ /** Perform steps from JLS 18.5.2. needed for computing the bound set B3. */
+ boolean computeB3(InvocationSite invocationSite, TypeBinding targetType, MethodBinding method)
+ throws InferenceFailureException
+ {
+ boolean result = ConstraintExpressionFormula.inferPolyInvocationType(this, invocationSite, targetType, method);
+ if (result) {
+ mergeInnerBounds();
+ if (this.b3 == null)
+ this.b3 = this.currentBounds.copy();
+ }
+ return result;
+ }
+
/** JLS 18.5.2 Invocation Type Inference
*/
public BoundSet inferInvocationType(TypeBinding expectedType, InvocationSite invocationSite, MethodBinding method) throws InferenceFailureException
@@ -412,11 +429,13 @@ public class InferenceContext18 {
&& ((Expression)invocationSite).isPolyExpression(method))
{
// 3. bullet: special treatment for poly expressions
- if (!ConstraintExpressionFormula.inferPolyInvocationType(this, invocationSite, expectedType, method)) {
+ if (!computeB3(invocationSite, expectedType, method)) {
return null;
}
+ } else {
+ mergeInnerBounds();
+ this.b3 = this.currentBounds.copy();
}
- this.b3 = this.currentBounds.copy();
if (SHOULD_WORKAROUND_BUG_JDK_8153748) { // "before 18.5.2", but should not spill into b3 ... (heuristically)
ReductionResult jdk8153748result = addJDK_8153748ConstraintsFromInvocation(this.invocationArguments, method);
@@ -425,9 +444,12 @@ public class InferenceContext18 {
}
}
+ pushBoundsToOuter();
+ this.directlyAcceptingInnerBounds = true;
+
// 4. bullet: assemble C:
Set<ConstraintFormula> c = new HashSet<ConstraintFormula>();
- if (!addConstraintsToC(this.invocationArguments, c, method, this.inferenceKind, false, invocationSite))
+ if (!addConstraintsToC(this.invocationArguments, c, method, this.inferenceKind, invocationSite))
return null;
// 5. bullet: determine B4 from C
List<Set<InferenceVariable>> components = this.currentBounds.computeConnectedComponents(this.inferenceVariables);
@@ -480,6 +502,42 @@ public class InferenceContext18 {
}
}
+ // --- not per JLS: emulate how javac passes type bounds from inner to outer: ---
+ /** Not per JLS: push current bounds to outer inference if outer is ready for it. */
+ private void pushBoundsToOuter() {
+ InferenceContext18 outer = this.outerContext;
+ if (outer != null && outer.stepCompleted >= APPLICABILITY_INFERRED) {
+ if (outer.directlyAcceptingInnerBounds) {
+ outer.currentBounds.addBounds(this.currentBounds, this.environment);
+ } else if (outer.innerInbox == null) {
+ outer.innerInbox = this.currentBounds.copy();
+ } else {
+ outer.innerInbox.addBounds(this.currentBounds, this.environment);
+ }
+ }
+ }
+ /** Not JLS: merge pending bounds of inner inference into current. */
+ private void mergeInnerBounds() {
+ if (this.innerInbox != null) {
+ this.currentBounds.addBounds(this.innerInbox, this.environment);
+ this.innerInbox = null;
+ }
+ }
+
+ interface InferenceOperation {
+ boolean perform() throws InferenceFailureException;
+ }
+ /** Not per JLS: if operation succeeds merge new bounds from inner into current. */
+ private boolean collectingInnerBounds(InferenceOperation operation) throws InferenceFailureException {
+ boolean result = operation.perform();
+ if (result)
+ mergeInnerBounds();
+ else
+ this.innerInbox = null;
+ return result;
+ }
+ // ---
+
private ReductionResult addJDK_8153748ConstraintsFromInvocation(Expression[] arguments, MethodBinding method) throws InferenceFailureException {
// not per JLS, trying to mimic javac behavior
boolean constraintAdded = false;
@@ -519,12 +577,12 @@ public class InferenceContext18 {
private ReductionResult addJDK_8153748ConstraintsFromFunctionalExpr(FunctionalExpression functionalExpr, TypeBinding targetType, MethodBinding method) throws InferenceFailureException {
if (!functionalExpr.isPertinentToApplicability(targetType, method)) {
- ConstraintFormula newConstraint = new ConstraintExpressionFormula(functionalExpr, targetType, ReductionResult.COMPATIBLE, ARGUMENT_CONSTRAINTS_ARE_SOFT);
- if (newConstraint.inputVariables(this).isEmpty()) { // input variable would signal: not ready for inference
- if (!reduceAndIncorporate(newConstraint))
+ ConstraintFormula exprConstraint = new ConstraintExpressionFormula(functionalExpr, targetType, ReductionResult.COMPATIBLE, ARGUMENT_CONSTRAINTS_ARE_SOFT);
+ if (collectingInnerBounds(() -> exprConstraint.inputVariables(this).isEmpty())) { // input variable would signal: not ready for inference
+ if (!collectingInnerBounds(() -> reduceAndIncorporate(exprConstraint)))
return ReductionResult.FALSE;
- newConstraint = new ConstraintExceptionFormula(functionalExpr, targetType); // ??
- if (!reduceAndIncorporate(newConstraint))
+ ConstraintFormula excConstraint = new ConstraintExceptionFormula(functionalExpr, targetType); // ??
+ if (!collectingInnerBounds(() -> reduceAndIncorporate(excConstraint)))
return ReductionResult.FALSE;
return ReductionResult.TRUE;
}
@@ -532,7 +590,7 @@ public class InferenceContext18 {
return null;
}
- private boolean addConstraintsToC(Expression[] exprs, Set<ConstraintFormula> c, MethodBinding method, int inferenceKindForMethod, boolean interleaved, InvocationSite site)
+ private boolean addConstraintsToC(Expression[] exprs, Set<ConstraintFormula> c, MethodBinding method, int inferenceKindForMethod, InvocationSite site)
throws InferenceFailureException
{
TypeBinding[] fs;
@@ -559,14 +617,14 @@ public class InferenceContext18 {
TypeBinding fsi = fs[Math.min(i, p-1)];
InferenceSubstitution inferenceSubstitution = new InferenceSubstitution(this.environment, this.inferenceVariables, site);
TypeBinding substF = inferenceSubstitution.substitute(inferenceSubstitution,fsi);
- if (!addConstraintsToC_OneExpr(exprs[i], c, fsi, substF, method, interleaved))
+ if (!addConstraintsToC_OneExpr(exprs[i], c, fsi, substF, method))
return false;
}
}
return true;
}
- private boolean addConstraintsToC_OneExpr(Expression expri, Set<ConstraintFormula> c, TypeBinding fsi, TypeBinding substF, MethodBinding method, boolean interleaved)
+ private boolean addConstraintsToC_OneExpr(Expression expri, Set<ConstraintFormula> c, TypeBinding fsi, TypeBinding substF, MethodBinding method)
throws InferenceFailureException
{
// -- not per JLS, emulate javac behavior:
@@ -595,7 +653,7 @@ public class InferenceContext18 {
Expression[] resultExpressions = lambda.resultExpressions();
for (int i = 0, length = resultExpressions == null ? 0 : resultExpressions.length; i < length; i++) {
Expression resultExpression = resultExpressions[i];
- if (!addConstraintsToC_OneExpr(resultExpression, c, r.original(), r, method, true))
+ if (!addConstraintsToC_OneExpr(resultExpression, c, r.original(), r, method))
return false;
}
}
@@ -619,22 +677,22 @@ public class InferenceContext18 {
if (innerMethod instanceof ParameterizedGenericMethodBinding)
innerContext = invocation.getInferenceContext((ParameterizedGenericMethodBinding) innerMethod);
- if (interleaved && innerContext != null) {
+ if (innerContext != null) {
MethodBinding shallowMethod = innerMethod.shallowOriginal();
innerContext.outerContext = this;
if (innerContext.stepCompleted < InferenceContext18.APPLICABILITY_INFERRED) // shouldn't happen, but let's play safe
innerContext.inferInvocationApplicability(shallowMethod, argumentTypes, shallowMethod.isConstructor());
- if (!ConstraintExpressionFormula.inferPolyInvocationType(innerContext, invocation, substF, shallowMethod))
+ if (!innerContext.computeB3(invocation, substF, shallowMethod))
return false;
- return innerContext.addConstraintsToC(arguments, c, innerMethod.genericMethod(), innerContext.inferenceKind, interleaved, invocation);
+ return innerContext.addConstraintsToC(arguments, c, innerMethod.genericMethod(), innerContext.inferenceKind, invocation);
} else {
int applicabilityKind = getInferenceKind(innerMethod, argumentTypes);
- return this.addConstraintsToC(arguments, c, innerMethod.genericMethod(), applicabilityKind, interleaved, invocation);
+ return this.addConstraintsToC(arguments, c, innerMethod.genericMethod(), applicabilityKind, invocation);
}
} else if (expri instanceof ConditionalExpression) {
ConditionalExpression ce = (ConditionalExpression) expri;
- return addConstraintsToC_OneExpr(ce.valueIfTrue, c, fsi, substF, method, interleaved)
- && addConstraintsToC_OneExpr(ce.valueIfFalse, c, fsi, substF, method, interleaved);
+ return addConstraintsToC_OneExpr(ce.valueIfTrue, c, fsi, substF, method)
+ && addConstraintsToC_OneExpr(ce.valueIfFalse, c, fsi, substF, method);
}
return true;
}
@@ -1504,7 +1562,8 @@ public class InferenceContext18 {
this.currentBounds.addBounds(innerCtx.b2, this.environment);
this.inferenceVariables = innerCtx.inferenceVariables;
this.inferenceKind = innerCtx.inferenceKind;
- innerCtx.outerContext = this;
+ if (!isSameSite(innerCtx.currentInvocation, this.currentInvocation))
+ innerCtx.outerContext = this;
this.usesUncheckedConversion = innerCtx.usesUncheckedConversion;
for (InferenceVariable variable : this.inferenceVariables)
if (!isInterned(variable))

Back to the top