KT-2842 Function with declared non-null receiver resolves with nullable argument receiver
#KT-2842 fixed
This commit is contained in:
@@ -20,7 +20,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
@@ -36,6 +39,12 @@ public final class CallResolutionContext<D extends CallableDescriptor, F extends
|
||||
this.tracing = tracing;
|
||||
}
|
||||
|
||||
private CallResolutionContext(@NotNull BasicResolutionContext context, @NotNull TracingStrategy tracing, @NotNull ResolvedCallImpl<D> candidateCall) {
|
||||
super(context.trace, context.scope, context.call, context.expectedType, context.dataFlowInfo);
|
||||
this.candidateCall = candidateCall;
|
||||
this.tracing = tracing;
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor, F extends D> CallResolutionContext<D, F> create(@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolutionTask<D, F> task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) {
|
||||
return new CallResolutionContext<D, F>(candidateCall, task, trace, tracing, call);
|
||||
}
|
||||
@@ -43,4 +52,8 @@ public final class CallResolutionContext<D extends CallableDescriptor, F extends
|
||||
public static <D extends CallableDescriptor, F extends D> CallResolutionContext<D, F> create(@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolutionTask<D, F> task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing) {
|
||||
return create(candidateCall, task, trace, tracing, task.call);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> CallResolutionContext<D, D> create(@NotNull BasicResolutionContext context, @NotNull TracingStrategy tracing, @NotNull ResolvedCallImpl<D> candidateCall) {
|
||||
return new CallResolutionContext<D, D>(context, tracing, candidateCall);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ public class CallResolver {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
completeTypeInferenceDependentOnExpectedTypeForCall(resolvedCall, context, tracing, successful, failed);
|
||||
completeTypeInferenceDependentOnExpectedTypeForCall(CallResolutionContext.create(context, tracing, resolvedCall), successful, failed);
|
||||
}
|
||||
OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(context.trace, tracing, successful, failed);
|
||||
if (!results.isSingleResult()) {
|
||||
@@ -337,12 +337,12 @@ public class CallResolver {
|
||||
return results;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(ResolvedCallImpl<D> resolvedCall,
|
||||
BasicResolutionContext context,
|
||||
TracingStrategy tracing,
|
||||
private <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||
CallResolutionContext<D, D> context,
|
||||
Set<ResolvedCallWithTrace<D>> successful,
|
||||
Set<ResolvedCallWithTrace<D>> failed
|
||||
) {
|
||||
ResolvedCallImpl<D> resolvedCall = context.candidateCall;
|
||||
assert resolvedCall.hasUnknownTypeParameters();
|
||||
D descriptor = resolvedCall.getCandidateDescriptor();
|
||||
ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
|
||||
@@ -383,7 +383,7 @@ public class CallResolver {
|
||||
}
|
||||
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes;
|
||||
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
|
||||
tracing.typeInferenceFailed(resolvedCall.getTrace(),
|
||||
context.tracing.typeInferenceFailed(resolvedCall.getTrace(),
|
||||
InferenceErrorData
|
||||
.create(descriptor, constraintSystem, argumentTypes, receiverType, context.expectedType),
|
||||
constraintSystemWithoutExpectedTypeConstraint);
|
||||
@@ -394,9 +394,9 @@ public class CallResolver {
|
||||
|
||||
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
|
||||
// Here we type check the arguments with inferred types expected
|
||||
checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace());
|
||||
checkAllValueArguments(context);
|
||||
|
||||
checkBounds(resolvedCall, constraintSystem, resolvedCall.getTrace(), tracing);
|
||||
checkBounds(resolvedCall, constraintSystem, resolvedCall.getTrace(), context.tracing);
|
||||
resolvedCall.setHasUnknownTypeParameters(false);
|
||||
if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) {
|
||||
resolvedCall.addStatus(ResolutionStatus.SUCCESS);
|
||||
@@ -866,7 +866,7 @@ public class CallResolver {
|
||||
|
||||
|
||||
private <D extends CallableDescriptor, F extends D> ValueArgumentsCheckingResult checkAllValueArguments(CallResolutionContext<D, F> context) {
|
||||
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(context, context.candidateCall);
|
||||
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(context, context.candidateCall, context.candidateCall.getTrace());
|
||||
ResolutionStatus resultStatus = checkingResult.status;
|
||||
ResolvedCall<D> candidateCall = context.candidateCall;
|
||||
|
||||
@@ -927,10 +927,6 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes(ResolutionContext context, ResolvedCallImpl<D> candidateCall) {
|
||||
return checkValueArgumentTypes(context, candidateCall, candidateCall.getTrace());
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes(ResolutionContext context, ResolvedCallImpl<D> candidateCall, BindingTrace trace) {
|
||||
ResolutionStatus resultStatus = SUCCESS;
|
||||
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package c
|
||||
|
||||
trait A<T>
|
||||
|
||||
fun test(a: A<Int>?) {
|
||||
a<!UNSAFE_CALL!>.<!>foo() //no error
|
||||
}
|
||||
|
||||
fun <R> A<R>.foo() {}
|
||||
|
||||
//------------
|
||||
fun test(nullabilityInfoMap: Map<Int, Any>?) {
|
||||
nullabilityInfoMap<!UNSAFE_CALL!>.<!>iterator() //no error
|
||||
}
|
||||
|
||||
//resolves to
|
||||
public inline fun <K,V> Map<K,V>.iterator(): Iterator<Map.Entry<K,V>> {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
|
||||
|
||||
//-------------
|
||||
fun foo() : Boolean {
|
||||
val nullableList = getNullableList()
|
||||
return nullableList<!UNSAFE_CALL!>.<!>contains("")
|
||||
|
||||
}
|
||||
|
||||
fun getNullableList(): List<String>? = null
|
||||
@@ -1889,6 +1889,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt2842.kt")
|
||||
public void testKt2842() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2842.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt702.kt")
|
||||
public void testKt702() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt702.kt");
|
||||
|
||||
@@ -10,7 +10,7 @@ class StringUtilTest() : TestCase() {
|
||||
|
||||
fun testToRegex() {
|
||||
val re = """foo""".toRegex()
|
||||
val list = re.split("hellofoobar").filterNotNull()
|
||||
val list = re.split("hellofoobar").toList()
|
||||
assertEquals(arrayList("hello", "bar"), list)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user