diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 3f80724b9ff..eba201ad0ac 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -70,7 +70,7 @@ class FunctionDescriptorResolver( CallableMemberDescriptor.Kind.DECLARATION, function.toSourceElement() ) - initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, null) + initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, TypeUtils.NO_EXPECTED_TYPE) initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo) BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor) return functionDescriptor @@ -81,7 +81,8 @@ class FunctionDescriptorResolver( scope: JetScope, function: JetNamedFunction, trace: BindingTrace, - dataFlowInfo: DataFlowInfo + dataFlowInfo: DataFlowInfo, + expectedFunctionType: JetType ): SimpleFunctionDescriptor { val functionDescriptor = FunctionExpressionDescriptor( containingDescriptor, @@ -90,7 +91,7 @@ class FunctionDescriptorResolver( CallableMemberDescriptor.Kind.DECLARATION, function.toSourceElement() ) - initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, null) + initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace, expectedFunctionType) initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo) BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor) return functionDescriptor @@ -128,7 +129,7 @@ class FunctionDescriptorResolver( function: JetFunction, functionDescriptor: SimpleFunctionDescriptorImpl, trace: BindingTrace, - expectedFunctionType: JetType? + expectedFunctionType: JetType ) { val innerScope = WritableScopeImpl(scope, functionDescriptor, TraceBasedRedeclarationHandler(trace), "Function descriptor header scope") innerScope.addLabeledDeclaration(functionDescriptor) @@ -170,7 +171,7 @@ class FunctionDescriptorResolver( functionDescriptor: SimpleFunctionDescriptorImpl, innerScope: WritableScopeImpl, trace: BindingTrace, - expectedFunctionType: JetType? + expectedFunctionType: JetType ): List { val expectedValueParameters = expectedFunctionType.getValueParameters(functionDescriptor) if (expectedValueParameters != null) { @@ -198,11 +199,11 @@ class FunctionDescriptorResolver( } private fun JetType.functionTypeExpected() = !TypeUtils.noExpectedType(this) && KotlinBuiltIns.isFunctionOrExtensionFunctionType(this) - private fun JetType?.getReceiverType(): JetType? = - if (this != null && functionTypeExpected()) getReceiverType(this) else null + private fun JetType.getReceiverType(): JetType? = + if (functionTypeExpected()) KotlinBuiltIns.getReceiverType(this) else null - private fun JetType?.getValueParameters(owner: FunctionDescriptor): List? = - if (this != null && functionTypeExpected()) getValueParameters(owner, this) else null + private fun JetType.getValueParameters(owner: FunctionDescriptor): List? = + if (functionTypeExpected()) KotlinBuiltIns.getValueParameters(owner, this) else null public fun resolvePrimaryConstructorDescriptor( scope: JetScope, @@ -316,7 +317,8 @@ class FunctionDescriptorResolver( else { type = TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE } - } else { + } + else { trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter)) type = ErrorUtils.createErrorType("Type annotation was missing for parameter ${valueParameter.getNameAsSafeName()}") } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt index d7603fd5b52..478c3040aa5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/FunctionsTypingVisitor.kt @@ -83,7 +83,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express } else { functionDescriptor = services.getFunctionDescriptorResolver().resolveFunctionExpressionDescriptor( - context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo) + context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo, context.expectedType) } val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace) diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/FunctionType.kt b/compiler/testData/diagnostics/tests/functionAsExpression/FunctionType.kt index 48517ffcc6d..d354d56b6ef 100644 --- a/compiler/testData/diagnostics/tests/functionAsExpression/FunctionType.kt +++ b/compiler/testData/diagnostics/tests/functionAsExpression/FunctionType.kt @@ -17,7 +17,7 @@ fun testParamType() { bar.checkType { it : _<(String) -> Unit> } val bas: (String) -> Unit = fun (param: String) {} - val bag: (Int) -> Unit = fun (param: String) {} + val bag: (Int) -> Unit = fun (param: String) {} } fun testReceiverType() { diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.kt b/compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.kt new file mode 100644 index 00000000000..977d970280e --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.kt @@ -0,0 +1,25 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +val a = fun (x) = x + +val b: (Int) -> Int = fun (x) = x + 3 + +val c: (Int, String) -> Int = fun (x) = 3 + +val d: (Int, String) -> Int = fun (x) = 3 + +val e: (Int, String) -> Int = fun (x: String) = 3 + +val f: (Int) -> Int = fun (x: String) = 3 + +fun test1(a: (Int) -> Unit) { + test1(fun (x) { x : Int}) +} + +fun test2(a: (Int) -> Unit) { + test2(fun (x: String) {}) +} + +fun test3(a: (Int, String) -> Unit) { + test3(fun (x: String) {}) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.txt b/compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.txt new file mode 100644 index 00000000000..cb07ce62458 --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.txt @@ -0,0 +1,11 @@ +package + +internal val a: (???) -> [ERROR : Cannot be inferred] +internal val b: (kotlin.Int) -> kotlin.Int +internal val c: (kotlin.Int, kotlin.String) -> kotlin.Int +internal val d: (kotlin.Int, kotlin.String) -> kotlin.Int +internal val e: (kotlin.Int, kotlin.String) -> kotlin.Int +internal val f: (kotlin.Int) -> kotlin.Int +internal fun test1(/*0*/ a: (kotlin.Int) -> kotlin.Unit): kotlin.Unit +internal fun test2(/*0*/ a: (kotlin.Int) -> kotlin.Unit): kotlin.Unit +internal fun test3(/*0*/ a: (kotlin.Int, kotlin.String) -> kotlin.Unit): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 138f8935230..b6ca5270998 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -4646,6 +4646,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("MissingParameterTypes.kt") + public void testMissingParameterTypes() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionAsExpression/MissingParameterTypes.kt"); + doTest(fileName); + } + @TestMetadata("NoOverloadError.kt") public void testNoOverloadError() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/functionAsExpression/NoOverloadError.kt");