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);
|
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 {
|
else {
|
||||||
if (!generateCall(operationReference)) {
|
if (!generateCall(operationReference)) {
|
||||||
generateBothArguments(expression);
|
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.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||||
import org.jetbrains.jet.utils.ThrowingList;
|
import org.jetbrains.jet.utils.ThrowingList;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -867,9 +868,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
ExpressionTypingContext context,
|
ExpressionTypingContext context,
|
||||||
JetSimpleNameExpression operationSign,
|
JetSimpleNameExpression operationSign,
|
||||||
JetExpression left,
|
JetExpression left,
|
||||||
JetExpression right
|
final JetExpression right
|
||||||
) {
|
) {
|
||||||
JetTypeInfo result;DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||||
if (right != null && left != null) {
|
if (right != null && left != null) {
|
||||||
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context);
|
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(EXPRESSION_TYPE, right, KotlinBuiltIns.getInstance().getNullableAnyType());
|
||||||
traceInterpretingRightAsNullableAny.record(PROCESSED, right);
|
traceInterpretingRightAsNullableAny.record(PROCESSED, right);
|
||||||
|
|
||||||
|
Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right));
|
||||||
|
ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
|
||||||
OverloadResolutionResults<FunctionDescriptor> resolutionResults =
|
OverloadResolutionResults<FunctionDescriptor> resolutionResults =
|
||||||
resolveFakeCall(receiver, context.replaceBindingTrace(traceInterpretingRightAsNullableAny),
|
newContext.resolveCallWithGivenName(call, operationSign, OperatorConventions.EQUALS);
|
||||||
Collections.singletonList(right), 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();
|
dataFlowInfo = facade.getTypeInfo(right, contextWithDataFlow).getDataFlowInfo();
|
||||||
|
|
||||||
if (resolutionResults.isSuccess()) {
|
if (resolutionResults.isSuccess()) {
|
||||||
FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
|
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)) {
|
if (ensureBooleanResult(operationSign, OperatorConventions.EQUALS, equals.getReturnType(), context)) {
|
||||||
ensureNonemptyIntersectionOfOperandTypes(expression, context);
|
ensureNonemptyIntersectionOfOperandTypes(expression, context);
|
||||||
}
|
}
|
||||||
@@ -906,8 +912,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo);
|
return JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ L4 [start finally]:
|
|||||||
mark(list != null)
|
mark(list != null)
|
||||||
r(list)
|
r(list)
|
||||||
r(null)
|
r(null)
|
||||||
call(list != null, equals)
|
call(!=, equals)
|
||||||
jf(L5) NEXT:[read (Unit), mark({ })]
|
jf(L5) NEXT:[read (Unit), mark({ })]
|
||||||
mark({ })
|
mark({ })
|
||||||
read (Unit)
|
read (Unit)
|
||||||
@@ -320,7 +320,7 @@ L3 [skipFinallyToErrorBlock]:
|
|||||||
mark(list != null)
|
mark(list != null)
|
||||||
r(list)
|
r(list)
|
||||||
r(null)
|
r(null)
|
||||||
call(list != null, equals)
|
call(!=, equals)
|
||||||
jf(copy L5) NEXT:[read (Unit), mark({ })]
|
jf(copy L5) NEXT:[read (Unit), mark({ })]
|
||||||
mark({ })
|
mark({ })
|
||||||
read (Unit)
|
read (Unit)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ L0:
|
|||||||
mark(a == b)
|
mark(a == b)
|
||||||
r(a)
|
r(a)
|
||||||
r(b)
|
r(b)
|
||||||
call(a == b, equals)
|
call(==, equals)
|
||||||
jf(L2) NEXT:[read (Unit), mark({ })]
|
jf(L2) NEXT:[read (Unit), mark({ })]
|
||||||
mark({ })
|
mark({ })
|
||||||
read (Unit)
|
read (Unit)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ L0:
|
|||||||
mark(a != b)
|
mark(a != b)
|
||||||
r(a)
|
r(a)
|
||||||
r(b)
|
r(b)
|
||||||
call(a != b, equals)
|
call(!=, equals)
|
||||||
jf(L2) NEXT:[read (Unit), mark({})]
|
jf(L2) NEXT:[read (Unit), mark({})]
|
||||||
mark({})
|
mark({})
|
||||||
read (Unit)
|
read (Unit)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ L0:
|
|||||||
mark(toLong())
|
mark(toLong())
|
||||||
r(0)
|
r(0)
|
||||||
call(toLong, toLong)
|
call(toLong, toLong)
|
||||||
call(x == 0.toLong(), equals)
|
call(==, equals)
|
||||||
jf(L2) NEXT:[read (Unit), r(sum)]
|
jf(L2) NEXT:[read (Unit), r(sum)]
|
||||||
r(sum)
|
r(sum)
|
||||||
ret(*) L1 NEXT:[<END>]
|
ret(*) L1 NEXT:[<END>]
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ fun foo() {
|
|||||||
bar(<!TYPE_MISMATCH!>x<!>)
|
bar(<!TYPE_MISMATCH!>x<!>)
|
||||||
if (<!SENSELESS_COMPARISON!>x != null<!>) {
|
if (<!SENSELESS_COMPARISON!>x != null<!>) {
|
||||||
bar(x)
|
bar(x)
|
||||||
if (x == null) bar(x)
|
if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x)
|
||||||
if (x == null) bar(x) else bar(x)
|
if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x) else bar(x)
|
||||||
bar(bar(x) + bar(x))
|
bar(bar(x) + bar(x))
|
||||||
} else if (<!SENSELESS_COMPARISON!>x == null<!>) {
|
} else if (<!SENSELESS_COMPARISON!>x == null<!>) {
|
||||||
bar(<!TYPE_MISMATCH!>x<!>)
|
bar(<!TYPE_MISMATCH!>x<!>)
|
||||||
|
|||||||
Reference in New Issue
Block a user