From 12c0a2cb775c78b603621905a91f243a4b3c1423 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Mon, 1 Apr 2013 19:07:04 +0400 Subject: [PATCH] KT-3461 Nullable argument allowed where shouldn't be #KT-3461 Fixed --- .../resolve/calls/CallExpressionResolver.java | 9 +-------- .../lang/resolve/calls/CallResolverUtil.java | 17 ++++++++++++++--- .../lang/resolve/calls/CandidateResolver.java | 17 ++++++++++++----- .../inference/nestedCalls/kt3461checkTypes.kt | 15 +++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 +++++ 5 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/nestedCalls/kt3461checkTypes.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index 1abd9940be0..058d5af53b5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -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 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; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index c100dc7374e..087b1879e23 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -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 boolean hasReturnTypeDependentOnNotInferredParams( - @NotNull ResolvedCallImpl 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) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index e9eb7d6d451..0b920829503 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -216,7 +216,7 @@ public class CandidateResolver { resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor()); } - public void completeTypeInferenceDependentOnExpectedTypeForCall( + public JetType completeTypeInferenceDependentOnExpectedTypeForCall( @NotNull CallCandidateResolutionContext 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 void completeNestedCallsInference( + @Nullable + public JetType completeNestedCallsInference( @NotNull CallCandidateResolutionContext context ) { ResolvedCallImpl resolvedCall = context.candidateCall; @@ -318,16 +321,20 @@ public class CandidateResolver { CallCandidateResolutionContext 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 void recordReferenceForInvokeFunction(CallCandidateResolutionContext context) { diff --git a/compiler/testData/diagnostics/tests/inference/nestedCalls/kt3461checkTypes.kt b/compiler/testData/diagnostics/tests/inference/nestedCalls/kt3461checkTypes.kt new file mode 100644 index 00000000000..3138e8998b9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nestedCalls/kt3461checkTypes.kt @@ -0,0 +1,15 @@ +//KT-3461 Nullable argument allowed where shouldn't be +package a + +class F { + fun p(): String? = null +} + +fun foo(s: String) {} + +fun r(): Int? = null + +fun test() { + foo(F().p()) + foo(r()) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 74f0b8893ab..0d855419520 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -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")