KT-3461 Nullable argument allowed where shouldn't be
#KT-3461 Fixed
This commit is contained in:
+1
-8
@@ -26,10 +26,8 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||
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.model.ResolvedCallImpl;
|
||||
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.util.CallMaker;
|
||||
@@ -183,12 +181,7 @@ public class CallExpressionResolver {
|
||||
checkSuper(receiver, results, context.trace, callExpression);
|
||||
result[0] = true;
|
||||
if (results.isSingleResult() && resolveMode == ResolveMode.TOP_LEVEL_CALL) {
|
||||
ResolvedCallImpl<FunctionDescriptor> callToComplete = results.getResultingCall().getCallToCompleteTypeArgumentInference();
|
||||
if (CallResolverUtil.hasReturnTypeDependentOnNotInferredParams(callToComplete)) return null;
|
||||
|
||||
// Expected type mismatch was reported before as 'TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH'
|
||||
ConstraintSystem constraintSystem = callToComplete.getConstraintSystem();
|
||||
if (constraintSystem != null && constraintSystem.hasOnlyExpectedTypeMismatch()) return null;
|
||||
if (!CallResolverUtil.hasInferredReturnType(results.getResultingCall())) return null;
|
||||
}
|
||||
|
||||
return results.isSingleResult() ? results.getResultingCall() : null;
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
@@ -33,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
||||
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
@@ -113,9 +115,7 @@ public class CallResolverUtil {
|
||||
return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberScope());
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> boolean hasReturnTypeDependentOnNotInferredParams(
|
||||
@NotNull ResolvedCallImpl<D> callToComplete
|
||||
) {
|
||||
private static boolean hasReturnTypeDependentOnNotInferredParams(@NotNull ResolvedCallImpl<?> callToComplete) {
|
||||
ConstraintSystem constraintSystem = callToComplete.getConstraintSystem();
|
||||
if (constraintSystem == null) return false;
|
||||
|
||||
@@ -134,6 +134,17 @@ public class CallResolverUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasInferredReturnType(ResolvedCallWithTrace<?> call) {
|
||||
boolean isKnownReturnType = true;
|
||||
ResolvedCallImpl<?> callToComplete = call.getCallToCompleteTypeArgumentInference();
|
||||
if (hasReturnTypeDependentOnNotInferredParams(callToComplete)) { isKnownReturnType = false; }
|
||||
|
||||
// Expected type mismatch was reported before as 'TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH'
|
||||
ConstraintSystem constraintSystem = callToComplete.getConstraintSystem();
|
||||
if (constraintSystem != null && constraintSystem.hasOnlyExpectedTypeMismatch()) { isKnownReturnType = false; }
|
||||
return isKnownReturnType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CallKey createCallKey(@NotNull BasicCallResolutionContext context) {
|
||||
if (context.call.getCallType() == Call.CallType.INVOKE) {
|
||||
|
||||
@@ -216,7 +216,7 @@ public class CandidateResolver {
|
||||
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
|
||||
}
|
||||
|
||||
public <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||
public <D extends CallableDescriptor> JetType completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
boolean isInnerCall
|
||||
) {
|
||||
@@ -239,7 +239,8 @@ public class CandidateResolver {
|
||||
|
||||
context.tracing.typeInferenceFailed(context.trace, errorData);
|
||||
resolvedCall.addStatus(ResolutionStatus.OTHER_ERROR);
|
||||
return;
|
||||
if (!CallResolverUtil.hasInferredReturnType(resolvedCall)) return null;
|
||||
return resolvedCall.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
|
||||
boolean boundsAreSatisfied = ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem, /*substituteOtherTypeParametersInBounds=*/true);
|
||||
@@ -271,9 +272,11 @@ public class CandidateResolver {
|
||||
DataFlowUtils.checkType(resolvedCall.getResultingDescriptor().getReturnType(), (JetCallExpression) callElement, context, context.dataFlowInfo);
|
||||
}
|
||||
}
|
||||
return resolvedCall.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
|
||||
public <D extends CallableDescriptor> void completeNestedCallsInference(
|
||||
@Nullable
|
||||
public <D extends CallableDescriptor> JetType completeNestedCallsInference(
|
||||
@NotNull CallCandidateResolutionContext<D> context
|
||||
) {
|
||||
ResolvedCallImpl<D> resolvedCall = context.candidateCall;
|
||||
@@ -318,16 +321,20 @@ public class CandidateResolver {
|
||||
|
||||
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument =
|
||||
storedContextForArgument.replaceResolveMode(ResolveMode.TOP_LEVEL_CALL).replaceBindingTrace(context.trace).replaceExpectedType(expectedType);
|
||||
JetType type;
|
||||
if (contextForArgument.candidateCall.hasIncompleteTypeParameters()) {
|
||||
completeTypeInferenceDependentOnExpectedTypeForCall(contextForArgument, true);
|
||||
type = completeTypeInferenceDependentOnExpectedTypeForCall(contextForArgument, true);
|
||||
}
|
||||
else {
|
||||
completeNestedCallsInference(contextForArgument);
|
||||
type = completeNestedCallsInference(contextForArgument);
|
||||
checkValueArgumentTypes(contextForArgument);
|
||||
}
|
||||
|
||||
DataFlowUtils.checkType(type, expression, contextForArgument);
|
||||
}
|
||||
}
|
||||
recordReferenceForInvokeFunction(context);
|
||||
return resolvedCall.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> void recordReferenceForInvokeFunction(CallCandidateResolutionContext<D> context) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//KT-3461 Nullable argument allowed where shouldn't be
|
||||
package a
|
||||
|
||||
class F {
|
||||
fun p(): String? = null
|
||||
}
|
||||
|
||||
fun foo(<!UNUSED_PARAMETER!>s<!>: String) {}
|
||||
|
||||
fun r(): Int? = null
|
||||
|
||||
fun test() {
|
||||
foo(<!TYPE_MISMATCH!>F().p()<!>)
|
||||
foo(<!TYPE_MISMATCH!>r()<!>)
|
||||
}
|
||||
@@ -2195,6 +2195,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/inference/nestedCalls/kt3395.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt3461checkTypes.kt")
|
||||
public void testKt3461checkTypes() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/nestedCalls/kt3461checkTypes.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/regressions")
|
||||
|
||||
Reference in New Issue
Block a user