diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 0384b8a32cd..e6f25e52d8a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -303,36 +303,6 @@ public class JetControlFlowProcessor { } builder.bindLabel(afterElvis); } - else if (operationType == JetTokens.EQEQ || operationType == JetTokens.EXCLEQ) { - // Equals is resolved on a fake argument, to ensure "Any?" in the signature, so we have to read the right argument manually - @SuppressWarnings("unchecked") - ResolvedCall resolvedCall = (ResolvedCall) getResolvedCall(operationReference); - if (resolvedCall != null && !resolvedCall.getValueArguments().isEmpty() && right != null) { - ResolvedCallImpl fakeCall = ResolvedCallImpl.create( - ResolutionCandidate.create( - resolvedCall.getCandidateDescriptor(), - resolvedCall.getThisObject(), - resolvedCall.getReceiverArgument(), - resolvedCall.getExplicitReceiverKind(), - resolvedCall.isSafeCall() - ), - new DelegatingBindingTrace(BindingContext.EMPTY, "Fake call for =="), - TracingStrategy.EMPTY, - MutableDataFlowInfoForArguments.WITHOUT_ARGUMENTS_CHECK - ); - - ValueParameterDescriptor parameterDescriptor = resolvedCall.getValueArguments().keySet().iterator().next(); - fakeCall.recordValueArgument( - parameterDescriptor, - new ExpressionValueArgument(CallMaker.makeValueArgument(right)) - ); - fakeCall.setStatusToSuccess(); - generateCall(expression, fakeCall); - } - else { - generateBothArguments(expression); - } - } else { if (!generateCall(operationReference)) { generateBothArguments(expression); 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 8b5fc58b53d..92beb936815 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 @@ -61,6 +61,7 @@ import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.util.slicedmap.WritableSlice; import org.jetbrains.jet.utils.ThrowingList; import java.util.Collection; @@ -867,9 +868,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ExpressionTypingContext context, JetSimpleNameExpression operationSign, JetExpression left, - JetExpression right + final JetExpression right ) { - JetTypeInfo result;DataFlowInfo dataFlowInfo = context.dataFlowInfo; + DataFlowInfo dataFlowInfo = context.dataFlowInfo; if (right != null && left != null) { ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context); @@ -883,16 +884,21 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { traceInterpretingRightAsNullableAny.record(EXPRESSION_TYPE, right, KotlinBuiltIns.getInstance().getNullableAnyType()); traceInterpretingRightAsNullableAny.record(PROCESSED, right); + Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right)); + ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny); OverloadResolutionResults resolutionResults = - resolveFakeCall(receiver, context.replaceBindingTrace(traceInterpretingRightAsNullableAny), - Collections.singletonList(right), OperatorConventions.EQUALS); + newContext.resolveCallWithGivenName(call, operationSign, OperatorConventions.EQUALS); + traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() { + @Override + public boolean accept(@Nullable WritableSlice slice, Object key) { + return !(key == right && (slice == EXPRESSION_TYPE || slice == PROCESSED)); + } + }, true); dataFlowInfo = facade.getTypeInfo(right, contextWithDataFlow).getDataFlowInfo(); if (resolutionResults.isSuccess()) { FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor(); - context.trace.record(REFERENCE_TARGET, operationSign, equals); - context.trace.record(RESOLVED_CALL, operationSign, resolutionResults.getResultingCall()); if (ensureBooleanResult(operationSign, OperatorConventions.EQUALS, equals.getReturnType(), context)) { ensureNonemptyIntersectionOfOperandTypes(expression, context); } @@ -906,8 +912,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } } } - result = JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo); - return result; + return JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo); } @NotNull diff --git a/compiler/testData/cfg/FinallyTestCopy.instructions b/compiler/testData/cfg/FinallyTestCopy.instructions index 15891186723..bdd12d67312 100644 --- a/compiler/testData/cfg/FinallyTestCopy.instructions +++ b/compiler/testData/cfg/FinallyTestCopy.instructions @@ -304,7 +304,7 @@ L4 [start finally]: mark(list != null) r(list) r(null) - call(list != null, equals) + call(!=, equals) jf(L5) NEXT:[read (Unit), mark({ })] mark({ }) read (Unit) @@ -320,7 +320,7 @@ L3 [skipFinallyToErrorBlock]: mark(list != null) r(list) r(null) - call(list != null, equals) + call(!=, equals) jf(copy L5) NEXT:[read (Unit), mark({ })] mark({ }) read (Unit) diff --git a/compiler/testData/cfg/equals.instructions b/compiler/testData/cfg/equals.instructions index 22234541ce6..72b70160179 100644 --- a/compiler/testData/cfg/equals.instructions +++ b/compiler/testData/cfg/equals.instructions @@ -15,7 +15,7 @@ L0: mark(a == b) r(a) r(b) - call(a == b, equals) + call(==, equals) jf(L2) NEXT:[read (Unit), mark({ })] mark({ }) read (Unit) diff --git a/compiler/testData/cfg/notEqual.instructions b/compiler/testData/cfg/notEqual.instructions index b15b8cdca9e..5bb121f60e4 100644 --- a/compiler/testData/cfg/notEqual.instructions +++ b/compiler/testData/cfg/notEqual.instructions @@ -14,7 +14,7 @@ L0: mark(a != b) r(a) r(b) - call(a != b, equals) + call(!=, equals) jf(L2) NEXT:[read (Unit), mark({})] mark({}) read (Unit) diff --git a/compiler/testData/cfg/tailCalls/sum.instructions b/compiler/testData/cfg/tailCalls/sum.instructions index 0fdf0fdf1d1..2c205a26ab4 100644 --- a/compiler/testData/cfg/tailCalls/sum.instructions +++ b/compiler/testData/cfg/tailCalls/sum.instructions @@ -18,7 +18,7 @@ L0: mark(toLong()) r(0) call(toLong, toLong) - call(x == 0.toLong(), equals) + call(==, equals) jf(L2) NEXT:[read (Unit), r(sum)] r(sum) ret(*) L1 NEXT:[] diff --git a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/DeepIf.kt b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/DeepIf.kt index 37ecb549250..fced673d8da 100644 --- a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/DeepIf.kt +++ b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/DeepIf.kt @@ -20,8 +20,8 @@ fun foo() { bar(x) if (x != null) { bar(x) - if (x == null) bar(x) - if (x == null) bar(x) else bar(x) + if (x == null) bar(x) + if (x == null) bar(x) else bar(x) bar(bar(x) + bar(x)) } else if (x == null) { bar(x)