diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index 13ba8ac4f11..4bfc6eb6746 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; +import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsUtil; import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.constants.ConstantUtils; import org.jetbrains.jet.lang.resolve.name.Name; @@ -193,11 +194,7 @@ public class CallExpressionResolver { if (!results.isNothing()) { checkSuper(call.getExplicitReceiver(), results, context.trace, callExpression); result[0] = true; - if (results.isSingleResult() && context.resolveMode == ResolveMode.TOP_LEVEL_CALL) { - if (!CallResolverUtil.hasInferredReturnType(results.getResultingCall())) return null; - } - - return results.isSingleResult() ? results.getResultingCall() : null; + return OverloadResolutionResultsUtil.getResultingCall(results, context.resolveMode); } result[0] = false; return null; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsUtil.java index 8d60da59e99..6a14e6d6e48 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsUtil.java @@ -20,6 +20,9 @@ import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; +import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.types.JetType; @@ -35,10 +38,24 @@ public class OverloadResolutionResultsUtil { } @Nullable - public static JetType getResultType(OverloadResolutionResults results) { - if (results.isSuccess()) { - return results.getResultingDescriptor().getReturnType(); + public static JetType getResultingType( + @NotNull OverloadResolutionResults results, + @NotNull ResolveMode resolveMode + ) { + ResolvedCall resultingCall = getResultingCall((OverloadResolutionResultsImpl) results, resolveMode); + return resultingCall != null ? resultingCall.getResultingDescriptor().getReturnType() : null; + } + + @Nullable + public static ResolvedCallWithTrace getResultingCall( + @NotNull OverloadResolutionResultsImpl results, + @NotNull ResolveMode resolveMode + ) { + if (results.isSingleResult() && resolveMode == ResolveMode.TOP_LEVEL_CALL) { + if (!CallResolverUtil.hasInferredReturnType(results.getResultingCall())) { + return null; + } } - return null; + return results.isSingleResult() ? results.getResultingCall() : null; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 980dcbcd986..a1e7d9b3753 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -36,8 +36,6 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory; import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability; import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode; import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition; -import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCache; -import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; @@ -1055,7 +1053,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), operationSign, OperatorConventions.CONTAINS); - JetType containsType = OverloadResolutionResultsUtil.getResultType(resolutionResult); + JetType containsType = OverloadResolutionResultsUtil.getResultingType(resolutionResult, context.resolveMode); ensureBooleanResult(operationSign, OperatorConventions.CONTAINS, containsType, context); if (left != null) { @@ -1165,7 +1163,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { dataFlowInfo = facade.getTypeInfo(right, contextWithDataFlow).getDataFlowInfo(); } - return JetTypeInfo.create(OverloadResolutionResultsUtil.getResultType(resolutionResults), dataFlowInfo); + return JetTypeInfo.create(OverloadResolutionResultsUtil.getResultingType(resolutionResults, context.resolveMode), dataFlowInfo); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java index 2682f844498..537a9766538 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java @@ -240,14 +240,15 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito TemporaryBindingTrace assignmentOperationTrace = TemporaryBindingTrace.create(context.trace, "trace to check assignment operation like '+=' for", expression); OverloadResolutionResults assignmentOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall( scope, name, context.replaceBindingTrace(assignmentOperationTrace).replaceResolutionResultsCache(), expression, receiver); - JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultType(assignmentOperationDescriptors); + JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultingType(assignmentOperationDescriptors, + context.resolveMode); // Check for '+' Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType)); TemporaryBindingTrace binaryOperationTrace = TemporaryBindingTrace.create(context.trace, "trace to check binary operation like '+' for", expression); OverloadResolutionResults binaryOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall( scope, counterpartName, context.replaceBindingTrace(binaryOperationTrace).replaceResolutionResultsCache(), expression, receiver); - JetType binaryOperationType = OverloadResolutionResultsUtil.getResultType(binaryOperationDescriptors); + JetType binaryOperationType = OverloadResolutionResultsUtil.getResultingType(binaryOperationDescriptors, context.resolveMode); JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType; if (assignmentOperationType != null && binaryOperationType != null) { diff --git a/compiler/testData/diagnostics/tests/inference/nestedCalls/inferenceForNestedBinaryCall.kt b/compiler/testData/diagnostics/tests/inference/nestedCalls/inferenceForNestedBinaryCall.kt new file mode 100644 index 00000000000..560f9ad66bf --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nestedCalls/inferenceForNestedBinaryCall.kt @@ -0,0 +1,10 @@ +package aaa + +fun T.foo(t: T) = t + +fun id(t: T) = t + +fun a() { + val i = id(2 foo 3) + i : Int // i shouldn't be resolved to error element +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index eb2cdc5c7a0..d6e38cf097a 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2846,6 +2846,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedForVariableAsFunctionCall.kt"); } + @TestMetadata("inferenceForNestedBinaryCall.kt") + public void testInferenceForNestedBinaryCall() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/nestedCalls/inferenceForNestedBinaryCall.kt"); + } + @TestMetadata("kt3395.kt") public void testKt3395() throws Exception { doTest("compiler/testData/diagnostics/tests/inference/nestedCalls/kt3395.kt");