Bug 506016: [1.8][inference] Replace ad-hoc tweaks with a precise
emulation of javac re JDK-8153748
- amendment after more details via email
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 0df7efd..6432e23 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
@@ -448,7 +448,15 @@
}
if (this.right.isFunctionalInterface(context.scope)) {
LambdaExpression lambda = (LambdaExpression) this.left;
- MethodBinding sam = this.right.getSingleAbstractMethod(context.scope, true); // TODO derive with target type?
+ ReferenceBinding targetType = (ReferenceBinding) this.right;
+ ParameterizedTypeBinding withWildCards = InferenceContext18.parameterizedWithWildcard(targetType);
+ if (withWildCards != null) {
+ targetType = ConstraintExpressionFormula.findGroundTargetType(context, lambda.enclosingScope, lambda, withWildCards);
+ }
+ if (targetType == null) {
+ return EMPTY_VARIABLE_LIST;
+ }
+ MethodBinding sam = targetType.getSingleAbstractMethod(context.scope, true);
final Set<InferenceVariable> variables = new HashSet<>();
if (lambda.argumentsTypeElided()) {
// i)
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 6a5f4c0..dab5fb6 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
@@ -482,50 +482,34 @@
}
private ReductionResult addJDK_8153748ConstraintsFromExpression(Expression argument, TypeBinding parameter, MethodBinding method) throws InferenceFailureException {
- if (argument instanceof LambdaExpression) {
- return addJDK_8153748ConstraintsFromLambda((LambdaExpression) argument, parameter, method);
- } else if (argument instanceof Invocation) {
+ if (argument instanceof FunctionalExpression) {
+ return addJDK_8153748ConstraintsFromFunctionalExpr((FunctionalExpression) argument, parameter, method);
+ } else if (argument instanceof Invocation && argument.isPolyExpression(method)) {
Invocation invocation = (Invocation) argument;
Expression[] innerArgs = invocation.arguments();
MethodBinding innerMethod = invocation.binding();
if (innerMethod != null && innerMethod.isValidBinding()) {
return addJDK_8153748ConstraintsFromInvocation(innerArgs, innerMethod.original());
}
+ } else if (argument instanceof ConditionalExpression) {
+ ConditionalExpression ce = (ConditionalExpression) argument;
+ if (addJDK_8153748ConstraintsFromExpression(ce.valueIfTrue, parameter, method) == ReductionResult.FALSE)
+ return ReductionResult.FALSE;
+ return addJDK_8153748ConstraintsFromExpression(ce.valueIfFalse, parameter, method);
}
return null;
}
- private ReductionResult addJDK_8153748ConstraintsFromLambda(LambdaExpression lambda, TypeBinding targetType, MethodBinding method) throws InferenceFailureException {
- if (!lambda.isPertinentToApplicability(targetType, method)) {
-// -- simple version:
-// lambda = lambda.resolveExpressionExpecting(targetType, this.scope, this);
-// if (lambda != null && lambda.descriptor != null && lambda.descriptor.isValidBinding()) {
-// MethodBinding sam = lambda.descriptor.declaringClass.getSingleAbstractMethod(this.scope, true);
-// if (sam != null && sam.isValidBinding()) {
-// -- more sophisticated version:
- BlockScope skope = lambda.enclosingScope;
- if (targetType.isFunctionalInterface(skope)) { // could be an inference variable.
- ReferenceBinding t = (ReferenceBinding) targetType;
- ParameterizedTypeBinding withWildCards = InferenceContext18.parameterizedWithWildcard(t);
- if (withWildCards != null) {
- t = ConstraintExpressionFormula.findGroundTargetType(this, skope, lambda, withWildCards);
- }
- MethodBinding functionType;
- if (t != null
- && (functionType = t.getSingleAbstractMethod(skope, true)) != null
- && (lambda = lambda.resolveExpressionExpecting(t, this.scope, this)) != null)
- {
-// --
- for (TypeBinding samParam : functionType.parameters) {
- if (!samParam.isProperType(true))
-// if (samParam instanceof InferenceVariable)
- return null;
- }
- ConstraintFormula newConstraint = new ConstraintExpressionFormula(lambda, targetType, ReductionResult.COMPATIBLE, ARGUMENT_CONSTRAINTS_ARE_SOFT);
- if (!reduceAndIncorporate(newConstraint))
- return ReductionResult.FALSE;
- return ReductionResult.TRUE;
- }
+ 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))
+ return ReductionResult.FALSE;
+ newConstraint = new ConstraintExceptionFormula(functionalExpr, targetType); // ??
+ if (!reduceAndIncorporate(newConstraint))
+ return ReductionResult.FALSE;
+ return ReductionResult.TRUE;
}
}
return null;