while resolve 'equals' as a fake call do not throw away temporary trace
This commit is contained in:
@@ -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<FunctionDescriptor> resolvedCall = (ResolvedCall<FunctionDescriptor>) getResolvedCall(operationReference);
|
||||
if (resolvedCall != null && !resolvedCall.getValueArguments().isEmpty() && right != null) {
|
||||
ResolvedCallImpl<FunctionDescriptor> 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);
|
||||
|
||||
+13
-8
@@ -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<FunctionDescriptor> 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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:[<END>]
|
||||
|
||||
@@ -20,8 +20,8 @@ fun foo() {
|
||||
bar(<!TYPE_MISMATCH!>x<!>)
|
||||
if (<!SENSELESS_COMPARISON!>x != null<!>) {
|
||||
bar(x)
|
||||
if (x == null) bar(x)
|
||||
if (x == null) bar(x) else bar(x)
|
||||
if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x)
|
||||
if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x) else bar(x)
|
||||
bar(bar(x) + bar(x))
|
||||
} else if (<!SENSELESS_COMPARISON!>x == null<!>) {
|
||||
bar(<!TYPE_MISMATCH!>x<!>)
|
||||
|
||||
Reference in New Issue
Block a user