diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index baa2e099bc0..75fc8857b2f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -347,6 +347,9 @@ public class CallResolver { constraintSystem.addSubtypingConstraint(descriptor.getReturnType(), context.expectedType, ConstraintPosition.EXPECTED_TYPE_POSITION); + TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities + .makeConstantSubstitutor(resolvedCall.getCandidateDescriptor().getTypeParameters(), ConstraintSystemImpl.DONT_CARE); + // constraints for function literals // Value parameters for (Map.Entry entry : resolvedCall.getValueArguments().entrySet()) { @@ -356,8 +359,15 @@ public class CallResolver { for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) { if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue; + ConstraintSystem systemWithCurrentSubstitution = constraintSystem.copy(); addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintSystem.getCurrentSubstitutor(), - constraintSystem, context); + systemWithCurrentSubstitution, context); + if (systemWithCurrentSubstitution.hasContradiction() || systemWithCurrentSubstitution.hasErrorInConstrainingTypes()) { + addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem, context); + } + else { + constraintSystem = systemWithCurrentSubstitution; + } } } @@ -753,7 +763,7 @@ public class CallResolver { // Solution - if (!constraintsSystem.hasTypeConstructorMismatch() && !constraintsSystem.hasConflictingConstraints()) { //no contradiction + if (!constraintsSystem.hasContradiction()) { candidateCall.setHasUnknownTypeParameters(true); return SUCCESS; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java index e369e975945..c18be884f4e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java @@ -64,6 +64,11 @@ public interface ConstraintSystem { */ boolean isSuccessful(); + /** + * Return true if constraint system has no contradiction (it can be not successful because of the lack of information for a type variable). + */ + boolean hasContradiction(); + /** * Returns true if type constraints for some type variable are contradicting.

* @@ -133,4 +138,6 @@ public interface ConstraintSystem { */ @NotNull TypeSubstitutor getCurrentSubstitutor(); + + ConstraintSystem copy(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java index 0151e20b868..3ca82d3d353 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java @@ -105,6 +105,16 @@ public class ConstraintSystemImpl implements ConstraintSystem { typeParameterConstraints.put(typeVariable, new TypeConstraintsImpl(positionVariance)); } + @Override + @NotNull + public ConstraintSystem copy() { + ConstraintSystemImpl newConstraintSystem = new ConstraintSystemImpl(); + newConstraintSystem.typeParameterConstraints.putAll(typeParameterConstraints); + newConstraintSystem.errorConstraintPositions.addAll(errorConstraintPositions); + newConstraintSystem.hasErrorInConstrainingTypes = hasErrorInConstrainingTypes; + return newConstraintSystem; + } + @NotNull public ConstraintSystem replaceTypeVariables(@NotNull Function typeVariablesMap) { ConstraintSystemImpl newConstraintSystem = new ConstraintSystemImpl(); @@ -116,9 +126,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { assert newTypeParameter != null; newConstraintSystem.typeParameterConstraints.put(newTypeParameter, typeConstraints); } - for (ConstraintPosition constraintPosition : errorConstraintPositions) { - newConstraintSystem.errorConstraintPositions.add(constraintPosition); - } + newConstraintSystem.errorConstraintPositions.addAll(errorConstraintPositions); newConstraintSystem.hasErrorInConstrainingTypes = hasErrorInConstrainingTypes; return newConstraintSystem; } @@ -221,6 +229,11 @@ public class ConstraintSystemImpl implements ConstraintSystem { return !hasTypeConstructorMismatch() && !hasUnknownParameters() && !hasConflictingConstraints(); } + @Override + public boolean hasContradiction() { + return hasTypeConstructorMismatch() || hasConflictingConstraints(); + } + @Override public boolean hasConflictingConstraints() { for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) { diff --git a/compiler/testData/diagnostics/tests/inference/inferInFunctionLiterals.kt b/compiler/testData/diagnostics/tests/inference/inferInFunctionLiterals.kt new file mode 100644 index 00000000000..a677ec097c3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/inferInFunctionLiterals.kt @@ -0,0 +1,12 @@ +package n + +//+JDK +import java.util.* + +fun expected(t: T, f: () -> T) : T = t + +fun test(arrayList: ArrayList, list: List) { + val t = expected(arrayList, { list.reverse() }) +} + +fun List.reverse() : List = this \ No newline at end of file